mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-15 13:01:45 +08:00
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:

committed by
Wojciech Woloszyn

parent
214b407353
commit
0ad81024b7
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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>(
|
||||
|
@ -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>(
|
||||
|
@ -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
50
runtime/helpers/mipmap.h
Normal 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
|
@ -225,6 +225,7 @@ struct ImageInfo {
|
||||
uint32_t yOffsetForUVPlane;
|
||||
GMM_YUV_PLANE_ENUM plane;
|
||||
int mipLevel;
|
||||
uint32_t mipCount;
|
||||
bool preferRenderCompression;
|
||||
};
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user