Add support for copy images by blitter OCL

Signed-off-by: Kamil Kopryk <kamil.kopryk@intel.com>
Related-To: NEO-4692
This commit is contained in:
Kamil Kopryk
2021-07-26 00:49:41 +00:00
committed by Compute-Runtime-Automation
parent 6f25994c5e
commit af4b1afdbd
9 changed files with 137 additions and 48 deletions

View File

@@ -733,6 +733,7 @@ bool CommandQueue::blitEnqueueAllowed(cl_command_type cmdType) const {
case CL_COMMAND_SVM_MEMCPY:
case CL_COMMAND_READ_IMAGE:
case CL_COMMAND_WRITE_IMAGE:
case CL_COMMAND_COPY_IMAGE:
return blitterSupported && blitEnqueueAllowed;
default:
return false;

View File

@@ -31,9 +31,6 @@ cl_int CommandQueueHw<GfxFamily>::enqueueCopyImage(
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event) {
auto &builder = BuiltInDispatchBuilderOp::getBuiltinDispatchInfoBuilder(EBuiltInOps::CopyImageToImage3d,
this->getClDevice());
BuiltInOwnershipWrapper builtInLock(builder, this->context);
MemObjSurface srcImgSurf(srcImage);
MemObjSurface dstImgSurf(dstImage);
@@ -52,17 +49,11 @@ cl_int CommandQueueHw<GfxFamily>::enqueueCopyImage(
dc.dstMipLevel = findMipLevel(dstImage->getImageDesc().image_type, dstOrigin);
}
MultiDispatchInfo di(dc);
MultiDispatchInfo dispatchInfo(dc);
cl_command_type cmdType = CL_COMMAND_COPY_IMAGE;
auto blitAllowed = blitEnqueueAllowed(cmdType) && blitEnqueueImageAllowed(srcOrigin, region, *srcImage) && blitEnqueueImageAllowed(dstOrigin, region, *dstImage);
builder.buildDispatchInfos(di);
enqueueHandler<CL_COMMAND_COPY_IMAGE>(
surfaces,
false,
di,
numEventsInWaitList,
eventWaitList,
event);
dispatchBcsOrGpgpuEnqueue<CL_COMMAND_COPY_IMAGE>(dispatchInfo, surfaces, EBuiltInOps::CopyImageToImage3d, numEventsInWaitList, eventWaitList, event, false, blitAllowed);
return CL_SUCCESS;
}

View File

@@ -22,8 +22,10 @@ struct ClBlitProperties {
auto rootDeviceIndex = commandStreamReceiver.getRootDeviceIndex();
auto clearColorAllocation = commandStreamReceiver.getClearColorAllocation();
BlitProperties blitProperties{};
if (BlitterConstants::BlitDirection::BufferToBuffer == blitDirection) {
if (BlitterConstants::BlitDirection::BufferToBuffer == blitDirection ||
BlitterConstants::BlitDirection::ImageToImage == blitDirection) {
auto dstOffset = builtinOpParams.dstOffset.x;
auto srcOffset = builtinOpParams.srcOffset.x;
GraphicsAllocation *dstAllocation = nullptr;
@@ -41,16 +43,21 @@ struct ClBlitProperties {
srcOffset += ptrDiff(builtinOpParams.srcPtr, srcAllocation->getGpuAddress());
}
return BlitProperties::constructPropertiesForCopyBuffer(dstAllocation,
srcAllocation,
{dstOffset, builtinOpParams.dstOffset.y, builtinOpParams.dstOffset.z},
{srcOffset, builtinOpParams.srcOffset.y, builtinOpParams.srcOffset.z},
builtinOpParams.size,
builtinOpParams.srcRowPitch, builtinOpParams.srcSlicePitch,
builtinOpParams.dstRowPitch, builtinOpParams.dstSlicePitch, clearColorAllocation);
blitProperties = BlitProperties::constructPropertiesForCopyBuffer(dstAllocation,
srcAllocation,
{dstOffset, builtinOpParams.dstOffset.y, builtinOpParams.dstOffset.z},
{srcOffset, builtinOpParams.srcOffset.y, builtinOpParams.srcOffset.z},
builtinOpParams.size,
builtinOpParams.srcRowPitch, builtinOpParams.srcSlicePitch,
builtinOpParams.dstRowPitch, builtinOpParams.dstSlicePitch, clearColorAllocation);
if (BlitterConstants::BlitDirection::ImageToImage == blitDirection) {
blitProperties.blitDirection = blitDirection;
setBlitPropertiesForImage(blitProperties, builtinOpParams);
}
return blitProperties;
}
BlitProperties blitProperties{};
GraphicsAllocation *gpuAllocation = nullptr;
Vec3<size_t> copyOffset = 0;
@@ -154,6 +161,8 @@ struct ClBlitProperties {
return BlitterConstants::BlitDirection::HostPtrToImage;
case CL_COMMAND_READ_IMAGE:
return BlitterConstants::BlitDirection::ImageToHostPtr;
case CL_COMMAND_COPY_IMAGE:
return BlitterConstants::BlitDirection::ImageToImage;
default:
UNRECOVERABLE_IF(true);
}
@@ -187,10 +196,14 @@ struct ClBlitProperties {
size_t srcSlicePitch = builtinOpParams.srcSlicePitch;
size_t dstSlicePitch = builtinOpParams.dstSlicePitch;
if (blitProperties.blitDirection == BlitterConstants::BlitDirection::ImageToHostPtr) {
if (blitProperties.blitDirection == BlitterConstants::BlitDirection::ImageToHostPtr ||
blitProperties.blitDirection == BlitterConstants::BlitDirection::ImageToImage) {
adjustBlitPropertiesForImage(builtinOpParams.srcMemObj, blitProperties.srcSize, blitProperties.bytesPerPixel,
blitProperties.srcGpuAddress, srcRowPitch, srcSlicePitch);
} else {
}
if (blitProperties.blitDirection == BlitterConstants::BlitDirection::HostPtrToImage ||
blitProperties.blitDirection == BlitterConstants::BlitDirection::ImageToImage) {
adjustBlitPropertiesForImage(builtinOpParams.dstMemObj, blitProperties.dstSize, blitProperties.bytesPerPixel,
blitProperties.dstGpuAddress, dstRowPitch, dstSlicePitch);
}

View File

@@ -1187,7 +1187,8 @@ TEST(CommandQueue, givenClCommandWhenCallingBlitEnqueueAllowedThenReturnCorrectV
EXPECT_EQ(supported, queue.blitEnqueueAllowed(CL_COMMAND_SVM_MEMCPY));
EXPECT_EQ(supported, queue.blitEnqueueAllowed(CL_COMMAND_READ_IMAGE));
EXPECT_EQ(supported, queue.blitEnqueueAllowed(CL_COMMAND_WRITE_IMAGE));
EXPECT_FALSE(queue.blitEnqueueAllowed(CL_COMMAND_COPY_IMAGE));
EXPECT_EQ(supported, queue.blitEnqueueAllowed(CL_COMMAND_COPY_IMAGE));
EXPECT_FALSE(queue.blitEnqueueAllowed(CL_COMMAND_COPY_IMAGE_TO_BUFFER));
}
TEST(CommandQueue, givenRegularClCommandWhenCallingBlitEnqueuePreferredThenReturnCorrectValue) {

View File

@@ -5,6 +5,7 @@
*
*/
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/unit_test_helper.h"
#include "opencl/source/built_ins/builtins_dispatch_builder.h"
@@ -208,6 +209,60 @@ HWTEST_F(EnqueueCopyImageTest, WhenCopyingImageThenNumberOfPipelineSelectsIsOne)
EXPECT_EQ(1, numCommands);
}
HWTEST_F(EnqueueCopyImageTest, givenDeviceWithBlitterSupportWhenEnqueueCopyImageThenBlitEnqueueImageAllowedReturnsCorrectResult) {
DebugManagerStateRestore restorer;
DebugManager.flags.OverrideInvalidEngineWithDefault.set(1);
DebugManager.flags.EnableBlitterForEnqueueOperations.set(1);
DebugManager.flags.EnableBlitterForReadWriteImage.set(1);
auto hwInfo = pClDevice->getRootDeviceEnvironment().getMutableHardwareInfo();
auto &hwHelper = HwHelper::get(hwInfo->platform.eRenderCoreFamily);
hwInfo->capabilityTable.blitterOperationsSupported = true;
size_t srcOrigin[] = {0, 0, 0};
size_t dstOrigin[] = {0, 0, 0};
auto mockCmdQ = std::make_unique<MockCommandQueueHw<FamilyType>>(context, pClDevice, nullptr);
std::unique_ptr<Image> srcImage(Image2dHelper<>::create(context));
std::unique_ptr<Image> dstImage(Image2dHelper<>::create(context));
{
size_t region[] = {BlitterConstants::maxBlitWidth + 1, BlitterConstants::maxBlitHeight, 1};
EnqueueCopyImageHelper<>::enqueueCopyImage(mockCmdQ.get(), srcImage.get(), dstImage.get(), srcOrigin, dstOrigin, region);
EnqueueCopyImageHelper<>::enqueueCopyImage(mockCmdQ.get(), srcImage.get(), dstImage.get(), srcOrigin, dstOrigin, region);
EXPECT_FALSE(mockCmdQ->isBlitEnqueueImageAllowed);
}
{
size_t region[] = {BlitterConstants::maxBlitWidth, BlitterConstants::maxBlitHeight, 1};
size_t dstOrigin[] = {10, 10, 10};
EnqueueCopyImageHelper<>::enqueueCopyImage(mockCmdQ.get(), srcImage.get(), dstImage.get(), srcOrigin, dstOrigin, region);
EXPECT_FALSE(mockCmdQ->isBlitEnqueueImageAllowed);
}
{
size_t region[] = {BlitterConstants::maxBlitWidth, BlitterConstants::maxBlitHeight, 1};
EnqueueCopyImageHelper<>::enqueueCopyImage(mockCmdQ.get(), srcImage.get(), dstImage.get(), srcOrigin, dstOrigin, region);
EXPECT_TRUE(mockCmdQ->isBlitEnqueueImageAllowed);
}
{
DebugManager.flags.EnableBlitterForReadWriteImage.set(-1);
size_t region[] = {BlitterConstants::maxBlitWidth, BlitterConstants::maxBlitHeight, 1};
EnqueueCopyImageHelper<>::enqueueCopyImage(mockCmdQ.get(), srcImage.get(), dstImage.get(), srcOrigin, dstOrigin, region);
auto supportExpected = hwHelper.isBlitterForImagesSupported(*hwInfo);
EXPECT_EQ(supportExpected, mockCmdQ->isBlitEnqueueImageAllowed);
}
{
DebugManager.flags.EnableBlitterForReadWriteImage.set(0);
size_t region[] = {BlitterConstants::maxBlitWidth, BlitterConstants::maxBlitHeight, 1};
EnqueueCopyImageHelper<>::enqueueCopyImage(mockCmdQ.get(), srcImage.get(), dstImage.get(), srcOrigin, dstOrigin, region);
EXPECT_FALSE(mockCmdQ->isBlitEnqueueImageAllowed);
}
{
DebugManager.flags.EnableBlitterForEnqueueOperations.set(0);
size_t region[] = {BlitterConstants::maxBlitWidth, BlitterConstants::maxBlitHeight, 1};
EnqueueCopyImageHelper<>::enqueueCopyImage(mockCmdQ.get(), srcImage.get(), dstImage.get(), srcOrigin, dstOrigin, region);
EXPECT_FALSE(mockCmdQ->isBlitEnqueueImageAllowed);
}
}
HWCMDTEST_F(IGFX_GEN8_CORE, EnqueueCopyImageTest, WhenCopyingImageThenMediaVfeStateIsSetCorrectly) {
enqueueCopyImage<FamilyType>();
validateMediaVFEState<FamilyType>(&pDevice->getHardwareInfo(), cmdMediaVfeState, cmdList, itorMediaVfeState);

View File

@@ -962,29 +962,25 @@ HWTEST_F(BcsTests, givenBltSizeWithLeftoverWhenDispatchedThenProgramAllRequiredC
}
HWTEST_F(BcsTests, givenCommandTypeWhenObtainBlitDirectionIsCalledThenReturnCorrectBlitDirection) {
std::array<std::pair<uint32_t, BlitterConstants::BlitDirection>, 9> testParams{
std::make_pair(CL_COMMAND_WRITE_BUFFER, BlitterConstants::BlitDirection::HostPtrToBuffer),
std::make_pair(CL_COMMAND_WRITE_BUFFER_RECT, BlitterConstants::BlitDirection::HostPtrToBuffer),
std::make_pair(CL_COMMAND_READ_BUFFER, BlitterConstants::BlitDirection::BufferToHostPtr),
std::make_pair(CL_COMMAND_READ_BUFFER_RECT, BlitterConstants::BlitDirection::BufferToHostPtr),
std::make_pair(CL_COMMAND_COPY_BUFFER_RECT, BlitterConstants::BlitDirection::BufferToBuffer),
std::make_pair(CL_COMMAND_SVM_MEMCPY, BlitterConstants::BlitDirection::BufferToBuffer),
std::make_pair(CL_COMMAND_WRITE_IMAGE, BlitterConstants::BlitDirection::HostPtrToImage),
std::make_pair(CL_COMMAND_READ_IMAGE, BlitterConstants::BlitDirection::ImageToHostPtr),
std::make_pair(CL_COMMAND_COPY_BUFFER, BlitterConstants::BlitDirection::BufferToBuffer)};
for (const auto &params : testParams) {
uint32_t commandType;
BlitterConstants::BlitDirection expectedBlitDirection;
std::tie(commandType, expectedBlitDirection) = params;
std::array<std::pair<uint32_t, BlitterConstants::BlitDirection>, 10> testParams = {{{CL_COMMAND_WRITE_BUFFER, BlitterConstants::BlitDirection::HostPtrToBuffer},
{CL_COMMAND_WRITE_BUFFER_RECT, BlitterConstants::BlitDirection::HostPtrToBuffer},
{CL_COMMAND_READ_BUFFER, BlitterConstants::BlitDirection::BufferToHostPtr},
{CL_COMMAND_READ_BUFFER_RECT, BlitterConstants::BlitDirection::BufferToHostPtr},
{CL_COMMAND_COPY_BUFFER_RECT, BlitterConstants::BlitDirection::BufferToBuffer},
{CL_COMMAND_SVM_MEMCPY, BlitterConstants::BlitDirection::BufferToBuffer},
{CL_COMMAND_WRITE_IMAGE, BlitterConstants::BlitDirection::HostPtrToImage},
{CL_COMMAND_READ_IMAGE, BlitterConstants::BlitDirection::ImageToHostPtr},
{CL_COMMAND_COPY_BUFFER, BlitterConstants::BlitDirection::BufferToBuffer},
{CL_COMMAND_COPY_IMAGE, BlitterConstants::BlitDirection::ImageToImage}}};
for (const auto &[commandType, expectedBlitDirection] : testParams) {
auto blitDirection = ClBlitProperties::obtainBlitDirection(commandType);
EXPECT_EQ(expectedBlitDirection, blitDirection);
}
}
HWTEST_F(BcsTests, givenWrongCommandTypeWhenObtainBlitDirectionIsCalledThenExpectThrow) {
uint32_t wrongCommandType = CL_COMMAND_COPY_IMAGE;
uint32_t wrongCommandType = CL_COMMAND_NDRANGE_KERNEL;
EXPECT_THROW(ClBlitProperties::obtainBlitDirection(wrongCommandType), std::exception);
}

View File

@@ -1643,6 +1643,37 @@ HWTEST_F(BcsTests, givenImageToHostPtrWhenBlitBufferIsCalledThenBlitCmdIsCorrect
EXPECT_EQ(blitProperties.dstGpuAddress, bltCmd->getDestinationBaseAddress());
}
HWTEST_F(BcsTests, givenImageToImageWhenBlitBufferIsCalledThenBlitCmdIsCorrectlyProgrammed) {
if (!pDevice->getHardwareInfo().capabilityTable.supportsImages) {
GTEST_SKIP();
}
cl_image_desc imgDesc = Image2dDefaults::imageDesc;
imgDesc.image_width = 10u;
imgDesc.image_height = 12u;
std::unique_ptr<Image> srcImage(Image2dHelper<>::create(context.get(), &imgDesc));
std::unique_ptr<Image> dstImage(Image2dHelper<>::create(context.get(), &imgDesc));
BuiltinOpParams builtinOpParams{};
builtinOpParams.srcMemObj = srcImage.get();
builtinOpParams.dstMemObj = dstImage.get();
builtinOpParams.size = {2, 3, 1};
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
auto blitProperties = ClBlitProperties::constructProperties(BlitterConstants::BlitDirection::ImageToImage,
csr,
builtinOpParams);
blitBuffer(&csr, blitProperties, true, *pDevice);
HardwareParse hwParser;
hwParser.parseCommands<FamilyType>(csr.commandStream, 0);
auto cmdIterator = find<typename FamilyType::XY_COPY_BLT *>(hwParser.cmdList.begin(), hwParser.cmdList.end());
ASSERT_NE(hwParser.cmdList.end(), cmdIterator);
auto bltCmd = genCmdCast<typename FamilyType::XY_COPY_BLT *>(*cmdIterator);
EXPECT_EQ(blitProperties.srcGpuAddress, bltCmd->getSourceBaseAddress());
EXPECT_EQ(blitProperties.dstGpuAddress, bltCmd->getDestinationBaseAddress());
}
HWTEST_F(BcsTests, givenBlitBufferCalledWhenClearColorAllocationIseSetThenItIsMadeResident) {
MockGraphicsAllocation graphicsAllocation1;
MockGraphicsAllocation graphicsAllocation2;