From 23c1c4fea6e31bbac121d324b52b6b4bb45f45fb Mon Sep 17 00:00:00 2001 From: "Dunajski, Bartosz" Date: Wed, 7 Mar 2018 14:37:09 +0100 Subject: [PATCH] clEnqueueMapImage origin and region usage fixes - Return error on origin > 0 or region > 1 when its not allowed - For 1Darray, array region and origin are stored on 2nd position. For 2Darray, its on 3rd postion - Fix map offset for 1Darray image - Fix CPU data transfer for 1Darray image Change-Id: Id35ba5f54f117e7af318ca7e6e03c1fc942ce729 --- runtime/api/api.cpp | 13 +++ runtime/mem_obj/image.cpp | 22 ++++- runtime/mem_obj/image.h | 2 +- unit_tests/api/cl_enqueue_map_image_tests.cpp | 77 ++++++++++++++++ .../multiple_map_image_tests.cpp | 10 +-- unit_tests/fixtures/image_fixture.cpp | 6 +- unit_tests/mem_obj/image_tests.cpp | 13 +++ unit_tests/mem_obj/image_transfer_tests.cpp | 87 ++++++++++++++----- 8 files changed, 199 insertions(+), 31 deletions(-) diff --git a/runtime/api/api.cpp b/runtime/api/api.cpp index 54290b703f..b0983dd56d 100644 --- a/runtime/api/api.cpp +++ b/runtime/api/api.cpp @@ -2436,6 +2436,19 @@ void *CL_API_CALL clEnqueueMapImage(cl_command_queue commandQueue, break; } + auto imgType = pImage->getImageDesc().image_type; + if ((imgType == CL_MEM_OBJECT_IMAGE1D || imgType == CL_MEM_OBJECT_IMAGE1D_BUFFER) && + (origin[1] > 0 || origin[2] > 0 || region[1] > 1 || region[2] > 1)) { + retVal = CL_INVALID_VALUE; + break; + } + + if ((imgType == CL_MEM_OBJECT_IMAGE2D || imgType == CL_MEM_OBJECT_IMAGE1D_ARRAY) && + (origin[2] > 0 || region[2] > 1)) { + retVal = CL_INVALID_VALUE; + break; + } + retPtr = pCommandQueue->enqueueMapImage( pImage, blockingMap, diff --git a/runtime/mem_obj/image.cpp b/runtime/mem_obj/image.cpp index c038a109f0..af0bf975a5 100644 --- a/runtime/mem_obj/image.cpp +++ b/runtime/mem_obj/image.cpp @@ -84,13 +84,19 @@ Image::Image(Context *context, void Image::transferData(void *dest, size_t destRowPitch, size_t destSlicePitch, void *src, size_t srcRowPitch, size_t srcSlicePitch, - std::array ©Region, std::array ©Origin) { + std::array copyRegion, std::array copyOrigin) { size_t pixelSize = surfaceFormatInfo.ImageElementSizeInBytes; size_t lineWidth = copyRegion[0] * pixelSize; DBG_LOG(LogMemoryObject, __FUNCTION__, "memcpy dest:", dest, "sizeRowToCopy:", lineWidth, "src:", src); + 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]); + } + for (size_t slice = copyOrigin[2]; slice < (copyOrigin[2] + copyRegion[2]); slice++) { auto srcSliceOffset = ptrOffset(src, srcSlicePitch * slice); auto dstSliceOffset = ptrOffset(dest, destSlicePitch * slice); @@ -334,6 +340,11 @@ Image *Image::create(Context *context, if (transferNeeded) { std::array copyOrigin = {{0, 0, 0}}; std::array 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)}}; + } if (isTilingAllowed) { auto cmdQ = context->getSpecialQueue(); @@ -1195,6 +1206,13 @@ size_t Image::calculateOffsetForMapping(const MemObjOffsetArray &origin) const { size_t rowPitch = mappingOnCpuAllowed() ? imageDesc.image_row_pitch : getHostPtrRowPitch(); size_t slicePitch = mappingOnCpuAllowed() ? imageDesc.image_slice_pitch : getHostPtrSlicePitch(); - return getSurfaceFormatInfo().ImageElementSizeInBytes * origin[0] + rowPitch * origin[1] + slicePitch * origin[2]; + size_t offset = getSurfaceFormatInfo().ImageElementSizeInBytes * origin[0]; + if (imageDesc.image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY) { + offset += slicePitch * origin[1]; + } else { + offset += rowPitch * origin[1] + slicePitch * origin[2]; + } + + return offset; } } // namespace OCLRT diff --git a/runtime/mem_obj/image.h b/runtime/mem_obj/image.h index 1514a628fb..c657534505 100644 --- a/runtime/mem_obj/image.h +++ b/runtime/mem_obj/image.h @@ -194,7 +194,7 @@ class Image : public MemObj { void transferData(void *dst, size_t dstRowPitch, size_t dstSlicePitch, void *src, size_t srcRowPitch, size_t srcSlicePitch, - std::array ©Region, std::array ©Origin); + std::array copyRegion, std::array copyOrigin); cl_image_format imageFormat; cl_image_desc imageDesc; diff --git a/unit_tests/api/cl_enqueue_map_image_tests.cpp b/unit_tests/api/cl_enqueue_map_image_tests.cpp index becdf2c0c3..27ed370a69 100644 --- a/unit_tests/api/cl_enqueue_map_image_tests.cpp +++ b/unit_tests/api/cl_enqueue_map_image_tests.cpp @@ -24,6 +24,7 @@ #include "runtime/command_queue/command_queue.h" #include "runtime/context/context.h" #include "runtime/helpers/surface_formats.h" +#include "unit_tests/fixtures/image_fixture.h" using namespace OCLRT; @@ -124,6 +125,82 @@ TEST_F(clEnqueueMapImageTests, givenAnyZeroRegionParamWhenMapImageCalledThenRetu EXPECT_EQ(CL_SUCCESS, retVal); } +TEST_F(clEnqueueMapImageTests, givenSecondOriginCoordinateAndNotAllowedImgTypeWhenMapCalledThenReturnError) { + size_t region[3] = {1, 1, 1}; + size_t origin[3] = {0, 1, 0}; + + std::unique_ptr image(ImageHelper::create(pContext)); + clEnqueueMapImage(pCommandQueue, image.get(), CL_TRUE, CL_MAP_READ, origin, region, 0, 0, 0, nullptr, nullptr, &retVal); + EXPECT_EQ(CL_INVALID_VALUE, retVal); + + auto image1dBufferDesc = Image1dDefaults::imageDesc; + image1dBufferDesc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER; + image.reset(ImageHelper::create(pContext, &image1dBufferDesc)); + clEnqueueMapImage(pCommandQueue, image.get(), CL_TRUE, CL_MAP_READ, origin, region, 0, 0, 0, nullptr, nullptr, &retVal); + EXPECT_EQ(CL_INVALID_VALUE, retVal); +} + +TEST_F(clEnqueueMapImageTests, givenThirdOriginCoordinateAndNotAllowedImgTypeWhenMapCalledThenReturnError) { + size_t region[3] = {1, 1, 1}; + size_t origin[3] = {0, 0, 1}; + + std::unique_ptr image(ImageHelper::create(pContext)); + clEnqueueMapImage(pCommandQueue, image.get(), CL_TRUE, CL_MAP_READ, origin, region, 0, 0, 0, nullptr, nullptr, &retVal); + EXPECT_EQ(CL_INVALID_VALUE, retVal); + + image.reset(ImageHelper::create(pContext)); + clEnqueueMapImage(pCommandQueue, image.get(), CL_TRUE, CL_MAP_READ, origin, region, 0, 0, 0, nullptr, nullptr, &retVal); + EXPECT_EQ(CL_INVALID_VALUE, retVal); + + image.reset(ImageHelper::create(pContext)); + clEnqueueMapImage(pCommandQueue, image.get(), CL_TRUE, CL_MAP_READ, origin, region, 0, 0, 0, nullptr, nullptr, &retVal); + EXPECT_EQ(CL_INVALID_VALUE, retVal); + + auto image1dBufferDesc = Image1dDefaults::imageDesc; + image1dBufferDesc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER; + image.reset(ImageHelper::create(pContext, &image1dBufferDesc)); + clEnqueueMapImage(pCommandQueue, image.get(), CL_TRUE, CL_MAP_READ, origin, region, 0, 0, 0, nullptr, nullptr, &retVal); + EXPECT_EQ(CL_INVALID_VALUE, retVal); +} + +TEST_F(clEnqueueMapImageTests, givenSecondRegionCoordinateAndNotAllowedImgTypeWhenMapCalledThenReturnError) { + size_t region[3] = {1, 2, 1}; + size_t origin[3] = {0, 0, 0}; + + std::unique_ptr image(ImageHelper::create(pContext)); + clEnqueueMapImage(pCommandQueue, image.get(), CL_TRUE, CL_MAP_READ, origin, region, 0, 0, 0, nullptr, nullptr, &retVal); + EXPECT_EQ(CL_INVALID_VALUE, retVal); + + auto image1dBufferDesc = Image1dDefaults::imageDesc; + image1dBufferDesc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER; + image.reset(ImageHelper::create(pContext, &image1dBufferDesc)); + clEnqueueMapImage(pCommandQueue, image.get(), CL_TRUE, CL_MAP_READ, origin, region, 0, 0, 0, nullptr, nullptr, &retVal); + EXPECT_EQ(CL_INVALID_VALUE, retVal); +} + +TEST_F(clEnqueueMapImageTests, givenThirdRegionnCoordinateAndNotAllowedImgTypeWhenMapCalledThenReturnError) { + size_t region[3] = {1, 1, 2}; + size_t origin[3] = {0, 0, 0}; + + std::unique_ptr image(ImageHelper::create(pContext)); + clEnqueueMapImage(pCommandQueue, image.get(), CL_TRUE, CL_MAP_READ, origin, region, 0, 0, 0, nullptr, nullptr, &retVal); + EXPECT_EQ(CL_INVALID_VALUE, retVal); + + image.reset(ImageHelper::create(pContext)); + clEnqueueMapImage(pCommandQueue, image.get(), CL_TRUE, CL_MAP_READ, origin, region, 0, 0, 0, nullptr, nullptr, &retVal); + EXPECT_EQ(CL_INVALID_VALUE, retVal); + + image.reset(ImageHelper::create(pContext)); + clEnqueueMapImage(pCommandQueue, image.get(), CL_TRUE, CL_MAP_READ, origin, region, 0, 0, 0, nullptr, nullptr, &retVal); + EXPECT_EQ(CL_INVALID_VALUE, retVal); + + auto image1dBufferDesc = Image1dDefaults::imageDesc; + image1dBufferDesc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER; + image.reset(ImageHelper::create(pContext, &image1dBufferDesc)); + clEnqueueMapImage(pCommandQueue, image.get(), CL_TRUE, CL_MAP_READ, origin, region, 0, 0, 0, nullptr, nullptr, &retVal); + EXPECT_EQ(CL_INVALID_VALUE, retVal); +} + struct clEnqueueMapImageYUVTests : public api_fixture, public ::testing::Test { diff --git a/unit_tests/command_queue/multiple_map_image_tests.cpp b/unit_tests/command_queue/multiple_map_image_tests.cpp index 7667bd8046..2f571b079b 100644 --- a/unit_tests/command_queue/multiple_map_image_tests.cpp +++ b/unit_tests/command_queue/multiple_map_image_tests.cpp @@ -221,7 +221,7 @@ HWTEST_F(MultipleMapImageTest, givenUnblockedQueueWhenMappedOnCpuThenAddMappedPt EXPECT_TRUE(image->mappingOnCpuAllowed()); MemObjOffsetArray origin = {{1, 0, 0}}; - MemObjSizeArray region = {{3, 4, 1}}; + MemObjSizeArray region = {{3, 1, 1}}; void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_WRITE, &origin[0], ®ion[0], nullptr, nullptr, 0, nullptr, nullptr, &retVal); EXPECT_NE(nullptr, mappedPtr); EXPECT_EQ(1u, image->mapOperationsHandler.size()); @@ -242,7 +242,7 @@ HWTEST_F(MultipleMapImageTest, givenUnblockedQueueWhenReadOnlyMappedOnCpuThenDon EXPECT_TRUE(image->mappingOnCpuAllowed()); MemObjOffsetArray origin = {{1, 0, 0}}; - MemObjSizeArray region = {{3, 4, 1}}; + MemObjSizeArray region = {{3, 1, 1}}; void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_READ, &origin[0], ®ion[0], nullptr, nullptr, 0, nullptr, nullptr, &retVal); EXPECT_NE(nullptr, mappedPtr); EXPECT_EQ(1u, image->mapOperationsHandler.size()); @@ -265,7 +265,7 @@ HWTEST_F(MultipleMapImageTest, givenBlockedQueueWhenMappedOnCpuThenAddMappedPtrA cl_event clUnmapEvent = &unmapEvent; MemObjOffsetArray origin = {{1, 0, 0}}; - MemObjSizeArray region = {{3, 4, 1}}; + MemObjSizeArray region = {{3, 1, 1}}; void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_FALSE, CL_MAP_WRITE, &origin[0], ®ion[0], nullptr, nullptr, 1, &clMapEvent, nullptr, &retVal); mapEvent.setStatus(CL_COMPLETE); EXPECT_NE(nullptr, mappedPtr); @@ -292,7 +292,7 @@ HWTEST_F(MultipleMapImageTest, givenBlockedQueueWhenMappedReadOnlyOnCpuThenDontM cl_event clUnmapEvent = &unmapEvent; MemObjOffsetArray origin = {{1, 0, 0}}; - MemObjSizeArray region = {{3, 4, 1}}; + MemObjSizeArray region = {{3, 1, 1}}; void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_FALSE, CL_MAP_READ, &origin[0], ®ion[0], nullptr, nullptr, 1, &clMapEvent, nullptr, &retVal); mapEvent.setStatus(CL_COMPLETE); EXPECT_NE(nullptr, mappedPtr); @@ -379,7 +379,7 @@ HWTEST_F(MultipleMapImageTest, givenOverlapingPtrWhenMappingOnCpuForWriteThenRet EXPECT_TRUE(image->mappingOnCpuAllowed()); MemObjOffsetArray origin = {{1, 0, 0}}; - MemObjSizeArray region = {{3, 4, 1}}; + MemObjSizeArray region = {{3, 1, 1}}; void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_READ, &origin[0], ®ion[0], nullptr, nullptr, 0, nullptr, nullptr, &retVal); EXPECT_NE(nullptr, mappedPtr); EXPECT_EQ(CL_SUCCESS, retVal); diff --git a/unit_tests/fixtures/image_fixture.cpp b/unit_tests/fixtures/image_fixture.cpp index 3eb024c8ac..738ec0d14c 100644 --- a/unit_tests/fixtures/image_fixture.cpp +++ b/unit_tests/fixtures/image_fixture.cpp @@ -26,8 +26,8 @@ using OCLRT::MockContext; static const size_t imageWidth = 7; -static const size_t imageHeight = 7; -static const size_t imageDepth = 7; +static const size_t imageHeight = 9; +static const size_t imageDepth = 11; static const size_t imageArray = imageDepth; const cl_image_format Image1dDefaults::imageFormat = { @@ -41,7 +41,7 @@ const cl_image_format LuminanceImage::imageFormat = { const cl_image_desc Image1dDefaults::imageDesc = { CL_MEM_OBJECT_IMAGE1D, imageWidth, - imageHeight, + 1, 1, 1, 0, diff --git a/unit_tests/mem_obj/image_tests.cpp b/unit_tests/mem_obj/image_tests.cpp index 91a951e624..3fb116b63d 100644 --- a/unit_tests/mem_obj/image_tests.cpp +++ b/unit_tests/mem_obj/image_tests.cpp @@ -1027,6 +1027,19 @@ TEST(ImageTest, givenImageWhenAskedForPtrOffsetForCpuMappingThenReturnCorrectVal EXPECT_EQ(expectedOffset, retOffset); } +TEST(ImageTest, given1DArrayImageWhenAskedForPtrOffsetForMappingThenReturnCorrectValue) { + MockContext ctx; + std::unique_ptr image(ImageHelper::create(&ctx)); + + MemObjOffsetArray origin = {{4, 5, 0}}; + + auto retOffset = image->calculateOffsetForMapping(origin); + size_t expectedOffset = image->getSurfaceFormatInfo().ImageElementSizeInBytes * origin[0] + + image->getImageDesc().image_slice_pitch * origin[1]; + + EXPECT_EQ(expectedOffset, retOffset); +} + TEST(ImageTest, givenImageWhenAskedForPtrLengthForGpuMappingThenReturnCorrectValue) { MockContext ctx; std::unique_ptr image(ImageHelper::create(&ctx)); diff --git a/unit_tests/mem_obj/image_transfer_tests.cpp b/unit_tests/mem_obj/image_transfer_tests.cpp index e9808f34b4..5880ac032b 100644 --- a/unit_tests/mem_obj/image_transfer_tests.cpp +++ b/unit_tests/mem_obj/image_transfer_tests.cpp @@ -40,8 +40,6 @@ class ImageHostPtrTransferTests : public testing::Test { image.reset(ImageHelper>::create(context.get())); imgDesc = &image->getImageDesc(); - copyOrigin = {{imgDesc->image_width / 2, imgDesc->image_height / 2, imgDesc->image_depth / 2}}; - copyRegion = copyOrigin; hostPtrSlicePitch = image->getHostPtrSlicePitch(); hostPtrRowPitch = image->getHostPtrRowPitch(); @@ -50,7 +48,13 @@ class ImageHostPtrTransferTests : public testing::Test { pixelSize = image->getSurfaceFormatInfo().ImageElementSizeInBytes; } - void setExpectedData(uint8_t *dstPtr, size_t slicePitch, size_t rowPitch) { + void setExpectedData(uint8_t *dstPtr, size_t slicePitch, size_t rowPitch, std::array copyOrigin, std::array copyRegion) { + if (image->getImageDesc().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]); + } + for (size_t slice = copyOrigin[2]; slice < (copyOrigin[2] + copyRegion[2]); slice++) { auto sliceOffset = ptrOffset(dstPtr, slicePitch * slice); for (size_t height = copyOrigin[1]; height < (copyOrigin[1] + copyRegion[1]); height++) { @@ -64,9 +68,6 @@ class ImageHostPtrTransferTests : public testing::Test { std::unique_ptr context; std::unique_ptr image; - std::array copyRegion; - std::array copyOrigin; - const cl_image_desc *imgDesc = nullptr; size_t hostPtrSlicePitch, hostPtrRowPitch, imageSlicePitch, imageRowPitch, pixelSize; }; @@ -77,12 +78,15 @@ TEST_F(ImageHostPtrTransferTests, given3dImageWhenTransferToHostPtrCalledThenCop EXPECT_NE(hostPtrRowPitch, imageRowPitch); EXPECT_NE(image->getCpuAddress(), image->getHostPtr()); + std::array copyOrigin = {{imgDesc->image_width / 2, imgDesc->image_height / 2, imgDesc->image_depth / 2}}; + std::array copyRegion = copyOrigin; + std::unique_ptr expectedHostPtr(new uint8_t[hostPtrSlicePitch * imgDesc->image_depth]); memset(image->getHostPtr(), 0, hostPtrSlicePitch * imgDesc->image_depth); memset(expectedHostPtr.get(), 0, hostPtrSlicePitch * imgDesc->image_depth); memset(image->getCpuAddress(), 123, imageSlicePitch * imgDesc->image_depth); - setExpectedData(expectedHostPtr.get(), hostPtrSlicePitch, hostPtrRowPitch); + setExpectedData(expectedHostPtr.get(), hostPtrSlicePitch, hostPtrRowPitch, copyOrigin, copyRegion); image->transferDataToHostPtr(copyRegion, copyOrigin); @@ -95,12 +99,15 @@ TEST_F(ImageHostPtrTransferTests, given3dImageWhenTransferFromHostPtrCalledThenC EXPECT_NE(hostPtrRowPitch, imageRowPitch); EXPECT_NE(image->getCpuAddress(), image->getHostPtr()); + std::array copyOrigin = {{imgDesc->image_width / 2, imgDesc->image_height / 2, imgDesc->image_depth / 2}}; + std::array copyRegion = copyOrigin; + std::unique_ptr expectedImageData(new uint8_t[imageSlicePitch * imgDesc->image_depth]); memset(image->getHostPtr(), 123, hostPtrSlicePitch * imgDesc->image_depth); memset(expectedImageData.get(), 0, imageSlicePitch * imgDesc->image_depth); memset(image->getCpuAddress(), 0, imageSlicePitch * imgDesc->image_depth); - setExpectedData(expectedImageData.get(), imageSlicePitch, imageRowPitch); + setExpectedData(expectedImageData.get(), imageSlicePitch, imageRowPitch, copyOrigin, copyRegion); image->transferDataFromHostPtr(copyRegion, copyOrigin); @@ -113,16 +120,19 @@ TEST_F(ImageHostPtrTransferTests, given2dArrayImageWhenTransferToHostPtrCalledTh EXPECT_NE(hostPtrRowPitch, imageRowPitch); EXPECT_NE(image->getCpuAddress(), image->getHostPtr()); - std::unique_ptr expectedHostPtr(new uint8_t[hostPtrSlicePitch * imgDesc->image_depth]); - memset(image->getHostPtr(), 0, hostPtrSlicePitch * imgDesc->image_depth); - memset(expectedHostPtr.get(), 0, hostPtrSlicePitch * imgDesc->image_depth); - memset(image->getCpuAddress(), 123, imageSlicePitch * imgDesc->image_depth); + std::array copyOrigin = {{imgDesc->image_width / 2, imgDesc->image_height / 2, imgDesc->image_array_size / 2}}; + std::array copyRegion = copyOrigin; - setExpectedData(expectedHostPtr.get(), hostPtrSlicePitch, hostPtrRowPitch); + std::unique_ptr expectedHostPtr(new uint8_t[hostPtrSlicePitch * imgDesc->image_array_size]); + memset(image->getHostPtr(), 0, hostPtrSlicePitch * imgDesc->image_array_size); + memset(expectedHostPtr.get(), 0, hostPtrSlicePitch * imgDesc->image_array_size); + memset(image->getCpuAddress(), 123, imageSlicePitch * imgDesc->image_array_size); + + setExpectedData(expectedHostPtr.get(), hostPtrSlicePitch, hostPtrRowPitch, copyOrigin, copyRegion); image->transferDataToHostPtr(copyRegion, copyOrigin); - EXPECT_TRUE(memcmp(image->getHostPtr(), expectedHostPtr.get(), hostPtrSlicePitch * imgDesc->image_depth) == 0); + EXPECT_TRUE(memcmp(image->getHostPtr(), expectedHostPtr.get(), hostPtrSlicePitch * imgDesc->image_array_size) == 0); } TEST_F(ImageHostPtrTransferTests, given2dArrayImageWhenTransferFromHostPtrCalledThenCopyRequestedRegionAndOriginOnly) { @@ -131,14 +141,51 @@ TEST_F(ImageHostPtrTransferTests, given2dArrayImageWhenTransferFromHostPtrCalled EXPECT_NE(hostPtrRowPitch, imageRowPitch); EXPECT_NE(image->getCpuAddress(), image->getHostPtr()); - std::unique_ptr expectedImageData(new uint8_t[imageSlicePitch * imgDesc->image_depth]); - memset(image->getHostPtr(), 123, hostPtrSlicePitch * imgDesc->image_depth); - memset(expectedImageData.get(), 0, imageSlicePitch * imgDesc->image_depth); - memset(image->getCpuAddress(), 0, imageSlicePitch * imgDesc->image_depth); + std::array copyOrigin = {{imgDesc->image_width / 2, imgDesc->image_height / 2, imgDesc->image_array_size / 2}}; + std::array copyRegion = copyOrigin; - setExpectedData(expectedImageData.get(), imageSlicePitch, imageRowPitch); + std::unique_ptr expectedImageData(new uint8_t[imageSlicePitch * imgDesc->image_array_size]); + memset(image->getHostPtr(), 123, hostPtrSlicePitch * imgDesc->image_array_size); + memset(expectedImageData.get(), 0, imageSlicePitch * imgDesc->image_array_size); + memset(image->getCpuAddress(), 0, imageSlicePitch * imgDesc->image_array_size); + + setExpectedData(expectedImageData.get(), imageSlicePitch, imageRowPitch, copyOrigin, copyRegion); image->transferDataFromHostPtr(copyRegion, copyOrigin); - EXPECT_TRUE(memcmp(image->getCpuAddress(), expectedImageData.get(), imageSlicePitch * imgDesc->image_depth) == 0); + EXPECT_TRUE(memcmp(image->getCpuAddress(), expectedImageData.get(), imageSlicePitch * imgDesc->image_array_size) == 0); +} + +TEST_F(ImageHostPtrTransferTests, given1dArrayImageWhenTransferToHostPtrCalledThenUseSecondCoordinateAsSlice) { + createImageAndSetTestParams(); + std::array copyOrigin = {{imgDesc->image_width / 2, imgDesc->image_array_size / 2, 0}}; + std::array copyRegion = {{imgDesc->image_width / 2, imgDesc->image_array_size / 2, 1}}; + + std::unique_ptr expectedHostPtr(new uint8_t[hostPtrSlicePitch * imgDesc->image_array_size]); + memset(image->getHostPtr(), 0, hostPtrSlicePitch * imgDesc->image_array_size); + memset(expectedHostPtr.get(), 0, hostPtrSlicePitch * imgDesc->image_array_size); + memset(image->getCpuAddress(), 123, imageSlicePitch * imgDesc->image_array_size); + + setExpectedData(expectedHostPtr.get(), hostPtrSlicePitch, hostPtrRowPitch, copyOrigin, copyRegion); + + image->transferDataToHostPtr(copyRegion, copyOrigin); + + EXPECT_TRUE(memcmp(image->getHostPtr(), expectedHostPtr.get(), hostPtrSlicePitch * imgDesc->image_array_size) == 0); +} + +TEST_F(ImageHostPtrTransferTests, given1dArrayImageWhenTransferFromHostPtrCalledThenUseSecondCoordinateAsSlice) { + createImageAndSetTestParams(); + std::array copyOrigin = {{imgDesc->image_width / 2, imgDesc->image_array_size / 2, 0}}; + std::array copyRegion = {{imgDesc->image_width / 2, imgDesc->image_array_size / 2, 1}}; + + std::unique_ptr expectedImageData(new uint8_t[imageSlicePitch * imgDesc->image_array_size]); + memset(image->getHostPtr(), 123, hostPtrSlicePitch * imgDesc->image_array_size); + memset(expectedImageData.get(), 0, imageSlicePitch * imgDesc->image_array_size); + memset(image->getCpuAddress(), 0, imageSlicePitch * imgDesc->image_array_size); + + setExpectedData(expectedImageData.get(), imageSlicePitch, imageRowPitch, copyOrigin, copyRegion); + + image->transferDataFromHostPtr(copyRegion, copyOrigin); + + EXPECT_TRUE(memcmp(image->getCpuAddress(), expectedImageData.get(), imageSlicePitch * imgDesc->image_array_size) == 0); }