2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2021-01-05 23:28:12 +08:00
|
|
|
* Copyright (C) 2018-2021 Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
2018-09-18 15:11:08 +08:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2020-02-23 05:50:57 +08:00
|
|
|
#include "opencl/source/mem_obj/image.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/debug_settings/debug_settings_manager.h"
|
|
|
|
#include "shared/source/gmm_helper/gmm.h"
|
|
|
|
#include "shared/source/gmm_helper/resource_info.h"
|
|
|
|
#include "shared/source/helpers/aligned_memory.h"
|
|
|
|
#include "shared/source/helpers/basic_math.h"
|
|
|
|
#include "shared/source/helpers/get_info.h"
|
|
|
|
#include "shared/source/helpers/hw_helper.h"
|
|
|
|
#include "shared/source/helpers/hw_info.h"
|
|
|
|
#include "shared/source/helpers/ptr_math.h"
|
|
|
|
#include "shared/source/helpers/string.h"
|
|
|
|
#include "shared/source/memory_manager/memory_manager.h"
|
|
|
|
#include "shared/source/utilities/compiler_support.h"
|
2020-02-24 17:22:30 +08:00
|
|
|
|
2020-03-20 18:15:25 +08:00
|
|
|
#include "opencl/source/cl_device/cl_device.h"
|
|
|
|
#include "opencl/source/cl_device/cl_device_get_cap.inl"
|
2020-02-23 05:50:57 +08:00
|
|
|
#include "opencl/source/command_queue/command_queue.h"
|
|
|
|
#include "opencl/source/context/context.h"
|
2021-10-07 01:00:24 +08:00
|
|
|
#include "opencl/source/helpers/cl_memory_properties_helpers.h"
|
2020-02-23 05:50:57 +08:00
|
|
|
#include "opencl/source/helpers/get_info_status_mapper.h"
|
2020-02-25 20:31:00 +08:00
|
|
|
#include "opencl/source/helpers/gmm_types_converter.h"
|
2020-02-23 05:50:57 +08:00
|
|
|
#include "opencl/source/helpers/mipmap.h"
|
|
|
|
#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/platform/platform.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
|
|
|
|
#include "igfxfmid.h"
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
#include <map>
|
|
|
|
|
2019-03-26 18:59:46 +08:00
|
|
|
namespace NEO {
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-05-12 19:47:44 +08:00
|
|
|
ImageFactoryFuncs imageFactory[IGFX_MAX_CORE] = {};
|
|
|
|
|
|
|
|
namespace ImageFunctions {
|
|
|
|
ValidateAndCreateImageFunc validateAndCreateImage = Image::validateAndCreateImage;
|
|
|
|
} // namespace ImageFunctions
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
Image::Image(Context *context,
|
2020-04-22 20:37:30 +08:00
|
|
|
const MemoryProperties &memoryProperties,
|
2019-09-24 22:05:17 +08:00
|
|
|
cl_mem_flags flags,
|
|
|
|
cl_mem_flags_intel flagsIntel,
|
2017-12-21 07:45:38 +08:00
|
|
|
size_t size,
|
2020-08-03 17:08:19 +08:00
|
|
|
void *memoryStorage,
|
2017-12-21 07:45:38 +08:00
|
|
|
void *hostPtr,
|
|
|
|
cl_image_format imageFormat,
|
|
|
|
const cl_image_desc &imageDesc,
|
|
|
|
bool zeroCopy,
|
2020-07-16 18:15:52 +08:00
|
|
|
MultiGraphicsAllocation multiGraphicsAllocation,
|
2017-12-21 07:45:38 +08:00
|
|
|
bool isObjectRedescribed,
|
2018-04-04 15:29:48 +08:00
|
|
|
uint32_t baseMipLevel,
|
|
|
|
uint32_t mipCount,
|
2020-01-09 00:29:15 +08:00
|
|
|
const ClSurfaceFormatInfo &surfaceFormatInfo,
|
2017-12-21 07:45:38 +08:00
|
|
|
const SurfaceOffsets *surfaceOffsets)
|
|
|
|
: MemObj(context,
|
|
|
|
imageDesc.image_type,
|
2019-10-09 23:29:00 +08:00
|
|
|
memoryProperties,
|
2019-09-24 22:05:17 +08:00
|
|
|
flags,
|
|
|
|
flagsIntel,
|
2017-12-21 07:45:38 +08:00
|
|
|
size,
|
2020-08-03 17:08:19 +08:00
|
|
|
memoryStorage,
|
2017-12-21 07:45:38 +08:00
|
|
|
hostPtr,
|
2020-08-03 17:08:19 +08:00
|
|
|
std::move(multiGraphicsAllocation),
|
2017-12-21 07:45:38 +08:00
|
|
|
zeroCopy,
|
|
|
|
false,
|
|
|
|
isObjectRedescribed),
|
|
|
|
createFunction(nullptr),
|
|
|
|
imageFormat(std::move(imageFormat)),
|
|
|
|
imageDesc(imageDesc),
|
2018-04-04 15:29:48 +08:00
|
|
|
surfaceFormatInfo(surfaceFormatInfo),
|
2017-12-21 07:45:38 +08:00
|
|
|
cubeFaceIndex(__GMM_NO_CUBE_MAP),
|
|
|
|
mediaPlaneType(0),
|
2018-04-04 15:29:48 +08:00
|
|
|
baseMipLevel(baseMipLevel),
|
|
|
|
mipCount(mipCount) {
|
2017-12-21 07:45:38 +08:00
|
|
|
magic = objectMagic;
|
|
|
|
if (surfaceOffsets)
|
|
|
|
setSurfaceOffsets(surfaceOffsets->offset, surfaceOffsets->xOffset, surfaceOffsets->yOffset, surfaceOffsets->yOffsetForUVplane);
|
|
|
|
else
|
|
|
|
setSurfaceOffsets(0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
|
2018-02-09 03:55:31 +08:00
|
|
|
void Image::transferData(void *dest, size_t destRowPitch, size_t destSlicePitch,
|
|
|
|
void *src, size_t srcRowPitch, size_t srcSlicePitch,
|
2018-03-07 21:37:09 +08:00
|
|
|
std::array<size_t, 3> copyRegion, std::array<size_t, 3> copyOrigin) {
|
2018-02-09 03:55:31 +08:00
|
|
|
|
2020-01-09 00:29:15 +08:00
|
|
|
size_t pixelSize = surfaceFormatInfo.surfaceFormat.ImageElementSizeInBytes;
|
2018-02-09 03:55:31 +08:00
|
|
|
size_t lineWidth = copyRegion[0] * pixelSize;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
DBG_LOG(LogMemoryObject, __FUNCTION__, "memcpy dest:", dest, "sizeRowToCopy:", lineWidth, "src:", src);
|
2018-02-09 03:55:31 +08:00
|
|
|
|
2018-03-07 21:37:09 +08:00
|
|
|
if (imageDesc.image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY) {
|
|
|
|
// For 1DArray type, array region and origin are stored on 2nd position. For 2Darray its on 3rd position.
|
|
|
|
std::swap(copyOrigin[1], copyOrigin[2]);
|
|
|
|
std::swap(copyRegion[1], copyRegion[2]);
|
|
|
|
}
|
|
|
|
|
2018-02-09 03:55:31 +08:00
|
|
|
for (size_t slice = copyOrigin[2]; slice < (copyOrigin[2] + copyRegion[2]); slice++) {
|
|
|
|
auto srcSliceOffset = ptrOffset(src, srcSlicePitch * slice);
|
|
|
|
auto dstSliceOffset = ptrOffset(dest, destSlicePitch * slice);
|
|
|
|
|
|
|
|
for (size_t height = copyOrigin[1]; height < (copyOrigin[1] + copyRegion[1]); height++) {
|
|
|
|
auto srcRowOffset = ptrOffset(srcSliceOffset, srcRowPitch * height);
|
|
|
|
auto dstRowOffset = ptrOffset(dstSliceOffset, destRowPitch * height);
|
|
|
|
|
|
|
|
memcpy_s(ptrOffset(dstRowOffset, copyOrigin[0] * pixelSize), lineWidth,
|
|
|
|
ptrOffset(srcRowOffset, copyOrigin[0] * pixelSize), lineWidth);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Image::~Image() = default;
|
|
|
|
|
|
|
|
Image *Image::create(Context *context,
|
2020-04-22 20:37:30 +08:00
|
|
|
const MemoryProperties &memoryProperties,
|
2019-10-17 20:18:55 +08:00
|
|
|
cl_mem_flags flags,
|
|
|
|
cl_mem_flags_intel flagsIntel,
|
2020-01-09 00:29:15 +08:00
|
|
|
const ClSurfaceFormatInfo *surfaceFormat,
|
2017-12-21 07:45:38 +08:00
|
|
|
const cl_image_desc *imageDesc,
|
|
|
|
const void *hostPtr,
|
|
|
|
cl_int &errcodeRet) {
|
|
|
|
UNRECOVERABLE_IF(surfaceFormat == nullptr);
|
2020-12-04 17:54:30 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
Image *image = nullptr;
|
|
|
|
MemoryManager *memoryManager = context->getMemoryManager();
|
2020-12-04 17:54:30 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
Buffer *parentBuffer = castToObject<Buffer>(imageDesc->mem_object);
|
|
|
|
Image *parentImage = castToObject<Image>(imageDesc->mem_object);
|
2020-12-04 17:54:30 +08:00
|
|
|
|
|
|
|
auto &defaultHwHelper = HwHelper::get(context->getDevice(0)->getHardwareInfo().platform.eRenderCoreFamily);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2021-07-02 00:00:22 +08:00
|
|
|
bool transferedMemory = false;
|
2017-12-21 07:45:38 +08:00
|
|
|
do {
|
|
|
|
size_t imageWidth = imageDesc->image_width;
|
|
|
|
size_t imageHeight = 1;
|
|
|
|
size_t imageDepth = 1;
|
|
|
|
size_t imageCount = 1;
|
|
|
|
size_t hostPtrMinSize = 0;
|
|
|
|
|
|
|
|
cl_image_desc imageDescriptor = *imageDesc;
|
2020-01-08 18:11:54 +08:00
|
|
|
ImageInfo imgInfo = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
void *hostPtrToSet = nullptr;
|
|
|
|
|
2019-10-17 20:18:55 +08:00
|
|
|
if (memoryProperties.flags.useHostPtr) {
|
2017-12-21 07:45:38 +08:00
|
|
|
hostPtrToSet = const_cast<void *>(hostPtr);
|
|
|
|
}
|
|
|
|
|
2020-01-08 18:11:54 +08:00
|
|
|
imgInfo.imgDesc = Image::convertDescriptor(imageDescriptor);
|
2020-01-09 00:29:15 +08:00
|
|
|
imgInfo.surfaceFormat = &surfaceFormat->surfaceFormat;
|
2018-03-12 23:32:08 +08:00
|
|
|
imgInfo.mipCount = imageDesc->num_mip_levels;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
if (imageDesc->image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY || imageDesc->image_type == CL_MEM_OBJECT_IMAGE2D_ARRAY) {
|
|
|
|
imageCount = imageDesc->image_array_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (imageDesc->image_type) {
|
|
|
|
case CL_MEM_OBJECT_IMAGE3D:
|
|
|
|
imageDepth = imageDesc->image_depth;
|
2018-02-11 11:46:02 +08:00
|
|
|
CPP_ATTRIBUTE_FALLTHROUGH;
|
2017-12-21 07:45:38 +08:00
|
|
|
case CL_MEM_OBJECT_IMAGE2D:
|
|
|
|
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
|
|
|
imageHeight = imageDesc->image_height;
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D:
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DEBUG_BREAK_IF("Unsupported cl_image_type");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parentImage) {
|
|
|
|
imageWidth = parentImage->getImageDesc().image_width;
|
|
|
|
imageHeight = parentImage->getImageDesc().image_height;
|
|
|
|
imageDepth = 1;
|
2021-06-28 13:06:24 +08:00
|
|
|
if (isNV12Image(&parentImage->getImageFormat())) {
|
2018-04-05 21:05:33 +08:00
|
|
|
if (imageDesc->image_depth == 1) { // UV Plane
|
|
|
|
imageWidth /= 2;
|
|
|
|
imageHeight /= 2;
|
|
|
|
imgInfo.plane = GMM_PLANE_U;
|
|
|
|
} else {
|
|
|
|
imgInfo.plane = GMM_PLANE_Y;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-01-09 00:29:15 +08:00
|
|
|
imgInfo.surfaceFormat = &parentImage->surfaceFormatInfo.surfaceFormat;
|
2017-12-21 07:45:38 +08:00
|
|
|
imageDescriptor = parentImage->getImageDesc();
|
|
|
|
}
|
|
|
|
|
2020-01-09 00:29:15 +08:00
|
|
|
auto hostPtrRowPitch = imageDesc->image_row_pitch ? imageDesc->image_row_pitch : imageWidth * surfaceFormat->surfaceFormat.ImageElementSizeInBytes;
|
2017-12-21 07:45:38 +08:00
|
|
|
auto hostPtrSlicePitch = imageDesc->image_slice_pitch ? imageDesc->image_slice_pitch : hostPtrRowPitch * imageHeight;
|
2020-12-04 17:54:30 +08:00
|
|
|
imgInfo.linearStorage = !defaultHwHelper.tilingAllowed(context->isSharedContext, Image::isImage1d(*imageDesc),
|
|
|
|
memoryProperties.flags.forceLinearStorage);
|
2019-08-26 15:27:30 +08:00
|
|
|
imgInfo.preferRenderCompression = MemObjHelper::isSuitableForRenderCompression(!imgInfo.linearStorage, memoryProperties,
|
2019-10-08 16:38:02 +08:00
|
|
|
*context, true);
|
2020-02-10 22:05:12 +08:00
|
|
|
imgInfo.preferRenderCompression &= !Image::isFormatRedescribable(surfaceFormat->OCLImageFormat);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-03-12 16:33:20 +08:00
|
|
|
if (!context->getDevice(0)->getSharedDeviceInfo().imageSupport && !imgInfo.linearStorage) {
|
2019-09-09 20:11:39 +08:00
|
|
|
errcodeRet = CL_INVALID_OPERATION;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2019-06-07 05:21:08 +08:00
|
|
|
switch (imageDesc->image_type) {
|
|
|
|
case CL_MEM_OBJECT_IMAGE3D:
|
|
|
|
hostPtrMinSize = hostPtrSlicePitch * imageDepth;
|
|
|
|
break;
|
|
|
|
case CL_MEM_OBJECT_IMAGE2D:
|
2021-06-28 13:06:24 +08:00
|
|
|
if (isNV12Image(&surfaceFormat->OCLImageFormat)) {
|
2019-06-07 05:21:08 +08:00
|
|
|
hostPtrMinSize = hostPtrRowPitch * imageHeight + hostPtrRowPitch * imageHeight / 2;
|
|
|
|
} else {
|
|
|
|
hostPtrMinSize = hostPtrRowPitch * imageHeight;
|
|
|
|
}
|
|
|
|
hostPtrSlicePitch = 0;
|
|
|
|
break;
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
|
|
|
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
|
|
|
hostPtrMinSize = hostPtrSlicePitch * imageCount;
|
|
|
|
break;
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D:
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
|
|
|
|
hostPtrMinSize = hostPtrRowPitch;
|
|
|
|
hostPtrSlicePitch = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DEBUG_BREAK_IF("Unsupported cl_image_type");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
auto maxRootDeviceIndex = context->getMaxRootDeviceIndex();
|
|
|
|
auto multiGraphicsAllocation = MultiGraphicsAllocation(maxRootDeviceIndex);
|
2019-03-29 18:48:32 +08:00
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
AllocationInfoType allocationInfo;
|
|
|
|
allocationInfo.resize(maxRootDeviceIndex + 1u);
|
|
|
|
bool isParentObject = parentBuffer || parentImage;
|
2019-03-29 18:48:32 +08:00
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
for (auto &rootDeviceIndex : context->getRootDeviceIndices()) {
|
|
|
|
allocationInfo[rootDeviceIndex] = {};
|
|
|
|
allocationInfo[rootDeviceIndex].zeroCopyAllowed = false;
|
2019-01-22 19:40:17 +08:00
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
Gmm *gmm = nullptr;
|
2021-01-05 23:28:12 +08:00
|
|
|
auto &hwInfo = *memoryManager->peekExecutionEnvironment().rootDeviceEnvironments[rootDeviceIndex]->getHardwareInfo();
|
2020-12-04 17:54:30 +08:00
|
|
|
auto &hwHelper = HwHelper::get((&memoryManager->peekExecutionEnvironment())->rootDeviceEnvironments[rootDeviceIndex]->getHardwareInfo()->platform.eRenderCoreFamily);
|
|
|
|
auto clientContext = (&memoryManager->peekExecutionEnvironment())->rootDeviceEnvironments[rootDeviceIndex]->getGmmClientContext();
|
2019-01-22 19:40:17 +08:00
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
if (((imageDesc->image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER) || (imageDesc->image_type == CL_MEM_OBJECT_IMAGE2D)) && (parentBuffer != nullptr)) {
|
|
|
|
|
|
|
|
allocationInfo[rootDeviceIndex].memory = parentBuffer->getGraphicsAllocation(rootDeviceIndex);
|
|
|
|
if (!hwHelper.checkResourceCompatibility(*allocationInfo[rootDeviceIndex].memory)) {
|
|
|
|
cleanAllGraphicsAllocations(*context, *memoryManager, allocationInfo, isParentObject);
|
|
|
|
errcodeRet = CL_INVALID_MEM_OBJECT;
|
|
|
|
return nullptr;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2020-12-04 17:54:30 +08:00
|
|
|
|
|
|
|
// Image from buffer - we never allocate memory, we use what buffer provides
|
|
|
|
allocationInfo[rootDeviceIndex].zeroCopyAllowed = true;
|
|
|
|
hostPtr = parentBuffer->getHostPtr();
|
|
|
|
hostPtrToSet = const_cast<void *>(hostPtr);
|
|
|
|
parentBuffer->incRefInternal();
|
|
|
|
GmmTypesConverter::queryImgFromBufferParams(imgInfo, allocationInfo[rootDeviceIndex].memory);
|
|
|
|
|
|
|
|
UNRECOVERABLE_IF(imgInfo.offset != 0);
|
|
|
|
imgInfo.offset = parentBuffer->getOffset();
|
|
|
|
|
|
|
|
if (memoryManager->peekVirtualPaddingSupport() && (imageDesc->image_type == CL_MEM_OBJECT_IMAGE2D) && (allocationInfo[rootDeviceIndex].memory->getUnderlyingBuffer() != 0)) {
|
|
|
|
// Retrieve sizes from GMM and apply virtual padding if buffer storage is not big enough
|
|
|
|
auto queryGmmImgInfo(imgInfo);
|
|
|
|
auto gmm = std::make_unique<Gmm>(clientContext, queryGmmImgInfo, StorageInfo{});
|
|
|
|
auto gmmAllocationSize = gmm->gmmResourceInfo->getSizeAllocation();
|
|
|
|
if (gmmAllocationSize > allocationInfo[rootDeviceIndex].memory->getUnderlyingBufferSize()) {
|
|
|
|
allocationInfo[rootDeviceIndex].memory = memoryManager->createGraphicsAllocationWithPadding(allocationInfo[rootDeviceIndex].memory, gmmAllocationSize);
|
|
|
|
}
|
2019-06-07 05:21:08 +08:00
|
|
|
}
|
2020-12-04 17:54:30 +08:00
|
|
|
} else if (parentImage != nullptr) {
|
|
|
|
allocationInfo[rootDeviceIndex].memory = parentImage->getGraphicsAllocation(rootDeviceIndex);
|
|
|
|
allocationInfo[rootDeviceIndex].memory->getDefaultGmm()->queryImageParams(imgInfo);
|
2017-12-21 07:45:38 +08:00
|
|
|
} else {
|
2020-12-04 17:54:30 +08:00
|
|
|
errcodeRet = CL_OUT_OF_HOST_MEMORY;
|
|
|
|
if (memoryProperties.flags.useHostPtr) {
|
|
|
|
if (!context->isSharedContext) {
|
|
|
|
AllocationProperties allocProperties = MemObjHelper::getAllocationPropertiesWithImageInfo(rootDeviceIndex, imgInfo,
|
|
|
|
false, // allocateMemory
|
2021-01-05 23:28:12 +08:00
|
|
|
memoryProperties, hwInfo,
|
2021-07-07 20:43:54 +08:00
|
|
|
context->getDeviceBitfieldForAllocation(rootDeviceIndex),
|
|
|
|
context->isSingleDeviceContext());
|
2020-12-04 17:54:30 +08:00
|
|
|
|
|
|
|
allocationInfo[rootDeviceIndex].memory = memoryManager->allocateGraphicsMemoryWithProperties(allocProperties, hostPtr);
|
|
|
|
|
|
|
|
if (allocationInfo[rootDeviceIndex].memory) {
|
|
|
|
if (allocationInfo[rootDeviceIndex].memory->getUnderlyingBuffer() != hostPtr) {
|
|
|
|
allocationInfo[rootDeviceIndex].zeroCopyAllowed = false;
|
|
|
|
allocationInfo[rootDeviceIndex].transferNeeded = true;
|
|
|
|
} else {
|
|
|
|
allocationInfo[rootDeviceIndex].zeroCopyAllowed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
gmm = new Gmm(clientContext, imgInfo, StorageInfo{});
|
|
|
|
allocationInfo[rootDeviceIndex].memory = memoryManager->allocateGraphicsMemoryWithProperties({rootDeviceIndex,
|
|
|
|
false, // allocateMemory
|
|
|
|
imgInfo.size, GraphicsAllocation::AllocationType::SHARED_CONTEXT_IMAGE,
|
|
|
|
false, // isMultiStorageAllocation
|
|
|
|
context->getDeviceBitfieldForAllocation(rootDeviceIndex)},
|
|
|
|
hostPtr);
|
|
|
|
allocationInfo[rootDeviceIndex].memory->setDefaultGmm(gmm);
|
|
|
|
allocationInfo[rootDeviceIndex].zeroCopyAllowed = true;
|
|
|
|
}
|
2021-03-30 00:39:45 +08:00
|
|
|
if (!allocationInfo[rootDeviceIndex].zeroCopyAllowed) {
|
|
|
|
if (allocationInfo[rootDeviceIndex].memory) {
|
|
|
|
AllocationProperties properties{rootDeviceIndex,
|
|
|
|
false, // allocateMemory
|
|
|
|
hostPtrMinSize, GraphicsAllocation::AllocationType::MAP_ALLOCATION,
|
|
|
|
false, // isMultiStorageAllocation
|
|
|
|
context->getDeviceBitfieldForAllocation(rootDeviceIndex)};
|
|
|
|
properties.flags.flushL3RequiredForRead = properties.flags.flushL3RequiredForWrite = true;
|
|
|
|
allocationInfo[rootDeviceIndex].mapAllocation = memoryManager->allocateGraphicsMemoryWithProperties(properties, hostPtr);
|
|
|
|
}
|
2020-12-04 17:54:30 +08:00
|
|
|
}
|
|
|
|
} else {
|
2021-07-02 00:00:22 +08:00
|
|
|
AllocationProperties allocProperties = MemObjHelper::getAllocationPropertiesWithImageInfo(rootDeviceIndex, imgInfo,
|
|
|
|
true, // allocateMemory
|
|
|
|
memoryProperties, hwInfo,
|
2021-07-07 20:43:54 +08:00
|
|
|
context->getDeviceBitfieldForAllocation(rootDeviceIndex),
|
|
|
|
context->isSingleDeviceContext());
|
2021-07-02 00:00:22 +08:00
|
|
|
allocationInfo[rootDeviceIndex].memory = memoryManager->allocateGraphicsMemoryWithProperties(allocProperties);
|
2020-12-04 17:54:30 +08:00
|
|
|
|
|
|
|
if (allocationInfo[rootDeviceIndex].memory && MemoryPool::isSystemMemoryPool(allocationInfo[rootDeviceIndex].memory->getMemoryPool())) {
|
|
|
|
allocationInfo[rootDeviceIndex].zeroCopyAllowed = true;
|
|
|
|
}
|
2018-08-22 16:00:40 +08:00
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2020-12-04 17:54:30 +08:00
|
|
|
allocationInfo[rootDeviceIndex].transferNeeded |= memoryProperties.flags.copyHostPtr;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
if (!allocationInfo[rootDeviceIndex].memory) {
|
|
|
|
cleanAllGraphicsAllocations(*context, *memoryManager, allocationInfo, isParentObject);
|
|
|
|
return image;
|
|
|
|
}
|
2019-06-17 19:18:26 +08:00
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
if (parentBuffer == nullptr) {
|
|
|
|
allocationInfo[rootDeviceIndex].memory->setAllocationType(GraphicsAllocation::AllocationType::IMAGE);
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
allocationInfo[rootDeviceIndex].memory->setMemObjectsAllocationWithWritableFlags(!memoryProperties.flags.readOnly &&
|
|
|
|
!memoryProperties.flags.hostReadOnly &&
|
|
|
|
!memoryProperties.flags.hostNoAccess);
|
|
|
|
|
|
|
|
DBG_LOG(LogMemoryObject, __FUNCTION__, "hostPtr:", hostPtr, "size:", allocationInfo[rootDeviceIndex].memory->getUnderlyingBufferSize(),
|
|
|
|
"memoryStorage:", allocationInfo[rootDeviceIndex].memory->getUnderlyingBuffer(), "GPU address:", std::hex, allocationInfo[rootDeviceIndex].memory->getGpuAddress());
|
|
|
|
|
|
|
|
if (parentImage) {
|
|
|
|
imageDescriptor.image_height = imageHeight;
|
|
|
|
imageDescriptor.image_width = imageWidth;
|
|
|
|
imageDescriptor.image_type = CL_MEM_OBJECT_IMAGE2D;
|
|
|
|
imageDescriptor.image_depth = 1;
|
|
|
|
imageDescriptor.image_array_size = 0;
|
|
|
|
imageDescriptor.image_row_pitch = 0;
|
|
|
|
imageDescriptor.image_slice_pitch = 0;
|
|
|
|
imageDescriptor.mem_object = imageDesc->mem_object;
|
|
|
|
parentImage->incRefInternal();
|
|
|
|
imgInfo.imgDesc = Image::convertDescriptor(imageDescriptor);
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
multiGraphicsAllocation.addAllocation(allocationInfo[rootDeviceIndex].memory);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
auto defaultRootDeviceIndex = context->getDevice(0u)->getRootDeviceIndex();
|
2020-07-16 18:15:52 +08:00
|
|
|
|
2021-07-02 00:00:22 +08:00
|
|
|
multiGraphicsAllocation.setMultiStorage(context->getRootDeviceIndices().size() > 1);
|
|
|
|
|
2019-10-17 20:18:55 +08:00
|
|
|
image = createImageHw(context, memoryProperties, flags, flagsIntel, imgInfo.size, hostPtrToSet, surfaceFormat->OCLImageFormat,
|
2020-12-04 17:54:30 +08:00
|
|
|
imageDescriptor, allocationInfo[defaultRootDeviceIndex].zeroCopyAllowed, std::move(multiGraphicsAllocation), false, 0, 0, surfaceFormat);
|
2021-03-24 21:19:30 +08:00
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
for (auto &rootDeviceIndex : context->getRootDeviceIndices()) {
|
|
|
|
|
2021-01-05 23:28:12 +08:00
|
|
|
auto &hwInfo = *memoryManager->peekExecutionEnvironment().rootDeviceEnvironments[rootDeviceIndex]->getHardwareInfo();
|
2020-12-04 17:54:30 +08:00
|
|
|
|
2021-01-05 23:28:12 +08:00
|
|
|
if (context->isProvidingPerformanceHints() && HwHelper::renderCompressedImagesSupported(hwInfo)) {
|
2020-12-04 17:54:30 +08:00
|
|
|
if (allocationInfo[rootDeviceIndex].memory->getDefaultGmm()) {
|
2021-06-09 00:37:54 +08:00
|
|
|
if (allocationInfo[rootDeviceIndex].memory->getDefaultGmm()->isCompressionEnabled) {
|
2020-12-04 17:54:30 +08:00
|
|
|
context->providePerformanceHint(CL_CONTEXT_DIAGNOSTICS_LEVEL_NEUTRAL_INTEL, IMAGE_IS_COMPRESSED, image);
|
|
|
|
} else {
|
|
|
|
context->providePerformanceHint(CL_CONTEXT_DIAGNOSTICS_LEVEL_NEUTRAL_INTEL, IMAGE_IS_NOT_COMPRESSED, image);
|
|
|
|
}
|
2019-06-29 00:22:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
if (imageDesc->image_type != CL_MEM_OBJECT_IMAGE1D_ARRAY && imageDesc->image_type != CL_MEM_OBJECT_IMAGE2D_ARRAY) {
|
|
|
|
image->imageDesc.image_array_size = 0;
|
|
|
|
}
|
|
|
|
if ((imageDesc->image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER) || ((imageDesc->image_type == CL_MEM_OBJECT_IMAGE2D) && (imageDesc->mem_object != nullptr))) {
|
|
|
|
image->associatedMemObject = castToObject<MemObj>(imageDesc->mem_object);
|
|
|
|
}
|
2018-12-20 03:15:32 +08:00
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
// Driver needs to store rowPitch passed by the app in order to synchronize the host_ptr later on map call
|
|
|
|
image->setHostPtrRowPitch(imageDesc->image_row_pitch ? imageDesc->image_row_pitch : hostPtrRowPitch);
|
|
|
|
image->setHostPtrSlicePitch(hostPtrSlicePitch);
|
|
|
|
image->setImageCount(imageCount);
|
|
|
|
image->setHostPtrMinSize(hostPtrMinSize);
|
|
|
|
image->setImageRowPitch(imgInfo.rowPitch);
|
|
|
|
image->setImageSlicePitch(imgInfo.slicePitch);
|
|
|
|
image->setQPitch(imgInfo.qPitch);
|
|
|
|
image->setSurfaceOffsets(imgInfo.offset, imgInfo.xOffset, imgInfo.yOffset, imgInfo.yOffsetForUVPlane);
|
|
|
|
image->setMipCount(imgInfo.mipCount);
|
|
|
|
if (parentImage) {
|
|
|
|
image->setMediaPlaneType(static_cast<cl_uint>(imageDesc->image_depth));
|
|
|
|
image->setParentSharingHandler(parentImage->getSharingHandler());
|
2018-03-07 21:37:09 +08:00
|
|
|
}
|
2020-12-04 17:54:30 +08:00
|
|
|
if (parentBuffer) {
|
|
|
|
image->setParentSharingHandler(parentBuffer->getSharingHandler());
|
|
|
|
}
|
|
|
|
errcodeRet = CL_SUCCESS;
|
|
|
|
if (context->isProvidingPerformanceHints() && image->isMemObjZeroCopy()) {
|
|
|
|
context->providePerformanceHint(CL_CONTEXT_DIAGNOSTICS_LEVEL_GOOD_INTEL, CL_IMAGE_MEETS_ALIGNMENT_RESTRICTIONS, static_cast<cl_mem>(image));
|
|
|
|
}
|
2021-07-02 00:00:22 +08:00
|
|
|
if (allocationInfo[rootDeviceIndex].transferNeeded && !transferedMemory) {
|
2020-12-04 17:54:30 +08:00
|
|
|
std::array<size_t, 3> copyOrigin = {{0, 0, 0}};
|
|
|
|
std::array<size_t, 3> copyRegion = {{imageWidth, imageHeight, std::max(imageDepth, imageCount)}};
|
|
|
|
if (imageDesc->image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY) {
|
|
|
|
copyRegion = {{imageWidth, imageCount, 1}};
|
|
|
|
} else {
|
|
|
|
copyRegion = {{imageWidth, imageHeight, std::max(imageDepth, imageCount)}};
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2021-01-05 23:28:12 +08:00
|
|
|
bool isCpuTransferPreferrred = imgInfo.linearStorage &&
|
|
|
|
(MemoryPool::isSystemMemoryPool(allocationInfo[rootDeviceIndex].memory->getMemoryPool()) ||
|
|
|
|
defaultHwHelper.isCpuImageTransferPreferred(hwInfo));
|
|
|
|
if (!isCpuTransferPreferrred) {
|
2020-12-04 17:54:30 +08:00
|
|
|
auto cmdQ = context->getSpecialQueue(rootDeviceIndex);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2021-06-28 13:06:24 +08:00
|
|
|
if (isNV12Image(&image->getImageFormat())) {
|
2020-12-04 17:54:30 +08:00
|
|
|
errcodeRet = image->writeNV12Planes(hostPtr, hostPtrRowPitch, rootDeviceIndex);
|
|
|
|
} else {
|
|
|
|
errcodeRet = cmdQ->enqueueWriteImage(image, CL_TRUE, ©Origin[0], ©Region[0],
|
|
|
|
hostPtrRowPitch, hostPtrSlicePitch,
|
|
|
|
hostPtr, allocationInfo[rootDeviceIndex].mapAllocation, 0, nullptr, nullptr);
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
} else {
|
2021-02-01 22:27:48 +08:00
|
|
|
void *pDestinationAddress = allocationInfo[rootDeviceIndex].memory->getUnderlyingBuffer();
|
2021-01-05 23:28:12 +08:00
|
|
|
auto isNotInSystemMemory = !MemoryPool::isSystemMemoryPool(allocationInfo[rootDeviceIndex].memory->getMemoryPool());
|
|
|
|
if (isNotInSystemMemory) {
|
2021-02-01 22:27:48 +08:00
|
|
|
pDestinationAddress = context->getMemoryManager()->lockResource(allocationInfo[rootDeviceIndex].memory);
|
2021-01-05 23:28:12 +08:00
|
|
|
}
|
|
|
|
|
2021-02-01 22:27:48 +08:00
|
|
|
image->transferData(pDestinationAddress, imgInfo.rowPitch, imgInfo.slicePitch,
|
2020-12-04 17:54:30 +08:00
|
|
|
const_cast<void *>(hostPtr), hostPtrRowPitch, hostPtrSlicePitch,
|
|
|
|
copyRegion, copyOrigin);
|
2021-01-05 23:28:12 +08:00
|
|
|
|
|
|
|
if (isNotInSystemMemory) {
|
2021-02-01 22:27:48 +08:00
|
|
|
context->getMemoryManager()->unlockResource(allocationInfo[rootDeviceIndex].memory);
|
2021-01-05 23:28:12 +08:00
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2021-07-02 00:00:22 +08:00
|
|
|
transferedMemory = true;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-12-04 17:54:30 +08:00
|
|
|
if (allocationInfo[rootDeviceIndex].mapAllocation) {
|
|
|
|
image->mapAllocations.addAllocation(allocationInfo[rootDeviceIndex].mapAllocation);
|
|
|
|
}
|
2020-07-23 20:52:32 +08:00
|
|
|
}
|
2018-02-09 03:55:31 +08:00
|
|
|
if (errcodeRet != CL_SUCCESS) {
|
|
|
|
image->release();
|
|
|
|
image = nullptr;
|
2020-12-04 17:54:30 +08:00
|
|
|
cleanAllGraphicsAllocations(*context, *memoryManager, allocationInfo, isParentObject);
|
|
|
|
return image;
|
2018-02-09 03:55:31 +08:00
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
} while (false);
|
|
|
|
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
2020-04-22 20:37:30 +08:00
|
|
|
Image *Image::createImageHw(Context *context, const MemoryProperties &memoryProperties, cl_mem_flags flags, cl_mem_flags_intel flagsIntel, size_t size, void *hostPtr,
|
2017-12-21 07:45:38 +08:00
|
|
|
const cl_image_format &imageFormat, const cl_image_desc &imageDesc,
|
2020-07-16 18:15:52 +08:00
|
|
|
bool zeroCopy, MultiGraphicsAllocation multiGraphicsAllocation,
|
2019-08-26 15:27:30 +08:00
|
|
|
bool isObjectRedescribed, uint32_t baseMipLevel, uint32_t mipCount,
|
2020-01-09 00:29:15 +08:00
|
|
|
const ClSurfaceFormatInfo *surfaceFormatInfo) {
|
2018-07-19 20:26:04 +08:00
|
|
|
const auto device = context->getDevice(0);
|
2017-12-21 07:45:38 +08:00
|
|
|
const auto &hwInfo = device->getHardwareInfo();
|
|
|
|
|
2019-05-08 22:00:24 +08:00
|
|
|
auto funcCreate = imageFactory[hwInfo.platform.eRenderCoreFamily].createImageFunction;
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(nullptr == funcCreate);
|
2019-10-17 20:18:55 +08:00
|
|
|
auto image = funcCreate(context, memoryProperties, flags, flagsIntel, size, hostPtr, imageFormat, imageDesc,
|
2020-07-16 18:15:52 +08:00
|
|
|
zeroCopy, std::move(multiGraphicsAllocation), isObjectRedescribed, baseMipLevel, mipCount, surfaceFormatInfo, nullptr);
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(nullptr == image);
|
|
|
|
image->createFunction = funcCreate;
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
2019-12-16 17:33:40 +08:00
|
|
|
Image *Image::createSharedImage(Context *context, SharingHandler *sharingHandler, const McsSurfaceInfo &mcsSurfaceInfo,
|
2020-07-16 18:15:52 +08:00
|
|
|
MultiGraphicsAllocation multiGraphicsAllocation, GraphicsAllocation *mcsAllocation,
|
2020-06-05 06:16:55 +08:00
|
|
|
cl_mem_flags flags, cl_mem_flags_intel flagsIntel, const ClSurfaceFormatInfo *surfaceFormat,
|
|
|
|
ImageInfo &imgInfo, uint32_t cubeFaceIndex, uint32_t baseMipLevel, uint32_t mipCount) {
|
2020-07-16 18:15:52 +08:00
|
|
|
auto rootDeviceIndex = context->getDevice(0)->getRootDeviceIndex();
|
|
|
|
auto size = multiGraphicsAllocation.getGraphicsAllocation(rootDeviceIndex)->getUnderlyingBufferSize();
|
2020-06-05 06:16:55 +08:00
|
|
|
auto sharedImage = createImageHw(
|
2021-10-07 01:00:24 +08:00
|
|
|
context, ClMemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context->getDevice(0)->getDevice()),
|
2020-07-16 18:15:52 +08:00
|
|
|
flags, flagsIntel, size, nullptr,
|
2020-06-05 06:16:55 +08:00
|
|
|
surfaceFormat->OCLImageFormat, Image::convertDescriptor(imgInfo.imgDesc), false,
|
2020-07-16 18:15:52 +08:00
|
|
|
std::move(multiGraphicsAllocation), false, baseMipLevel, mipCount, surfaceFormat);
|
2017-12-21 07:45:38 +08:00
|
|
|
sharedImage->setSharingHandler(sharingHandler);
|
|
|
|
sharedImage->setMcsAllocation(mcsAllocation);
|
|
|
|
sharedImage->setQPitch(imgInfo.qPitch);
|
2020-01-09 18:15:03 +08:00
|
|
|
sharedImage->setHostPtrRowPitch(imgInfo.imgDesc.imageRowPitch);
|
|
|
|
sharedImage->setHostPtrSlicePitch(imgInfo.imgDesc.imageSlicePitch);
|
2017-12-21 07:45:38 +08:00
|
|
|
sharedImage->setCubeFaceIndex(cubeFaceIndex);
|
|
|
|
sharedImage->setSurfaceOffsets(imgInfo.offset, imgInfo.xOffset, imgInfo.yOffset, imgInfo.yOffsetForUVPlane);
|
|
|
|
sharedImage->setMcsSurfaceInfo(mcsSurfaceInfo);
|
|
|
|
return sharedImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
cl_int Image::validate(Context *context,
|
2020-04-22 20:37:30 +08:00
|
|
|
const MemoryProperties &memoryProperties,
|
2020-01-09 00:29:15 +08:00
|
|
|
const ClSurfaceFormatInfo *surfaceFormat,
|
2017-12-21 07:45:38 +08:00
|
|
|
const cl_image_desc *imageDesc,
|
|
|
|
const void *hostPtr) {
|
2020-01-14 21:32:11 +08:00
|
|
|
auto pClDevice = context->getDevice(0);
|
2017-12-21 07:45:38 +08:00
|
|
|
size_t srcSize = 0;
|
|
|
|
size_t retSize = 0;
|
|
|
|
const size_t *maxWidth = nullptr;
|
|
|
|
const size_t *maxHeight = nullptr;
|
|
|
|
const uint32_t *pitchAlignment = nullptr;
|
|
|
|
const uint32_t *baseAddressAlignment = nullptr;
|
|
|
|
if (!surfaceFormat) {
|
|
|
|
return CL_IMAGE_FORMAT_NOT_SUPPORTED;
|
|
|
|
}
|
2018-04-05 21:05:33 +08:00
|
|
|
|
|
|
|
Image *parentImage = castToObject<Image>(imageDesc->mem_object);
|
|
|
|
Buffer *parentBuffer = castToObject<Buffer>(imageDesc->mem_object);
|
2018-04-10 16:56:37 +08:00
|
|
|
if (imageDesc->image_type == CL_MEM_OBJECT_IMAGE2D) {
|
2020-04-21 19:45:26 +08:00
|
|
|
if ((imageDesc->mem_object != nullptr) && (pClDevice->getSharedDeviceInfo().imageSupport == false)) {
|
|
|
|
return CL_INVALID_OPERATION;
|
|
|
|
}
|
|
|
|
|
2020-01-14 21:32:11 +08:00
|
|
|
pClDevice->getCap<CL_DEVICE_IMAGE2D_MAX_WIDTH>(reinterpret_cast<const void *&>(maxWidth), srcSize, retSize);
|
|
|
|
pClDevice->getCap<CL_DEVICE_IMAGE2D_MAX_HEIGHT>(reinterpret_cast<const void *&>(maxHeight), srcSize, retSize);
|
2017-12-21 07:45:38 +08:00
|
|
|
if (imageDesc->image_width > *maxWidth ||
|
|
|
|
imageDesc->image_height > *maxHeight) {
|
2018-04-10 16:56:37 +08:00
|
|
|
return CL_INVALID_IMAGE_SIZE;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-04-05 21:05:33 +08:00
|
|
|
if (parentBuffer) { // Image 2d from buffer
|
2020-01-14 21:32:11 +08:00
|
|
|
pClDevice->getCap<CL_DEVICE_IMAGE_PITCH_ALIGNMENT>(reinterpret_cast<const void *&>(pitchAlignment), srcSize, retSize);
|
|
|
|
pClDevice->getCap<CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT>(reinterpret_cast<const void *&>(baseAddressAlignment), srcSize, retSize);
|
2018-04-05 21:05:33 +08:00
|
|
|
|
2020-01-09 00:29:15 +08:00
|
|
|
const auto rowSize = imageDesc->image_row_pitch != 0 ? imageDesc->image_row_pitch : alignUp(imageDesc->image_width * surfaceFormat->surfaceFormat.NumChannels * surfaceFormat->surfaceFormat.PerChannelSizeInBytes, *pitchAlignment);
|
2018-06-05 17:03:13 +08:00
|
|
|
const auto minimumBufferSize = imageDesc->image_height * rowSize;
|
|
|
|
|
2018-04-05 21:05:33 +08:00
|
|
|
if ((imageDesc->image_row_pitch % (*pitchAlignment)) ||
|
2020-04-22 20:37:30 +08:00
|
|
|
((parentBuffer->getFlags() & CL_MEM_USE_HOST_PTR) && (reinterpret_cast<uint64_t>(parentBuffer->getHostPtr()) % (*baseAddressAlignment))) ||
|
2018-06-05 17:03:13 +08:00
|
|
|
(minimumBufferSize > parentBuffer->getSize())) {
|
2018-04-10 16:56:37 +08:00
|
|
|
return CL_INVALID_IMAGE_FORMAT_DESCRIPTOR;
|
2019-08-22 18:31:07 +08:00
|
|
|
} else if (memoryProperties.flags.useHostPtr || memoryProperties.flags.copyHostPtr) {
|
2018-04-10 16:56:37 +08:00
|
|
|
return CL_INVALID_VALUE;
|
2018-04-05 21:05:33 +08:00
|
|
|
}
|
|
|
|
}
|
2021-06-28 13:06:24 +08:00
|
|
|
if (parentImage && !isNV12Image(&parentImage->getImageFormat())) { // Image 2d from image 2d
|
2018-04-05 21:05:33 +08:00
|
|
|
if (!parentImage->hasSameDescriptor(*imageDesc) || !parentImage->hasValidParentImageFormat(surfaceFormat->OCLImageFormat)) {
|
2018-04-10 16:56:37 +08:00
|
|
|
return CL_INVALID_IMAGE_FORMAT_DESCRIPTOR;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-04-10 15:19:27 +08:00
|
|
|
}
|
2021-06-28 13:06:24 +08:00
|
|
|
if (!(parentImage && isNV12Image(&parentImage->getImageFormat())) &&
|
2018-04-10 16:56:37 +08:00
|
|
|
(imageDesc->image_width == 0 || imageDesc->image_height == 0)) {
|
|
|
|
return CL_INVALID_IMAGE_DESCRIPTOR;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (hostPtr == nullptr) {
|
|
|
|
if (imageDesc->image_row_pitch != 0 && imageDesc->mem_object == nullptr) {
|
2018-04-10 16:56:37 +08:00
|
|
|
return CL_INVALID_IMAGE_DESCRIPTOR;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (imageDesc->image_row_pitch != 0) {
|
2020-01-09 00:29:15 +08:00
|
|
|
if (imageDesc->image_row_pitch % surfaceFormat->surfaceFormat.ImageElementSizeInBytes != 0 ||
|
|
|
|
imageDesc->image_row_pitch < imageDesc->image_width * surfaceFormat->surfaceFormat.ImageElementSizeInBytes) {
|
2018-04-10 16:56:37 +08:00
|
|
|
return CL_INVALID_IMAGE_DESCRIPTOR;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-05 21:05:33 +08:00
|
|
|
if (parentBuffer && imageDesc->image_type != CL_MEM_OBJECT_IMAGE1D_BUFFER && imageDesc->image_type != CL_MEM_OBJECT_IMAGE2D) {
|
2018-04-10 16:56:37 +08:00
|
|
|
return CL_INVALID_IMAGE_DESCRIPTOR;
|
2018-04-05 21:05:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (parentImage && imageDesc->image_type != CL_MEM_OBJECT_IMAGE2D) {
|
2018-04-10 16:56:37 +08:00
|
|
|
return CL_INVALID_IMAGE_DESCRIPTOR;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2019-08-20 21:00:07 +08:00
|
|
|
return validateImageTraits(context, memoryProperties, &surfaceFormat->OCLImageFormat, imageDesc, hostPtr);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
cl_int Image::validateImageFormat(const cl_image_format *imageFormat) {
|
|
|
|
if (!imageFormat) {
|
|
|
|
return CL_INVALID_IMAGE_FORMAT_DESCRIPTOR;
|
|
|
|
}
|
|
|
|
bool isValidFormat = isValidSingleChannelFormat(imageFormat) ||
|
|
|
|
isValidIntensityFormat(imageFormat) ||
|
|
|
|
isValidLuminanceFormat(imageFormat) ||
|
|
|
|
isValidDepthFormat(imageFormat) ||
|
|
|
|
isValidDoubleChannelFormat(imageFormat) ||
|
|
|
|
isValidTripleChannelFormat(imageFormat) ||
|
|
|
|
isValidRGBAFormat(imageFormat) ||
|
|
|
|
isValidSRGBFormat(imageFormat) ||
|
|
|
|
isValidARGBFormat(imageFormat) ||
|
2020-01-07 22:07:48 +08:00
|
|
|
isValidDepthStencilFormat(imageFormat) ||
|
|
|
|
isValidYUVFormat(imageFormat);
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
if (isValidFormat) {
|
|
|
|
return CL_SUCCESS;
|
|
|
|
}
|
|
|
|
return CL_INVALID_IMAGE_FORMAT_DESCRIPTOR;
|
|
|
|
}
|
|
|
|
|
|
|
|
cl_int Image::validatePlanarYUV(Context *context,
|
2020-04-22 20:37:30 +08:00
|
|
|
const MemoryProperties &memoryProperties,
|
2017-12-21 07:45:38 +08:00
|
|
|
const cl_image_desc *imageDesc,
|
|
|
|
const void *hostPtr) {
|
|
|
|
cl_int errorCode = CL_SUCCESS;
|
2020-01-14 21:32:11 +08:00
|
|
|
auto pClDevice = context->getDevice(0);
|
2017-12-21 07:45:38 +08:00
|
|
|
const size_t *maxWidth = nullptr;
|
|
|
|
const size_t *maxHeight = nullptr;
|
|
|
|
size_t srcSize = 0;
|
|
|
|
size_t retSize = 0;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
|
|
Image *memObject = castToObject<Image>(imageDesc->mem_object);
|
|
|
|
if (memObject != nullptr) {
|
|
|
|
if (memObject->memObjectType == CL_MEM_OBJECT_IMAGE2D) {
|
|
|
|
if (imageDesc->image_depth != 1 && imageDesc->image_depth != 0) {
|
|
|
|
errorCode = CL_INVALID_IMAGE_DESCRIPTOR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (imageDesc->mem_object != nullptr) {
|
|
|
|
errorCode = CL_INVALID_IMAGE_DESCRIPTOR;
|
|
|
|
break;
|
|
|
|
}
|
2019-08-22 18:31:07 +08:00
|
|
|
if (!memoryProperties.flags.hostNoAccess) {
|
2017-12-21 07:45:38 +08:00
|
|
|
errorCode = CL_INVALID_VALUE;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
if (imageDesc->image_height % 4 ||
|
|
|
|
imageDesc->image_width % 4 ||
|
|
|
|
imageDesc->image_type != CL_MEM_OBJECT_IMAGE2D) {
|
|
|
|
errorCode = CL_INVALID_IMAGE_DESCRIPTOR;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-14 21:32:11 +08:00
|
|
|
pClDevice->getCap<CL_DEVICE_PLANAR_YUV_MAX_WIDTH_INTEL>(reinterpret_cast<const void *&>(maxWidth), srcSize, retSize);
|
|
|
|
pClDevice->getCap<CL_DEVICE_PLANAR_YUV_MAX_HEIGHT_INTEL>(reinterpret_cast<const void *&>(maxHeight), srcSize, retSize);
|
2017-12-21 07:45:38 +08:00
|
|
|
if (imageDesc->image_width > *maxWidth || imageDesc->image_height > *maxHeight) {
|
|
|
|
errorCode = CL_INVALID_IMAGE_SIZE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return errorCode;
|
|
|
|
}
|
|
|
|
|
2020-04-22 20:37:30 +08:00
|
|
|
cl_int Image::validatePackedYUV(const MemoryProperties &memoryProperties, const cl_image_desc *imageDesc) {
|
2017-12-21 07:45:38 +08:00
|
|
|
cl_int errorCode = CL_SUCCESS;
|
|
|
|
while (true) {
|
2019-08-22 18:31:07 +08:00
|
|
|
if (!memoryProperties.flags.readOnly) {
|
2017-12-21 07:45:38 +08:00
|
|
|
errorCode = CL_INVALID_VALUE;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
if (imageDesc->image_width % 2 != 0 ||
|
|
|
|
imageDesc->image_type != CL_MEM_OBJECT_IMAGE2D) {
|
|
|
|
errorCode = CL_INVALID_IMAGE_DESCRIPTOR;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return errorCode;
|
|
|
|
}
|
|
|
|
|
2020-04-22 20:37:30 +08:00
|
|
|
cl_int Image::validateImageTraits(Context *context, const MemoryProperties &memoryProperties, const cl_image_format *imageFormat, const cl_image_desc *imageDesc, const void *hostPtr) {
|
2021-06-28 13:06:24 +08:00
|
|
|
if (isNV12Image(imageFormat))
|
2019-08-20 21:00:07 +08:00
|
|
|
return validatePlanarYUV(context, memoryProperties, imageDesc, hostPtr);
|
2021-06-28 13:06:24 +08:00
|
|
|
else if (isPackedYuvImage(imageFormat))
|
2019-08-20 21:00:07 +08:00
|
|
|
return validatePackedYUV(memoryProperties, imageDesc);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
return CL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2018-12-12 00:06:47 +08:00
|
|
|
size_t Image::calculateHostPtrSize(const size_t *region, size_t rowPitch, size_t slicePitch, size_t pixelSize, uint32_t imageType) {
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(!((rowPitch != 0) && (slicePitch != 0)));
|
|
|
|
size_t sizeToReturn = 0u;
|
|
|
|
|
|
|
|
switch (imageType) {
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D:
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
|
|
|
|
sizeToReturn = region[0] * pixelSize;
|
|
|
|
break;
|
|
|
|
case CL_MEM_OBJECT_IMAGE2D:
|
|
|
|
sizeToReturn = (region[1] - 1) * rowPitch + region[0] * pixelSize;
|
|
|
|
break;
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
|
|
|
sizeToReturn = (region[1] - 1) * slicePitch + region[0] * pixelSize;
|
|
|
|
break;
|
|
|
|
case CL_MEM_OBJECT_IMAGE3D:
|
|
|
|
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
|
|
|
sizeToReturn = (region[2] - 1) * slicePitch + (region[1] - 1) * rowPitch + region[0] * pixelSize;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DEBUG_BREAK_IF("Unsupported cl_image_type");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG_BREAK_IF(sizeToReturn == 0);
|
|
|
|
return sizeToReturn;
|
|
|
|
}
|
|
|
|
|
2018-02-02 17:19:13 +08:00
|
|
|
void Image::calculateHostPtrOffset(size_t *imageOffset, const size_t *origin, const size_t *region, size_t rowPitch, size_t slicePitch, uint32_t imageType, size_t bytesPerPixel) {
|
|
|
|
|
|
|
|
size_t computedImageRowPitch = rowPitch ? rowPitch : region[0] * bytesPerPixel;
|
|
|
|
size_t computedImageSlicePitch = slicePitch ? slicePitch : region[1] * computedImageRowPitch * bytesPerPixel;
|
|
|
|
switch (imageType) {
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D:
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
|
|
|
|
case CL_MEM_OBJECT_IMAGE2D:
|
|
|
|
DEBUG_BREAK_IF(slicePitch != 0 && slicePitch < computedImageRowPitch * region[1]);
|
2018-02-11 11:46:02 +08:00
|
|
|
CPP_ATTRIBUTE_FALLTHROUGH;
|
2018-02-02 17:19:13 +08:00
|
|
|
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
|
|
|
case CL_MEM_OBJECT_IMAGE3D:
|
|
|
|
*imageOffset = origin[2] * computedImageSlicePitch + origin[1] * computedImageRowPitch + origin[0] * bytesPerPixel;
|
|
|
|
break;
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
|
|
|
*imageOffset = origin[1] * computedImageSlicePitch + origin[0] * bytesPerPixel;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DEBUG_BREAK_IF("Unsupported cl_image_type");
|
|
|
|
*imageOffset = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
// Called by clGetImageParamsINTEL to obtain image row pitch and slice pitch
|
|
|
|
// Assumption: all parameters are already validated be calling function
|
|
|
|
cl_int Image::getImageParams(Context *context,
|
|
|
|
cl_mem_flags memFlags,
|
2020-01-09 00:29:15 +08:00
|
|
|
const ClSurfaceFormatInfo *surfaceFormat,
|
2017-12-21 07:45:38 +08:00
|
|
|
const cl_image_desc *imageDesc,
|
|
|
|
size_t *imageRowPitch,
|
|
|
|
size_t *imageSlicePitch) {
|
|
|
|
cl_int retVal = CL_SUCCESS;
|
2020-02-25 01:04:30 +08:00
|
|
|
auto clientContext = context->getDevice(0)->getRootDeviceEnvironment().getGmmClientContext();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-01-08 18:11:54 +08:00
|
|
|
ImageInfo imgInfo = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
cl_image_desc imageDescriptor = *imageDesc;
|
2020-01-08 18:11:54 +08:00
|
|
|
imgInfo.imgDesc = Image::convertDescriptor(imageDescriptor);
|
2020-01-09 00:29:15 +08:00
|
|
|
imgInfo.surfaceFormat = &surfaceFormat->surfaceFormat;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-12-30 21:14:27 +08:00
|
|
|
auto gmm = std::make_unique<Gmm>(clientContext, imgInfo, StorageInfo{});
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
*imageRowPitch = imgInfo.rowPitch;
|
|
|
|
*imageSlicePitch = imgInfo.slicePitch;
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
const cl_image_desc &Image::getImageDesc() const {
|
|
|
|
return imageDesc;
|
|
|
|
}
|
|
|
|
|
|
|
|
const cl_image_format &Image::getImageFormat() const {
|
|
|
|
return imageFormat;
|
|
|
|
}
|
|
|
|
|
2020-01-09 00:29:15 +08:00
|
|
|
const ClSurfaceFormatInfo &Image::getSurfaceFormatInfo() const {
|
2017-12-21 07:45:38 +08:00
|
|
|
return surfaceFormatInfo;
|
|
|
|
}
|
|
|
|
|
2020-01-08 18:11:54 +08:00
|
|
|
cl_mem_object_type Image::convertType(const ImageType type) {
|
|
|
|
switch (type) {
|
|
|
|
case ImageType::Image2D:
|
|
|
|
return CL_MEM_OBJECT_IMAGE2D;
|
|
|
|
case ImageType::Image3D:
|
|
|
|
return CL_MEM_OBJECT_IMAGE3D;
|
|
|
|
case ImageType::Image2DArray:
|
|
|
|
return CL_MEM_OBJECT_IMAGE2D_ARRAY;
|
|
|
|
case ImageType::Image1D:
|
|
|
|
return CL_MEM_OBJECT_IMAGE1D;
|
|
|
|
case ImageType::Image1DArray:
|
|
|
|
return CL_MEM_OBJECT_IMAGE1D_ARRAY;
|
|
|
|
case ImageType::Image1DBuffer:
|
|
|
|
return CL_MEM_OBJECT_IMAGE1D_BUFFER;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImageType Image::convertType(const cl_mem_object_type type) {
|
|
|
|
switch (type) {
|
|
|
|
case CL_MEM_OBJECT_IMAGE2D:
|
|
|
|
return ImageType::Image2D;
|
|
|
|
case CL_MEM_OBJECT_IMAGE3D:
|
|
|
|
return ImageType::Image3D;
|
|
|
|
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
|
|
|
return ImageType::Image2DArray;
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D:
|
|
|
|
return ImageType::Image1D;
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
|
|
|
return ImageType::Image1DArray;
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
|
|
|
|
return ImageType::Image1DBuffer;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return ImageType::Invalid;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImageDescriptor Image::convertDescriptor(const cl_image_desc &imageDesc) {
|
|
|
|
ImageDescriptor desc = {};
|
2020-01-09 18:15:03 +08:00
|
|
|
desc.fromParent = imageDesc.mem_object != nullptr;
|
|
|
|
desc.imageArraySize = imageDesc.image_array_size;
|
|
|
|
desc.imageDepth = imageDesc.image_depth;
|
|
|
|
desc.imageHeight = imageDesc.image_height;
|
|
|
|
desc.imageRowPitch = imageDesc.image_row_pitch;
|
|
|
|
desc.imageSlicePitch = imageDesc.image_slice_pitch;
|
|
|
|
desc.imageType = convertType(imageDesc.image_type);
|
|
|
|
desc.imageWidth = imageDesc.image_width;
|
|
|
|
desc.numMipLevels = imageDesc.num_mip_levels;
|
|
|
|
desc.numSamples = imageDesc.num_samples;
|
2020-01-08 18:11:54 +08:00
|
|
|
return desc;
|
|
|
|
}
|
|
|
|
|
|
|
|
cl_image_desc Image::convertDescriptor(const ImageDescriptor &imageDesc) {
|
|
|
|
cl_image_desc desc = {};
|
|
|
|
desc.mem_object = nullptr;
|
2020-01-09 18:15:03 +08:00
|
|
|
desc.image_array_size = imageDesc.imageArraySize;
|
|
|
|
desc.image_depth = imageDesc.imageDepth;
|
|
|
|
desc.image_height = imageDesc.imageHeight;
|
|
|
|
desc.image_row_pitch = imageDesc.imageRowPitch;
|
|
|
|
desc.image_slice_pitch = imageDesc.imageSlicePitch;
|
|
|
|
desc.image_type = convertType(imageDesc.imageType);
|
|
|
|
desc.image_width = imageDesc.imageWidth;
|
|
|
|
desc.num_mip_levels = imageDesc.numMipLevels;
|
|
|
|
desc.num_samples = imageDesc.numSamples;
|
2020-01-08 18:11:54 +08:00
|
|
|
return desc;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
cl_int Image::getImageInfo(cl_image_info paramName,
|
|
|
|
size_t paramValueSize,
|
|
|
|
void *paramValue,
|
|
|
|
size_t *paramValueSizeRet) {
|
|
|
|
cl_int retVal;
|
2020-05-18 22:13:59 +08:00
|
|
|
size_t srcParamSize = GetInfo::invalidSourceSize;
|
2017-12-21 07:45:38 +08:00
|
|
|
void *srcParam = nullptr;
|
|
|
|
auto imageDesc = getImageDesc();
|
|
|
|
auto surfFmtInfo = getSurfaceFormatInfo();
|
|
|
|
size_t retParam;
|
|
|
|
size_t array_size = imageDesc.image_array_size * (imageDesc.image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY || imageDesc.image_type == CL_MEM_OBJECT_IMAGE2D_ARRAY);
|
|
|
|
size_t SlicePitch = hostPtrSlicePitch * !(imageDesc.image_type == CL_MEM_OBJECT_IMAGE2D || imageDesc.image_type == CL_MEM_OBJECT_IMAGE1D || imageDesc.image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER);
|
|
|
|
|
|
|
|
switch (paramName) {
|
|
|
|
case CL_IMAGE_FORMAT:
|
|
|
|
srcParamSize = sizeof(cl_image_format);
|
|
|
|
srcParam = &(surfFmtInfo.OCLImageFormat);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_IMAGE_ELEMENT_SIZE:
|
|
|
|
srcParamSize = sizeof(size_t);
|
2020-01-09 00:29:15 +08:00
|
|
|
srcParam = &(surfFmtInfo.surfaceFormat.ImageElementSizeInBytes);
|
2017-12-21 07:45:38 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_IMAGE_ROW_PITCH:
|
|
|
|
srcParamSize = sizeof(size_t);
|
2018-06-13 18:46:54 +08:00
|
|
|
if (mcsSurfaceInfo.multisampleCount > 1) {
|
2020-01-09 00:29:15 +08:00
|
|
|
retParam = imageDesc.image_width * surfFmtInfo.surfaceFormat.ImageElementSizeInBytes * imageDesc.num_samples;
|
2018-06-13 18:46:54 +08:00
|
|
|
} else {
|
|
|
|
retParam = hostPtrRowPitch;
|
|
|
|
}
|
|
|
|
srcParam = &retParam;
|
2017-12-21 07:45:38 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_IMAGE_SLICE_PITCH:
|
|
|
|
srcParamSize = sizeof(size_t);
|
|
|
|
srcParam = &SlicePitch;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_IMAGE_WIDTH:
|
|
|
|
srcParamSize = sizeof(size_t);
|
|
|
|
retParam = imageDesc.image_width;
|
2018-04-04 15:29:48 +08:00
|
|
|
if (this->baseMipLevel) {
|
|
|
|
retParam = imageDesc.image_width >> this->baseMipLevel;
|
2017-12-21 07:45:38 +08:00
|
|
|
retParam = std::max(retParam, (size_t)1);
|
|
|
|
}
|
|
|
|
srcParam = &retParam;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_IMAGE_HEIGHT:
|
|
|
|
srcParamSize = sizeof(size_t);
|
|
|
|
retParam = imageDesc.image_height * !((imageDesc.image_type == CL_MEM_OBJECT_IMAGE1D) || (imageDesc.image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY) || (imageDesc.image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER));
|
2018-04-04 15:29:48 +08:00
|
|
|
if ((retParam != 0) && (this->baseMipLevel > 0)) {
|
|
|
|
retParam = retParam >> this->baseMipLevel;
|
2017-12-21 07:45:38 +08:00
|
|
|
retParam = std::max(retParam, (size_t)1);
|
|
|
|
}
|
|
|
|
srcParam = &retParam;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_IMAGE_DEPTH:
|
|
|
|
srcParamSize = sizeof(size_t);
|
|
|
|
retParam = imageDesc.image_depth * (imageDesc.image_type == CL_MEM_OBJECT_IMAGE3D);
|
2018-04-04 15:29:48 +08:00
|
|
|
if ((retParam != 0) && (this->baseMipLevel > 0)) {
|
|
|
|
retParam = retParam >> this->baseMipLevel;
|
2017-12-21 07:45:38 +08:00
|
|
|
retParam = std::max(retParam, (size_t)1);
|
|
|
|
}
|
|
|
|
srcParam = &retParam;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_IMAGE_ARRAY_SIZE:
|
|
|
|
srcParamSize = sizeof(size_t);
|
|
|
|
srcParam = &(array_size);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_IMAGE_BUFFER:
|
|
|
|
srcParamSize = sizeof(cl_mem);
|
|
|
|
srcParam = &(imageDesc.buffer);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_IMAGE_NUM_MIP_LEVELS:
|
|
|
|
srcParamSize = sizeof(cl_uint);
|
|
|
|
srcParam = &(imageDesc.num_mip_levels);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_IMAGE_NUM_SAMPLES:
|
|
|
|
srcParamSize = sizeof(cl_uint);
|
|
|
|
srcParam = &(imageDesc.num_samples);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
getOsSpecificImageInfo(paramName, &srcParamSize, &srcParam);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-05-18 22:13:59 +08:00
|
|
|
auto getInfoStatus = GetInfo::getInfo(paramValue, paramValueSize, srcParam, srcParamSize);
|
|
|
|
retVal = changeGetInfoStatusToCLResultType(getInfoStatus);
|
|
|
|
GetInfo::setParamValueReturnSize(paramValueSizeRet, srcParamSize, getInfoStatus);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
Image *Image::redescribeFillImage() {
|
|
|
|
const uint32_t redescribeTable[3][3] = {
|
|
|
|
{17, 27, 5}, // {CL_R, CL_UNSIGNED_INT8}, {CL_RG, CL_UNSIGNED_INT8}, {CL_RGBA, CL_UNSIGNED_INT8}
|
|
|
|
{18, 28, 6}, // {CL_R, CL_UNSIGNED_INT16}, {CL_RG, CL_UNSIGNED_INT16}, {CL_RGBA, CL_UNSIGNED_INT16}
|
|
|
|
{19, 29, 7} // {CL_R, CL_UNSIGNED_INT32}, {CL_RG, CL_UNSIGNED_INT32}, {CL_RGBA, CL_UNSIGNED_INT32}
|
|
|
|
};
|
|
|
|
|
|
|
|
auto imageFormatNew = this->imageFormat;
|
|
|
|
auto imageDescNew = this->imageDesc;
|
2020-01-09 00:29:15 +08:00
|
|
|
const ClSurfaceFormatInfo *surfaceFormat = nullptr;
|
|
|
|
uint32_t redescribeTableCol = this->surfaceFormatInfo.surfaceFormat.NumChannels / 2;
|
|
|
|
uint32_t redescribeTableRow = this->surfaceFormatInfo.surfaceFormat.PerChannelSizeInBytes / 2;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-01-09 00:29:15 +08:00
|
|
|
ArrayRef<const ClSurfaceFormatInfo> readWriteSurfaceFormats = SurfaceFormats::readWrite();
|
2018-09-11 19:08:29 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
uint32_t surfaceFormatIdx = redescribeTable[redescribeTableRow][redescribeTableCol];
|
|
|
|
surfaceFormat = &readWriteSurfaceFormats[surfaceFormatIdx];
|
|
|
|
|
|
|
|
imageFormatNew.image_channel_order = surfaceFormat->OCLImageFormat.image_channel_order;
|
|
|
|
imageFormatNew.image_channel_data_type = surfaceFormat->OCLImageFormat.image_channel_data_type;
|
|
|
|
|
|
|
|
DEBUG_BREAK_IF(nullptr == createFunction);
|
2021-10-07 01:00:24 +08:00
|
|
|
MemoryProperties memoryProperties = ClMemoryPropertiesHelper::createMemoryProperties(flags | CL_MEM_USE_HOST_PTR, flagsIntel, 0,
|
|
|
|
&context->getDevice(0)->getDevice());
|
2017-12-21 07:45:38 +08:00
|
|
|
auto image = createFunction(context,
|
2019-10-09 23:29:00 +08:00
|
|
|
memoryProperties,
|
|
|
|
flags | CL_MEM_USE_HOST_PTR,
|
|
|
|
flagsIntel,
|
2017-12-21 07:45:38 +08:00
|
|
|
this->getSize(),
|
|
|
|
this->getCpuAddress(),
|
|
|
|
imageFormatNew,
|
|
|
|
imageDescNew,
|
|
|
|
this->isMemObjZeroCopy(),
|
2020-07-16 18:15:52 +08:00
|
|
|
this->multiGraphicsAllocation,
|
2017-12-21 07:45:38 +08:00
|
|
|
true,
|
2018-04-04 15:29:48 +08:00
|
|
|
this->baseMipLevel,
|
|
|
|
this->mipCount,
|
2017-12-21 07:45:38 +08:00
|
|
|
surfaceFormat,
|
|
|
|
&this->surfaceOffsets);
|
|
|
|
image->setQPitch(this->getQPitch());
|
|
|
|
image->setCubeFaceIndex(this->getCubeFaceIndex());
|
2018-12-20 03:15:32 +08:00
|
|
|
image->associatedMemObject = this->associatedMemObject;
|
2017-12-21 07:45:38 +08:00
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
2020-02-10 22:05:12 +08:00
|
|
|
static const uint32_t redescribeTableBytes[] = {
|
|
|
|
17, // {CL_R, CL_UNSIGNED_INT8} 1 byte
|
|
|
|
18, // {CL_R, CL_UNSIGNED_INT16} 2 byte
|
|
|
|
19, // {CL_R, CL_UNSIGNED_INT32} 4 byte
|
|
|
|
29, // {CL_RG, CL_UNSIGNED_INT32} 8 byte
|
|
|
|
7 // {CL_RGBA, CL_UNSIGNED_INT32} 16 byte
|
|
|
|
};
|
|
|
|
|
|
|
|
bool Image::isFormatRedescribable(cl_image_format format) {
|
|
|
|
const ArrayRef<const ClSurfaceFormatInfo> readWriteSurfaceFormats = SurfaceFormats::readWrite();
|
|
|
|
for (auto indexInRedescribeTable = 0u; indexInRedescribeTable < sizeof(redescribeTableBytes) / sizeof(uint32_t); indexInRedescribeTable++) {
|
|
|
|
const uint32_t formatIndex = redescribeTableBytes[indexInRedescribeTable];
|
|
|
|
const cl_image_format nonRedescribableFormat = readWriteSurfaceFormats[formatIndex].OCLImageFormat;
|
|
|
|
if (nonRedescribableFormat.image_channel_data_type == format.image_channel_data_type &&
|
|
|
|
nonRedescribableFormat.image_channel_order == format.image_channel_order) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-02-10 22:05:12 +08:00
|
|
|
Image *Image::redescribe() {
|
2020-01-09 00:29:15 +08:00
|
|
|
const uint32_t bytesPerPixel = this->surfaceFormatInfo.surfaceFormat.NumChannels * surfaceFormatInfo.surfaceFormat.PerChannelSizeInBytes;
|
2019-12-13 23:02:06 +08:00
|
|
|
const uint32_t exponent = Math::log2(bytesPerPixel);
|
|
|
|
DEBUG_BREAK_IF(exponent >= 5u);
|
|
|
|
const uint32_t surfaceFormatIdx = redescribeTableBytes[exponent % 5];
|
2020-01-09 00:29:15 +08:00
|
|
|
const ArrayRef<const ClSurfaceFormatInfo> readWriteSurfaceFormats = SurfaceFormats::readWrite();
|
|
|
|
const ClSurfaceFormatInfo *surfaceFormat = &readWriteSurfaceFormats[surfaceFormatIdx];
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-12-13 23:02:06 +08:00
|
|
|
auto imageFormatNew = this->imageFormat;
|
2017-12-21 07:45:38 +08:00
|
|
|
imageFormatNew.image_channel_order = surfaceFormat->OCLImageFormat.image_channel_order;
|
|
|
|
imageFormatNew.image_channel_data_type = surfaceFormat->OCLImageFormat.image_channel_data_type;
|
|
|
|
|
|
|
|
DEBUG_BREAK_IF(nullptr == createFunction);
|
2021-10-07 01:00:24 +08:00
|
|
|
MemoryProperties memoryProperties = ClMemoryPropertiesHelper::createMemoryProperties(flags | CL_MEM_USE_HOST_PTR, flagsIntel, 0,
|
|
|
|
&context->getDevice(0)->getDevice());
|
2017-12-21 07:45:38 +08:00
|
|
|
auto image = createFunction(context,
|
2019-10-09 23:29:00 +08:00
|
|
|
memoryProperties,
|
|
|
|
flags | CL_MEM_USE_HOST_PTR,
|
|
|
|
flagsIntel,
|
2017-12-21 07:45:38 +08:00
|
|
|
this->getSize(),
|
|
|
|
this->getCpuAddress(),
|
|
|
|
imageFormatNew,
|
2019-12-13 23:02:06 +08:00
|
|
|
this->imageDesc,
|
2017-12-21 07:45:38 +08:00
|
|
|
this->isMemObjZeroCopy(),
|
2020-07-16 18:15:52 +08:00
|
|
|
this->multiGraphicsAllocation,
|
2017-12-21 07:45:38 +08:00
|
|
|
true,
|
2018-04-04 15:29:48 +08:00
|
|
|
this->baseMipLevel,
|
|
|
|
this->mipCount,
|
2017-12-21 07:45:38 +08:00
|
|
|
surfaceFormat,
|
|
|
|
&this->surfaceOffsets);
|
|
|
|
image->setQPitch(this->getQPitch());
|
|
|
|
image->setCubeFaceIndex(this->getCubeFaceIndex());
|
2018-12-20 03:15:32 +08:00
|
|
|
image->associatedMemObject = this->associatedMemObject;
|
2021-06-18 15:30:24 +08:00
|
|
|
image->createFunction = createFunction;
|
2017-12-21 07:45:38 +08:00
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
2018-02-18 05:26:28 +08:00
|
|
|
void Image::transferDataToHostPtr(MemObjSizeArray ©Size, MemObjOffsetArray ©Offset) {
|
2018-02-09 03:55:31 +08:00
|
|
|
transferData(hostPtr, hostPtrRowPitch, hostPtrSlicePitch,
|
2020-06-24 18:40:22 +08:00
|
|
|
memoryStorage, imageDesc.image_row_pitch, imageDesc.image_slice_pitch,
|
2018-02-09 03:55:31 +08:00
|
|
|
copySize, copyOffset);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-02-18 05:26:28 +08:00
|
|
|
void Image::transferDataFromHostPtr(MemObjSizeArray ©Size, MemObjOffsetArray ©Offset) {
|
2018-02-09 03:55:31 +08:00
|
|
|
transferData(memoryStorage, imageDesc.image_row_pitch, imageDesc.image_slice_pitch,
|
|
|
|
hostPtr, hostPtrRowPitch, hostPtrSlicePitch,
|
|
|
|
copySize, copyOffset);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-10-29 17:21:29 +08:00
|
|
|
cl_int Image::writeNV12Planes(const void *hostPtr, size_t hostPtrRowPitch, uint32_t rootDeviceIndex) {
|
|
|
|
CommandQueue *cmdQ = context->getSpecialQueue(rootDeviceIndex);
|
2017-12-21 07:45:38 +08:00
|
|
|
size_t origin[3] = {0, 0, 0};
|
|
|
|
size_t region[3] = {this->imageDesc.image_width, this->imageDesc.image_height, 1};
|
|
|
|
|
|
|
|
cl_int retVal = 0;
|
|
|
|
cl_image_desc imageDesc = {0};
|
|
|
|
cl_image_format imageFormat = {0};
|
|
|
|
// Make NV12 planes readable and writable both on device and host
|
|
|
|
cl_mem_flags flags = CL_MEM_READ_WRITE;
|
|
|
|
|
|
|
|
// Plane Y
|
|
|
|
imageFormat.image_channel_data_type = CL_UNORM_INT8;
|
|
|
|
imageFormat.image_channel_order = CL_R;
|
|
|
|
|
|
|
|
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
|
|
|
|
// image_width & image_height are ignored for plane extraction
|
|
|
|
imageDesc.image_width = 0;
|
|
|
|
imageDesc.image_height = 0;
|
|
|
|
// set mem_object to the full NV12 image
|
|
|
|
imageDesc.mem_object = this;
|
|
|
|
// get access to the Y plane (CL_R)
|
|
|
|
imageDesc.image_depth = 0;
|
2020-04-30 21:47:43 +08:00
|
|
|
const ClSurfaceFormatInfo *surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat, context->getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
// Create NV12 UV Plane image
|
|
|
|
std::unique_ptr<Image> imageYPlane(Image::create(
|
|
|
|
context,
|
2021-10-07 01:00:24 +08:00
|
|
|
ClMemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context->getDevice(0)->getDevice()),
|
2017-12-21 07:45:38 +08:00
|
|
|
flags,
|
2019-10-17 20:18:55 +08:00
|
|
|
0,
|
2017-12-21 07:45:38 +08:00
|
|
|
surfaceFormat,
|
|
|
|
&imageDesc,
|
|
|
|
nullptr,
|
|
|
|
retVal));
|
|
|
|
|
2019-04-16 00:17:28 +08:00
|
|
|
retVal = cmdQ->enqueueWriteImage(imageYPlane.get(), CL_TRUE, origin, region, hostPtrRowPitch, 0, hostPtr, nullptr, 0, nullptr, nullptr);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
// UV Plane is two times smaller than Plane Y
|
|
|
|
region[0] = region[0] / 2;
|
|
|
|
region[1] = region[1] / 2;
|
|
|
|
|
|
|
|
imageDesc.image_width = 0;
|
|
|
|
imageDesc.image_height = 0;
|
|
|
|
imageDesc.image_depth = 1; // UV plane
|
|
|
|
imageFormat.image_channel_order = CL_RG;
|
|
|
|
|
|
|
|
hostPtr = static_cast<const void *>(static_cast<const char *>(hostPtr) + (hostPtrRowPitch * this->imageDesc.image_height));
|
2020-04-30 21:47:43 +08:00
|
|
|
surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat, context->getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features);
|
2017-12-21 07:45:38 +08:00
|
|
|
// Create NV12 UV Plane image
|
|
|
|
std::unique_ptr<Image> imageUVPlane(Image::create(
|
|
|
|
context,
|
2021-10-07 01:00:24 +08:00
|
|
|
ClMemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context->getDevice(0)->getDevice()),
|
2017-12-21 07:45:38 +08:00
|
|
|
flags,
|
2019-10-17 20:18:55 +08:00
|
|
|
0,
|
2017-12-21 07:45:38 +08:00
|
|
|
surfaceFormat,
|
|
|
|
&imageDesc,
|
|
|
|
nullptr,
|
|
|
|
retVal));
|
|
|
|
|
2019-04-16 00:17:28 +08:00
|
|
|
retVal = cmdQ->enqueueWriteImage(imageUVPlane.get(), CL_TRUE, origin, region, hostPtrRowPitch, 0, hostPtr, nullptr, 0, nullptr, nullptr);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
2020-04-30 21:47:43 +08:00
|
|
|
const ClSurfaceFormatInfo *Image::getSurfaceFormatFromTable(cl_mem_flags flags, const cl_image_format *imageFormat, bool supportsOcl20Features) {
|
2017-12-21 07:45:38 +08:00
|
|
|
if (!imageFormat) {
|
2018-08-20 14:32:57 +08:00
|
|
|
DEBUG_BREAK_IF("Invalid format");
|
2017-12-21 07:45:38 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-04-30 21:47:43 +08:00
|
|
|
ArrayRef<const ClSurfaceFormatInfo> formats = SurfaceFormats::surfaceFormats(flags, imageFormat, supportsOcl20Features);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-09-11 19:08:29 +08:00
|
|
|
for (auto &format : formats) {
|
|
|
|
if (format.OCLImageFormat.image_channel_data_type == imageFormat->image_channel_data_type &&
|
|
|
|
format.OCLImageFormat.image_channel_order == imageFormat->image_channel_order) {
|
|
|
|
return &format;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
}
|
2018-09-11 19:08:29 +08:00
|
|
|
DEBUG_BREAK_IF("Invalid format");
|
|
|
|
return nullptr;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2019-11-14 21:34:34 +08:00
|
|
|
bool Image::isImage1d(const cl_image_desc &imageDesc) {
|
|
|
|
auto imageType = imageDesc.image_type;
|
|
|
|
auto buffer = castToObject<Buffer>(imageDesc.buffer);
|
|
|
|
|
|
|
|
return (imageType == CL_MEM_OBJECT_IMAGE1D || imageType == CL_MEM_OBJECT_IMAGE1D_ARRAY ||
|
|
|
|
imageType == CL_MEM_OBJECT_IMAGE1D_BUFFER || buffer);
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
bool Image::isImage2d(cl_mem_object_type imageType) {
|
2019-02-28 18:21:01 +08:00
|
|
|
return imageType == CL_MEM_OBJECT_IMAGE2D;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::isImage2dOr2dArray(cl_mem_object_type imageType) {
|
2019-02-28 18:21:01 +08:00
|
|
|
return imageType == CL_MEM_OBJECT_IMAGE2D || imageType == CL_MEM_OBJECT_IMAGE2D_ARRAY;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::isDepthFormat(const cl_image_format &imageFormat) {
|
2019-02-28 18:21:01 +08:00
|
|
|
return imageFormat.image_channel_order == CL_DEPTH || imageFormat.image_channel_order == CL_DEPTH_STENCIL;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-05-12 19:47:44 +08:00
|
|
|
cl_mem Image::validateAndCreateImage(cl_context context,
|
|
|
|
const cl_mem_properties *properties,
|
2019-09-24 22:05:17 +08:00
|
|
|
cl_mem_flags flags,
|
|
|
|
cl_mem_flags_intel flagsIntel,
|
2017-12-21 07:45:38 +08:00
|
|
|
const cl_image_format *imageFormat,
|
|
|
|
const cl_image_desc *imageDesc,
|
|
|
|
const void *hostPtr,
|
|
|
|
cl_int &errcodeRet) {
|
2019-06-17 19:18:26 +08:00
|
|
|
|
2020-05-12 19:47:44 +08:00
|
|
|
Context *pContext = nullptr;
|
|
|
|
errcodeRet = validateObjects(WithCastToInternal(context, &pContext));
|
|
|
|
if (errcodeRet != CL_SUCCESS) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-06-05 06:16:55 +08:00
|
|
|
MemoryProperties memoryProperties{};
|
|
|
|
cl_mem_flags_intel emptyFlagsIntel = 0;
|
2020-05-12 19:47:44 +08:00
|
|
|
cl_mem_alloc_flags_intel allocflags = 0;
|
2021-10-07 01:00:24 +08:00
|
|
|
if ((false == ClMemoryPropertiesHelper::parseMemoryProperties(nullptr, memoryProperties, flags, emptyFlagsIntel, allocflags,
|
|
|
|
MemoryPropertiesHelper::ObjType::IMAGE, *pContext)) ||
|
2020-06-05 06:16:55 +08:00
|
|
|
(false == MemObjHelper::validateMemoryPropertiesForImage(memoryProperties, flags, emptyFlagsIntel, imageDesc->mem_object,
|
|
|
|
*pContext))) {
|
2019-06-17 19:18:26 +08:00
|
|
|
errcodeRet = CL_INVALID_VALUE;
|
2017-12-21 07:45:38 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
2019-06-17 19:18:26 +08:00
|
|
|
|
2021-10-07 01:00:24 +08:00
|
|
|
if ((false == ClMemoryPropertiesHelper::parseMemoryProperties(properties, memoryProperties, flags, flagsIntel, allocflags,
|
|
|
|
MemoryPropertiesHelper::ObjType::IMAGE, *pContext)) ||
|
2020-06-05 06:16:55 +08:00
|
|
|
(false == MemObjHelper::validateMemoryPropertiesForImage(memoryProperties, flags, flagsIntel, imageDesc->mem_object,
|
|
|
|
*pContext))) {
|
2020-05-12 19:47:44 +08:00
|
|
|
errcodeRet = CL_INVALID_PROPERTY;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2019-06-17 19:18:26 +08:00
|
|
|
bool isHostPtrUsed = (hostPtr != nullptr);
|
2019-10-17 20:18:55 +08:00
|
|
|
bool areHostPtrFlagsUsed = memoryProperties.flags.copyHostPtr || memoryProperties.flags.useHostPtr;
|
2019-06-17 19:18:26 +08:00
|
|
|
if (isHostPtrUsed != areHostPtrFlagsUsed) {
|
|
|
|
errcodeRet = CL_INVALID_HOST_PTR;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
errcodeRet = Image::validateImageFormat(imageFormat);
|
|
|
|
if (errcodeRet != CL_SUCCESS) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-05-12 19:47:44 +08:00
|
|
|
const auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, imageFormat, pContext->getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features);
|
2019-06-17 19:18:26 +08:00
|
|
|
|
2020-05-12 19:47:44 +08:00
|
|
|
errcodeRet = Image::validate(pContext, memoryProperties, surfaceFormat, imageDesc, hostPtr);
|
2019-06-17 19:18:26 +08:00
|
|
|
if (errcodeRet != CL_SUCCESS) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-05-27 23:12:32 +08:00
|
|
|
auto image = Image::create(pContext, memoryProperties, flags, flagsIntel, surfaceFormat, imageDesc, hostPtr, errcodeRet);
|
|
|
|
|
|
|
|
if (errcodeRet == CL_SUCCESS) {
|
|
|
|
image->storeProperties(properties);
|
|
|
|
}
|
|
|
|
|
|
|
|
return image;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::isValidSingleChannelFormat(const cl_image_format *imageFormat) {
|
|
|
|
auto channelOrder = imageFormat->image_channel_order;
|
|
|
|
auto dataType = imageFormat->image_channel_data_type;
|
|
|
|
|
|
|
|
bool isValidOrder = (channelOrder == CL_A) ||
|
|
|
|
(channelOrder == CL_R) ||
|
|
|
|
(channelOrder == CL_Rx);
|
|
|
|
|
|
|
|
bool isValidDataType = (dataType == CL_UNORM_INT8) ||
|
|
|
|
(dataType == CL_UNORM_INT16) ||
|
|
|
|
(dataType == CL_SNORM_INT8) ||
|
|
|
|
(dataType == CL_SNORM_INT16) ||
|
|
|
|
(dataType == CL_HALF_FLOAT) ||
|
|
|
|
(dataType == CL_FLOAT) ||
|
|
|
|
(dataType == CL_SIGNED_INT8) ||
|
|
|
|
(dataType == CL_SIGNED_INT16) ||
|
|
|
|
(dataType == CL_SIGNED_INT32) ||
|
|
|
|
(dataType == CL_UNSIGNED_INT8) ||
|
|
|
|
(dataType == CL_UNSIGNED_INT16) ||
|
|
|
|
(dataType == CL_UNSIGNED_INT32);
|
|
|
|
|
|
|
|
return isValidOrder && isValidDataType;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::isValidIntensityFormat(const cl_image_format *imageFormat) {
|
|
|
|
if (imageFormat->image_channel_order != CL_INTENSITY) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
auto dataType = imageFormat->image_channel_data_type;
|
|
|
|
return (dataType == CL_UNORM_INT8) ||
|
|
|
|
(dataType == CL_UNORM_INT16) ||
|
|
|
|
(dataType == CL_SNORM_INT8) ||
|
|
|
|
(dataType == CL_SNORM_INT16) ||
|
|
|
|
(dataType == CL_HALF_FLOAT) ||
|
|
|
|
(dataType == CL_FLOAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::isValidLuminanceFormat(const cl_image_format *imageFormat) {
|
|
|
|
if (imageFormat->image_channel_order != CL_LUMINANCE) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
auto dataType = imageFormat->image_channel_data_type;
|
|
|
|
return (dataType == CL_UNORM_INT8) ||
|
|
|
|
(dataType == CL_UNORM_INT16) ||
|
|
|
|
(dataType == CL_SNORM_INT8) ||
|
|
|
|
(dataType == CL_SNORM_INT16) ||
|
|
|
|
(dataType == CL_HALF_FLOAT) ||
|
|
|
|
(dataType == CL_FLOAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::isValidDepthFormat(const cl_image_format *imageFormat) {
|
|
|
|
if (imageFormat->image_channel_order != CL_DEPTH) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
auto dataType = imageFormat->image_channel_data_type;
|
|
|
|
return (dataType == CL_UNORM_INT16) ||
|
|
|
|
(dataType == CL_FLOAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::isValidDoubleChannelFormat(const cl_image_format *imageFormat) {
|
|
|
|
auto channelOrder = imageFormat->image_channel_order;
|
|
|
|
auto dataType = imageFormat->image_channel_data_type;
|
|
|
|
|
|
|
|
bool isValidOrder = (channelOrder == CL_RG) ||
|
|
|
|
(channelOrder == CL_RGx) ||
|
|
|
|
(channelOrder == CL_RA);
|
|
|
|
|
|
|
|
bool isValidDataType = (dataType == CL_UNORM_INT8) ||
|
|
|
|
(dataType == CL_UNORM_INT16) ||
|
|
|
|
(dataType == CL_SNORM_INT8) ||
|
|
|
|
(dataType == CL_SNORM_INT16) ||
|
|
|
|
(dataType == CL_HALF_FLOAT) ||
|
|
|
|
(dataType == CL_FLOAT) ||
|
|
|
|
(dataType == CL_SIGNED_INT8) ||
|
|
|
|
(dataType == CL_SIGNED_INT16) ||
|
|
|
|
(dataType == CL_SIGNED_INT32) ||
|
|
|
|
(dataType == CL_UNSIGNED_INT8) ||
|
|
|
|
(dataType == CL_UNSIGNED_INT16) ||
|
|
|
|
(dataType == CL_UNSIGNED_INT32);
|
|
|
|
|
|
|
|
return isValidOrder && isValidDataType;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::isValidTripleChannelFormat(const cl_image_format *imageFormat) {
|
|
|
|
auto channelOrder = imageFormat->image_channel_order;
|
|
|
|
auto dataType = imageFormat->image_channel_data_type;
|
|
|
|
|
|
|
|
bool isValidOrder = (channelOrder == CL_RGB) ||
|
|
|
|
(channelOrder == CL_RGBx);
|
|
|
|
|
|
|
|
bool isValidDataType = (dataType == CL_UNORM_SHORT_565) ||
|
|
|
|
(dataType == CL_UNORM_SHORT_555) ||
|
|
|
|
(dataType == CL_UNORM_INT_101010);
|
|
|
|
|
|
|
|
return isValidOrder && isValidDataType;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::isValidRGBAFormat(const cl_image_format *imageFormat) {
|
|
|
|
if (imageFormat->image_channel_order != CL_RGBA) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
auto dataType = imageFormat->image_channel_data_type;
|
|
|
|
return (dataType == CL_UNORM_INT8) ||
|
|
|
|
(dataType == CL_UNORM_INT16) ||
|
|
|
|
(dataType == CL_SNORM_INT8) ||
|
|
|
|
(dataType == CL_SNORM_INT16) ||
|
|
|
|
(dataType == CL_HALF_FLOAT) ||
|
|
|
|
(dataType == CL_FLOAT) ||
|
|
|
|
(dataType == CL_SIGNED_INT8) ||
|
|
|
|
(dataType == CL_SIGNED_INT16) ||
|
|
|
|
(dataType == CL_SIGNED_INT32) ||
|
|
|
|
(dataType == CL_UNSIGNED_INT8) ||
|
|
|
|
(dataType == CL_UNSIGNED_INT16) ||
|
|
|
|
(dataType == CL_UNSIGNED_INT32);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::isValidSRGBFormat(const cl_image_format *imageFormat) {
|
|
|
|
auto channelOrder = imageFormat->image_channel_order;
|
|
|
|
auto dataType = imageFormat->image_channel_data_type;
|
|
|
|
|
|
|
|
bool isValidOrder = (channelOrder == CL_sRGB) ||
|
|
|
|
(channelOrder == CL_sRGBx) ||
|
|
|
|
(channelOrder == CL_sRGBA) ||
|
|
|
|
(channelOrder == CL_sBGRA);
|
|
|
|
|
|
|
|
bool isValidDataType = (dataType == CL_UNORM_INT8);
|
|
|
|
|
|
|
|
return isValidOrder && isValidDataType;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::isValidARGBFormat(const cl_image_format *imageFormat) {
|
|
|
|
auto channelOrder = imageFormat->image_channel_order;
|
|
|
|
auto dataType = imageFormat->image_channel_data_type;
|
|
|
|
|
|
|
|
bool isValidOrder = (channelOrder == CL_ARGB) ||
|
|
|
|
(channelOrder == CL_BGRA) ||
|
|
|
|
(channelOrder == CL_ABGR);
|
|
|
|
|
|
|
|
bool isValidDataType = (dataType == CL_UNORM_INT8) ||
|
|
|
|
(dataType == CL_SNORM_INT8) ||
|
|
|
|
(dataType == CL_SIGNED_INT8) ||
|
|
|
|
(dataType == CL_UNSIGNED_INT8);
|
|
|
|
|
|
|
|
return isValidOrder && isValidDataType;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::isValidDepthStencilFormat(const cl_image_format *imageFormat) {
|
|
|
|
if (imageFormat->image_channel_order != CL_DEPTH_STENCIL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
auto dataType = imageFormat->image_channel_data_type;
|
|
|
|
return (dataType == CL_UNORM_INT24) ||
|
|
|
|
(dataType == CL_FLOAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::isValidYUVFormat(const cl_image_format *imageFormat) {
|
|
|
|
auto dataType = imageFormat->image_channel_data_type;
|
|
|
|
|
2021-06-28 13:06:24 +08:00
|
|
|
bool isValidOrder = isNV12Image(imageFormat) || isPackedYuvImage(imageFormat);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
bool isValidDataType = (dataType == CL_UNORM_INT8);
|
|
|
|
|
|
|
|
return isValidOrder && isValidDataType;
|
|
|
|
}
|
2018-01-23 20:40:37 +08:00
|
|
|
|
|
|
|
bool Image::hasAlphaChannel(const cl_image_format *imageFormat) {
|
|
|
|
auto channelOrder = imageFormat->image_channel_order;
|
|
|
|
return (channelOrder == CL_A) ||
|
|
|
|
(channelOrder == CL_Rx) ||
|
|
|
|
(channelOrder == CL_RA) ||
|
|
|
|
(channelOrder == CL_RGx) ||
|
|
|
|
(channelOrder == CL_RGBx) ||
|
|
|
|
(channelOrder == CL_RGBA) ||
|
|
|
|
(channelOrder == CL_BGRA) ||
|
|
|
|
(channelOrder == CL_ARGB) ||
|
|
|
|
(channelOrder == CL_INTENSITY) ||
|
|
|
|
(channelOrder == CL_sRGBA) ||
|
|
|
|
(channelOrder == CL_sBGRA) ||
|
|
|
|
(channelOrder == CL_sRGBx) ||
|
|
|
|
(channelOrder == CL_ABGR);
|
|
|
|
}
|
2018-02-13 20:20:34 +08:00
|
|
|
|
2018-02-18 05:26:28 +08:00
|
|
|
size_t Image::calculateOffsetForMapping(const MemObjOffsetArray &origin) const {
|
2018-02-21 22:25:46 +08:00
|
|
|
size_t rowPitch = mappingOnCpuAllowed() ? imageDesc.image_row_pitch : getHostPtrRowPitch();
|
|
|
|
size_t slicePitch = mappingOnCpuAllowed() ? imageDesc.image_slice_pitch : getHostPtrSlicePitch();
|
|
|
|
|
2020-01-09 00:29:15 +08:00
|
|
|
size_t offset = getSurfaceFormatInfo().surfaceFormat.ImageElementSizeInBytes * origin[0];
|
2018-04-04 15:29:48 +08:00
|
|
|
|
|
|
|
switch (imageDesc.image_type) {
|
|
|
|
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
2018-09-04 21:25:29 +08:00
|
|
|
offset += slicePitch * origin[1];
|
2018-04-04 15:29:48 +08:00
|
|
|
break;
|
|
|
|
case CL_MEM_OBJECT_IMAGE2D:
|
|
|
|
offset += rowPitch * origin[1];
|
|
|
|
break;
|
|
|
|
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
|
|
|
case CL_MEM_OBJECT_IMAGE3D:
|
2018-09-04 21:25:29 +08:00
|
|
|
offset += rowPitch * origin[1] + slicePitch * origin[2];
|
2018-04-04 15:29:48 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2018-03-07 21:37:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return offset;
|
2018-02-13 20:20:34 +08:00
|
|
|
}
|
2018-03-08 18:11:27 +08:00
|
|
|
|
2018-08-12 17:20:53 +08:00
|
|
|
cl_int Image::validateRegionAndOrigin(const size_t *origin, const size_t *region, const cl_image_desc &imgDesc) {
|
2018-03-08 18:11:27 +08:00
|
|
|
if (region[0] == 0 || region[1] == 0 || region[2] == 0) {
|
2018-08-12 17:20:53 +08:00
|
|
|
return CL_INVALID_VALUE;
|
2018-03-08 18:11:27 +08:00
|
|
|
}
|
|
|
|
|
2018-08-13 18:13:01 +08:00
|
|
|
bool notMipMapped = (false == isMipMapped(imgDesc));
|
2018-04-04 15:29:48 +08:00
|
|
|
|
|
|
|
if ((imgDesc.image_type == CL_MEM_OBJECT_IMAGE1D || imgDesc.image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER) &&
|
2018-08-13 18:13:01 +08:00
|
|
|
(((origin[1] > 0) && notMipMapped) || origin[2] > 0 || region[1] > 1 || region[2] > 1)) {
|
2018-08-12 17:20:53 +08:00
|
|
|
return CL_INVALID_VALUE;
|
2018-03-08 18:11:27 +08:00
|
|
|
}
|
|
|
|
|
2018-04-04 15:29:48 +08:00
|
|
|
if ((imgDesc.image_type == CL_MEM_OBJECT_IMAGE2D || imgDesc.image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY) &&
|
2018-08-13 18:13:01 +08:00
|
|
|
(((origin[2] > 0) && notMipMapped) || region[2] > 1)) {
|
2018-08-12 17:20:53 +08:00
|
|
|
return CL_INVALID_VALUE;
|
2018-03-08 18:11:27 +08:00
|
|
|
}
|
|
|
|
|
2018-08-13 18:13:01 +08:00
|
|
|
if (notMipMapped) {
|
2018-08-12 17:20:53 +08:00
|
|
|
return CL_SUCCESS;
|
2018-04-04 15:29:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t mipLevel = findMipLevel(imgDesc.image_type, origin);
|
2018-08-12 17:20:53 +08:00
|
|
|
if (mipLevel < imgDesc.num_mip_levels) {
|
|
|
|
return CL_SUCCESS;
|
|
|
|
} else {
|
|
|
|
return CL_INVALID_MIP_LEVEL;
|
|
|
|
}
|
2018-03-08 18:11:27 +08:00
|
|
|
}
|
2018-04-05 21:05:33 +08:00
|
|
|
|
|
|
|
bool Image::hasSameDescriptor(const cl_image_desc &imageDesc) const {
|
|
|
|
return this->imageDesc.image_type == imageDesc.image_type &&
|
|
|
|
this->imageDesc.image_width == imageDesc.image_width &&
|
|
|
|
this->imageDesc.image_height == imageDesc.image_height &&
|
|
|
|
this->imageDesc.image_depth == imageDesc.image_depth &&
|
|
|
|
this->imageDesc.image_array_size == imageDesc.image_array_size &&
|
|
|
|
this->hostPtrRowPitch == imageDesc.image_row_pitch &&
|
|
|
|
this->hostPtrSlicePitch == imageDesc.image_slice_pitch &&
|
|
|
|
this->imageDesc.num_mip_levels == imageDesc.num_mip_levels &&
|
|
|
|
this->imageDesc.num_samples == imageDesc.num_samples;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::hasValidParentImageFormat(const cl_image_format &imageFormat) const {
|
|
|
|
if (this->imageFormat.image_channel_data_type != imageFormat.image_channel_data_type) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
switch (this->imageFormat.image_channel_order) {
|
|
|
|
case CL_BGRA:
|
|
|
|
return imageFormat.image_channel_order == CL_sBGRA;
|
|
|
|
case CL_sBGRA:
|
|
|
|
return imageFormat.image_channel_order == CL_BGRA;
|
|
|
|
case CL_RGBA:
|
|
|
|
return imageFormat.image_channel_order == CL_sRGBA;
|
|
|
|
case CL_sRGBA:
|
|
|
|
return imageFormat.image_channel_order == CL_RGBA;
|
|
|
|
case CL_RGB:
|
|
|
|
return imageFormat.image_channel_order == CL_sRGB;
|
|
|
|
case CL_sRGB:
|
|
|
|
return imageFormat.image_channel_order == CL_RGB;
|
|
|
|
case CL_RGBx:
|
|
|
|
return imageFormat.image_channel_order == CL_sRGBx;
|
|
|
|
case CL_sRGBx:
|
|
|
|
return imageFormat.image_channel_order == CL_RGBx;
|
|
|
|
case CL_R:
|
|
|
|
return imageFormat.image_channel_order == CL_DEPTH;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2020-05-25 16:21:04 +08:00
|
|
|
|
|
|
|
cl_int Image::checkIfDeviceSupportsImages(cl_context context) {
|
|
|
|
auto pContext = castToObject<Context>(context);
|
|
|
|
if (pContext != nullptr) {
|
|
|
|
auto capabilityTable = pContext->getDevice(0)->getHardwareInfo().capabilityTable;
|
|
|
|
if (!capabilityTable.supportsImages) {
|
|
|
|
return CL_INVALID_OPERATION;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CL_INVALID_CONTEXT;
|
|
|
|
}
|
2021-07-02 00:00:22 +08:00
|
|
|
void Image::fillImageRegion(size_t *region) const {
|
|
|
|
region[0] = imageDesc.image_width;
|
|
|
|
if (imageDesc.image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY) {
|
|
|
|
region[1] = imageDesc.image_array_size;
|
|
|
|
} else if (Image::isImage1d(imageDesc)) {
|
|
|
|
region[1] = 1u;
|
|
|
|
} else {
|
|
|
|
region[1] = imageDesc.image_height;
|
|
|
|
}
|
2020-05-25 16:21:04 +08:00
|
|
|
|
2021-07-02 00:00:22 +08:00
|
|
|
if (imageDesc.image_type == CL_MEM_OBJECT_IMAGE2D_ARRAY) {
|
|
|
|
region[2] = imageDesc.image_array_size;
|
|
|
|
} else if (imageDesc.image_type == CL_MEM_OBJECT_IMAGE3D) {
|
|
|
|
region[2] = imageDesc.image_depth;
|
|
|
|
} else {
|
|
|
|
region[2] = 1u;
|
|
|
|
}
|
|
|
|
}
|
2019-03-26 18:59:46 +08:00
|
|
|
} // namespace NEO
|