Implement cl_khr_mipmap_image [1/n]

- Add mipmap image handling for clEnqueueReadImage, clEnqueueWriteImage
- Fix mipmap image handling for clCreateImage

Change-Id: I42938a330b55c7e69a16c26dce3ab5d66f8a8938
This commit is contained in:
Woloszyn, Wojciech
2018-03-12 16:32:08 +01:00
committed by Wojciech Woloszyn
parent 214b407353
commit 0ad81024b7
24 changed files with 356 additions and 45 deletions

View File

@ -539,7 +539,7 @@ class BuiltInOp<HWFamily, EBuiltInOps::CopyBufferToImage3d> : public BuiltinDisp
}
// Set-up destination image
kernelNoSplit3DBuilder.setArg(1, dstImageRedescribed);
kernelNoSplit3DBuilder.setArg(1, dstImageRedescribed, operationParams.dstMipLevel);
// Set-up srcOffset
kernelNoSplit3DBuilder.setArg(2, static_cast<uint32_t>(operationParams.srcOffset.x));
@ -618,7 +618,7 @@ class BuiltInOp<HWFamily, EBuiltInOps::CopyImage3dToBuffer> : public BuiltinDisp
kernelNoSplit3DBuilder.setKernel(kernelBytes[bytesExponent]);
// Set-up source image
kernelNoSplit3DBuilder.setArg(0, srcImageRedescribed);
kernelNoSplit3DBuilder.setArg(0, srcImageRedescribed, operationParams.srcMipLevel);
// Set-up destination host ptr / buffer
if (operationParams.dstPtr) {

View File

@ -249,6 +249,8 @@ class BuiltinDispatchInfoBuilder {
size_t dstRowPitch = 0;
size_t srcSlicePitch = 0;
size_t dstSlicePitch = 0;
uint32_t srcMipLevel = 0;
uint32_t dstMipLevel = 0;
};
BuiltinDispatchInfoBuilder(BuiltIns &kernelLib) : kernelsLib(kernelLib) {}
@ -259,6 +261,7 @@ class BuiltinDispatchInfoBuilder {
virtual bool buildDispatchInfos(MultiDispatchInfo &multiDispatchInfo, const BuiltinOpParams &operationParams) const {
return false;
}
virtual bool buildDispatchInfos(MultiDispatchInfo &multiDispatchInfo, Kernel *kernel,
const uint32_t dim, const Vec3<size_t> &gws, const Vec3<size_t> &elws, const Vec3<size_t> &offset) const {
return false;

View File

@ -29,6 +29,7 @@
#include "runtime/helpers/cache_policy.h"
#include "runtime/helpers/kernel_commands.h"
#include "runtime/helpers/basic_math.h"
#include "runtime/helpers/mipmap.h"
#include "runtime/mem_obj/image.h"
#include "runtime/memory_manager/surface.h"
#include <algorithm>
@ -108,6 +109,9 @@ cl_int CommandQueueHw<GfxFamily>::enqueueReadImage(
dc.size = region;
dc.srcRowPitch = inputRowPitch;
dc.srcSlicePitch = inputSlicePitch;
if (srcImage->getImageDesc().num_mip_levels > 0) {
dc.srcMipLevel = findMipLevel(srcImage->getImageDesc().image_type, origin);
}
builder.buildDispatchInfos(di, dc);
enqueueHandler<CL_COMMAND_READ_IMAGE>(

View File

@ -28,6 +28,7 @@
#include "runtime/helpers/surface_formats.h"
#include "runtime/helpers/kernel_commands.h"
#include "runtime/helpers/basic_math.h"
#include "runtime/helpers/mipmap.h"
#include "runtime/mem_obj/image.h"
#include <algorithm>
#include <new>
@ -105,6 +106,10 @@ cl_int CommandQueueHw<GfxFamily>::enqueueWriteImage(
dc.size = region;
dc.dstRowPitch = inputRowPitch;
dc.dstSlicePitch = inputSlicePitch;
if (dstImage->getImageDesc().num_mip_levels > 0) {
dc.dstMipLevel = findMipLevel(dstImage->getImageDesc().image_type, origin);
}
builder.buildDispatchInfos(di, dc);
enqueueHandler<CL_COMMAND_WRITE_IMAGE>(

View File

@ -53,6 +53,7 @@ set(RUNTIME_SRCS_HELPERS_BASE
${CMAKE_CURRENT_SOURCE_DIR}/hw_info.h
${CMAKE_CURRENT_SOURCE_DIR}/kernel_commands.h
${CMAKE_CURRENT_SOURCE_DIR}/kernel_commands.inl
${CMAKE_CURRENT_SOURCE_DIR}/mipmap.h
${CMAKE_CURRENT_SOURCE_DIR}/options.cpp
${CMAKE_CURRENT_SOURCE_DIR}/options.h
${CMAKE_CURRENT_SOURCE_DIR}/per_thread_data.cpp

50
runtime/helpers/mipmap.h Normal file
View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <cstdint>
#include "CL/cl.h"
namespace OCLRT {
inline uint32_t findMipLevel(cl_mem_object_type imageType, const size_t *origin) {
size_t mipLevel = 0;
switch (imageType) {
case CL_MEM_OBJECT_IMAGE1D:
mipLevel = origin[1];
break;
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
case CL_MEM_OBJECT_IMAGE2D:
mipLevel = origin[2];
break;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
case CL_MEM_OBJECT_IMAGE3D:
mipLevel = origin[3];
break;
default:
mipLevel = 0;
}
return static_cast<uint32_t>(mipLevel);
}
} // namespace OCLRT

View File

@ -225,6 +225,7 @@ struct ImageInfo {
uint32_t yOffsetForUVPlane;
GMM_YUV_PLANE_ENUM plane;
int mipLevel;
uint32_t mipCount;
bool preferRenderCompression;
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Intel Corporation
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -785,6 +785,10 @@ cl_int Kernel::setArg(uint32_t argIndex, cl_mem argVal) {
return setArg(argIndex, sizeof(argVal), &argVal);
}
cl_int Kernel::setArg(uint32_t argIndex, cl_mem argVal, uint32_t mipLevel) {
return setArgImageWithMipLevel(argIndex, sizeof(argVal), &argVal, mipLevel);
}
void *Kernel::patchBufferOffset(const KernelArgInfo &argInfo, void *svmPtr, GraphicsAllocation *svmAlloc) {
if (isInvalidOffset(argInfo.offsetBufferOffset)) {
return svmPtr;
@ -1164,6 +1168,12 @@ cl_int Kernel::setArgPipe(uint32_t argIndex,
cl_int Kernel::setArgImage(uint32_t argIndex,
size_t argSize,
const void *argVal) {
return setArgImageWithMipLevel(argIndex, argSize, argVal, 0u);
}
cl_int Kernel::setArgImageWithMipLevel(uint32_t argIndex,
size_t argSize,
const void *argVal, uint32_t mipLevel) {
auto retVal = CL_INVALID_ARG_VALUE;
patchBufferOffset(kernelInfo.kernelArgInfo[argIndex], nullptr, nullptr);
@ -1187,10 +1197,8 @@ cl_int Kernel::setArgImage(uint32_t argIndex,
if (kernelArgInfo.isMediaImage) {
DEBUG_BREAK_IF(!kernelInfo.isVmeWorkload);
pImage->setMediaImageArg(const_cast<void *>(surfaceState));
} else if (kernelArgInfo.isMediaBlockImage) {
pImage->setImageArg(const_cast<void *>(surfaceState), true);
} else {
pImage->setImageArg(const_cast<void *>(surfaceState), false);
pImage->setImageArg(const_cast<void *>(surfaceState), kernelArgInfo.isMediaBlockImage, mipLevel);
}
auto crossThreadData = reinterpret_cast<uint32_t *>(getCrossThreadData());

View File

@ -229,6 +229,7 @@ class Kernel : public BaseObject<_cl_kernel> {
// Helpers
cl_int setArg(uint32_t argIndex, uint32_t argValue);
cl_int setArg(uint32_t argIndex, cl_mem argValue);
cl_int setArg(uint32_t argIndex, cl_mem argValue, uint32_t mipLevel);
// Handlers
void setKernelArgHandler(uint32_t argIndex, KernelArgHandler handler);
@ -251,6 +252,10 @@ class Kernel : public BaseObject<_cl_kernel> {
size_t argSize,
const void *argVal);
cl_int setArgImageWithMipLevel(uint32_t argIndex,
size_t argSize,
const void *argVal, uint32_t mipLevel);
cl_int setArgLocal(uint32_t argIndex,
size_t argSize,
const void *argVal);

View File

@ -144,7 +144,7 @@ Image *Image::create(Context *context,
imgInfo.imgDesc = &imageDescriptor;
imgInfo.surfaceFormat = surfaceFormat;
imgInfo.mipLevel = imageDesc->num_mip_levels;
imgInfo.mipCount = imageDesc->num_mip_levels;
Gmm *gmm = nullptr;
if (imageDesc->image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY || imageDesc->image_type == CL_MEM_OBJECT_IMAGE2D_ARRAY) {
@ -325,7 +325,7 @@ Image *Image::create(Context *context,
image->setImageSlicePitch(imgInfo.slicePitch);
image->setQPitch(imgInfo.qPitch);
image->setSurfaceOffsets(imgInfo.offset, imgInfo.xOffset, imgInfo.yOffset, imgInfo.yOffsetForUVPlane);
image->setMipLevel(imgInfo.mipLevel);
image->setMipCount(imgInfo.mipCount);
if (parentImage) {
image->setMediaPlaneType(static_cast<cl_uint>(imageDesc->image_depth));
image->setParentSharingHandler(parentImage->getSharingHandler());

View File

@ -124,7 +124,7 @@ class Image : public MemObj {
void *paramValue,
size_t *paramValueSizeRet);
virtual void setImageArg(void *memory, bool isMediaBlockImage) = 0;
virtual void setImageArg(void *memory, bool isMediaBlockImage, uint32_t mipLevel) = 0;
virtual void setMediaImageArg(void *memory) = 0;
virtual void setMediaSurfaceRotation(void *memory) = 0;
virtual void setSurfaceMemoryObjectControlStateIndexToMocsTable(void *memory, uint32_t value) = 0;
@ -166,6 +166,9 @@ class Image : public MemObj {
int peekMipLevel() { return mipLevel; }
void setMipLevel(int mipLevelNew) { this->mipLevel = mipLevelNew; }
uint32_t peekMipCount() { return mipCount; }
void setMipCount(uint32_t mipCountNew) { this->mipCount = mipCountNew; }
static const SurfaceFormatInfo *getSurfaceFormatFromTable(cl_mem_flags flags, const cl_image_format *imageFormat);
static bool validateRegionAndOrigin(const size_t *origin, const size_t *region, const cl_mem_object_type &imgType);
@ -209,6 +212,7 @@ class Image : public MemObj {
cl_uint mediaPlaneType;
SurfaceOffsets surfaceOffsets;
int mipLevel = 0;
uint32_t mipCount = 0;
static bool isValidSingleChannelFormat(const cl_image_format *imageFormat);
static bool isValidIntensityFormat(const cl_image_format *imageFormat);
@ -254,7 +258,7 @@ class ImageHw : public Image {
}
}
void setImageArg(void *memory, bool setAsMediaBlockImage) override;
void setImageArg(void *memory, bool setAsMediaBlockImage, uint32_t mipLevel) override;
void setAuxParamsForMultisamples(RENDER_SURFACE_STATE *surfaceState);
void setAuxParamsForCCS(RENDER_SURFACE_STATE *surfaceState, Gmm *gmm);
void setMediaImageArg(void *memory) override;

View File

@ -39,7 +39,7 @@ union SURFACE_STATE_BUFFER_LENGTH {
};
template <typename GfxFamily>
void ImageHw<GfxFamily>::setImageArg(void *memory, bool setAsMediaBlockImage) {
void ImageHw<GfxFamily>::setImageArg(void *memory, bool setAsMediaBlockImage, uint32_t mipLevel) {
using SURFACE_FORMAT = typename RENDER_SURFACE_STATE::SURFACE_FORMAT;
auto surfaceState = reinterpret_cast<RENDER_SURFACE_STATE *>(memory);
auto gmm = getGraphicsAllocation()->gmm;
@ -109,7 +109,8 @@ void ImageHw<GfxFamily>::setImageArg(void *memory, bool setAsMediaBlockImage) {
surfaceState->setSurfaceBaseAddress(getGraphicsAllocation()->getGpuAddress() + this->surfaceOffsets.offset);
surfaceState->setRenderTargetViewExtent(renderTargetViewExtent);
surfaceState->setMinimumArrayElement(minimumArrayElement);
surfaceState->setSurfaceMinLod(this->mipLevel);
surfaceState->setSurfaceMinLod(this->mipLevel + mipLevel);
surfaceState->setMipCountLod(this->mipCount - 1);
// SurfaceQpitch is in rows but must be a multiple of VALIGN
surfaceState->setSurfaceQpitch(qPitch);

View File

@ -66,7 +66,7 @@ void APIENTRY WddmMemoryManager::trimCallback(_Inout_ D3DKMT_TRIMNOTIFICATION *t
}
GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemoryForImage(ImageInfo &imgInfo, Gmm *gmm) {
if (!Gmm::allowTiling(*imgInfo.imgDesc) && imgInfo.mipLevel == 0) {
if (!Gmm::allowTiling(*imgInfo.imgDesc) && imgInfo.mipCount == 0) {
delete gmm;
return allocateGraphicsMemory(imgInfo.size, MemoryConstants::preferredAlignment);
}