diff --git a/opencl/source/command_queue/command_queue_staging.cpp b/opencl/source/command_queue/command_queue_staging.cpp index 331c1ca8c3..686653f61c 100644 --- a/opencl/source/command_queue/command_queue_staging.cpp +++ b/opencl/source/command_queue/command_queue_staging.cpp @@ -70,7 +70,7 @@ cl_int CommandQueue::enqueueStagingImageTransfer(cl_command_type commandType, Im auto dstRowPitch = inputRowPitch ? inputRowPitch : globalRegion[0] * bytesPerPixel; auto stagingBufferManager = this->context->getStagingBufferManager(); - auto ret = stagingBufferManager->performImageTransfer(ptr, globalOrigin, globalRegion, dstRowPitch, chunkWrite, &csr, isRead); + auto ret = stagingBufferManager->performImageTransfer(ptr, globalOrigin, globalRegion, dstRowPitch, bytesPerPixel, chunkWrite, &csr, isRead); return postStagingTransferSync(ret, event, profilingEvent, isSingleTransfer, blockingCopy, commandType); } diff --git a/shared/source/utilities/staging_buffer_manager.cpp b/shared/source/utilities/staging_buffer_manager.cpp index d610ade970..0a108c44b0 100644 --- a/shared/source/utilities/staging_buffer_manager.cpp +++ b/shared/source/utilities/staging_buffer_manager.cpp @@ -55,31 +55,31 @@ StagingBufferManager::~StagingBufferManager() { * or tracking container for further reusage. */ template -StagingTransferStatus StagingBufferManager::performChunkTransfer(bool isRead, void *userPtr, size_t size, StagingQueue ¤tStagingBuffers, CommandStreamReceiver *csr, Func &func, Args... args) { +StagingTransferStatus StagingBufferManager::performChunkTransfer(size_t chunkTransferId, bool isRead, const UserData &userData, StagingQueue ¤tStagingBuffers, CommandStreamReceiver *csr, Func &func, Args... args) { StagingTransferStatus result{}; StagingBufferTracker tracker{}; - if (currentStagingBuffers.size() > 1) { - if (fetchHead(currentStagingBuffers, tracker) == WaitStatus::gpuHang) { + auto stagingBufferIndex = chunkTransferId % maxInFlightReads; + if (isRead && chunkTransferId >= maxInFlightReads) { + if (copyStagingToHost(currentStagingBuffers[stagingBufferIndex], tracker) == WaitStatus::gpuHang) { result.waitStatus = WaitStatus::gpuHang; return result; } } else { - auto allocatedSize = size; + auto allocatedSize = userData.size; auto [allocator, stagingBuffer] = requestStagingBuffer(allocatedSize); tracker = StagingBufferTracker{allocator, stagingBuffer, allocatedSize, csr}; } auto stagingBuffer = addrToPtr(tracker.chunkAddress); if (!isRead) { - memcpy(stagingBuffer, userPtr, size); + memcpy(stagingBuffer, userData.ptr, userData.size); } result.chunkCopyStatus = func(stagingBuffer, args...); tracker.taskCountToWait = csr->peekTaskCount(); if (isRead) { - UserDstData dstData{userPtr, size}; - currentStagingBuffers.push({dstData, tracker}); + currentStagingBuffers[stagingBufferIndex] = {userData, tracker}; } else { trackChunk(tracker); } @@ -103,7 +103,8 @@ StagingTransferStatus StagingBufferManager::performCopy(void *dstPtr, const void for (auto i = 0u; i < copiesNum; i++) { auto chunkDst = ptrOffset(dstPtr, i * chunkSize); auto chunkSrc = ptrOffset(srcPtr, i * chunkSize); - result = performChunkTransfer(false, const_cast(chunkSrc), chunkSize, stagingQueue, csr, chunkCopyFunc, chunkDst, chunkSize); + UserData userData{chunkSrc, chunkSize}; + result = performChunkTransfer(i, false, userData, stagingQueue, csr, chunkCopyFunc, chunkDst, chunkSize); if (result.chunkCopyStatus != 0) { return result; } @@ -112,7 +113,8 @@ StagingTransferStatus StagingBufferManager::performCopy(void *dstPtr, const void if (remainder != 0) { auto chunkDst = ptrOffset(dstPtr, copiesNum * chunkSize); auto chunkSrc = ptrOffset(srcPtr, copiesNum * chunkSize); - auto result = performChunkTransfer(false, const_cast(chunkSrc), remainder, stagingQueue, csr, chunkCopyFunc, chunkDst, remainder); + UserData userData{chunkSrc, remainder}; + auto result = performChunkTransfer(copiesNum, false, userData, stagingQueue, csr, chunkCopyFunc, chunkDst, remainder); if (result.chunkCopyStatus != 0) { return result; } @@ -127,7 +129,7 @@ StagingTransferStatus StagingBufferManager::performCopy(void *dstPtr, const void * Several rows are packed into single chunk unless size of single row exceeds maximum chunk size (2MB). * Caller provides actual function to enqueue read/write operation for single chunk. */ -StagingTransferStatus StagingBufferManager::performImageTransfer(const void *ptr, const size_t *globalOrigin, const size_t *globalRegion, size_t rowPitch, ChunkTransferImageFunc &chunkTransferImageFunc, CommandStreamReceiver *csr, bool isRead) { +StagingTransferStatus StagingBufferManager::performImageTransfer(const void *ptr, const size_t *globalOrigin, const size_t *globalRegion, size_t rowPitch, size_t bytesPerPixel, ChunkTransferImageFunc &chunkTransferImageFunc, CommandStreamReceiver *csr, bool isRead) { StagingQueue stagingQueue; size_t origin[3] = {}; size_t region[3] = {}; @@ -140,13 +142,16 @@ StagingTransferStatus StagingBufferManager::performImageTransfer(const void *ptr auto numOfChunks = globalRegion[1] / rowsPerChunk; auto remainder = globalRegion[1] % (rowsPerChunk * numOfChunks); StagingTransferStatus result{}; + RowPitchData rowPitchData{region[0] * bytesPerPixel, rowPitch, rowsPerChunk}; for (auto i = 0u; i < numOfChunks; i++) { origin[1] = globalOrigin[1] + i * rowsPerChunk; region[1] = rowsPerChunk; auto size = region[1] * rowPitch; auto chunkPtr = ptrOffset(ptr, i * rowsPerChunk * rowPitch); - result = performChunkTransfer(isRead, const_cast(chunkPtr), size, stagingQueue, csr, chunkTransferImageFunc, origin, region); + UserData userData{chunkPtr, size, rowPitchData}; + + result = performChunkTransfer(i, isRead, userData, stagingQueue, csr, chunkTransferImageFunc, origin, region); if (result.chunkCopyStatus != 0 || result.waitStatus == WaitStatus::gpuHang) { return result; } @@ -157,13 +162,19 @@ StagingTransferStatus StagingBufferManager::performImageTransfer(const void *ptr region[1] = remainder; auto size = region[1] * rowPitch; auto chunkPtr = ptrOffset(ptr, numOfChunks * rowsPerChunk * rowPitch); - result = performChunkTransfer(isRead, const_cast(chunkPtr), size, stagingQueue, csr, chunkTransferImageFunc, origin, region); + rowPitchData.rowsInChunk = remainder; + UserData userData{chunkPtr, size, rowPitchData}; + + result = performChunkTransfer(numOfChunks, isRead, userData, stagingQueue, csr, chunkTransferImageFunc, origin, region); if (result.chunkCopyStatus != 0 || result.waitStatus == WaitStatus::gpuHang) { return result; } } - result.waitStatus = drainAndReleaseStagingQueue(stagingQueue); + if (isRead) { + auto numOfSubmittedTransfers = numOfChunks + (remainder != 0 ? 1 : 0); + result.waitStatus = drainAndReleaseStagingQueue(stagingQueue, std::min(numOfSubmittedTransfers, maxInFlightReads)); + } return result; } @@ -175,7 +186,8 @@ StagingTransferStatus StagingBufferManager::performBufferTransfer(const void *pt StagingTransferStatus result{}; for (auto i = 0u; i < copiesNum; i++) { auto chunkPtr = ptrOffset(ptr, i * chunkSize); - result = performChunkTransfer(isRead, const_cast(chunkPtr), chunkSize, stagingQueue, csr, chunkTransferBufferFunc, chunkOffset, chunkSize); + UserData userData{chunkPtr, chunkSize}; + result = performChunkTransfer(i, isRead, userData, stagingQueue, csr, chunkTransferBufferFunc, chunkOffset, chunkSize); if (result.chunkCopyStatus != 0) { return result; } @@ -184,33 +196,39 @@ StagingTransferStatus StagingBufferManager::performBufferTransfer(const void *pt if (remainder != 0) { auto chunkPtr = ptrOffset(ptr, copiesNum * chunkSize); - result = performChunkTransfer(isRead, const_cast(chunkPtr), remainder, stagingQueue, csr, chunkTransferBufferFunc, chunkOffset, remainder); + UserData userData{chunkPtr, remainder}; + result = performChunkTransfer(copiesNum, isRead, userData, stagingQueue, csr, chunkTransferBufferFunc, chunkOffset, remainder); if (result.chunkCopyStatus != 0) { return result; } } - result.waitStatus = drainAndReleaseStagingQueue(stagingQueue); return result; } /* - * This method is used for read transfers. It waits for oldest transfer to finish + * This method is used for read transfers. It waits for transfer to finish * and copies data associated with that transfer to host allocation. * Returned tracker contains staging buffer ready for reuse. */ -WaitStatus StagingBufferManager::fetchHead(StagingQueue &stagingQueue, StagingBufferTracker &tracker) const { - auto &head = stagingQueue.front(); - auto status = head.second.csr->waitForTaskCount(head.second.taskCountToWait); +WaitStatus StagingBufferManager::copyStagingToHost(const std::pair &transfer, StagingBufferTracker &tracker) const { + auto status = transfer.second.csr->waitForTaskCount(transfer.second.taskCountToWait); if (status == WaitStatus::gpuHang) { return status; } - auto &userData = head.first; - tracker = head.second; + auto &userData = transfer.first; + tracker = transfer.second; auto stagingBuffer = addrToPtr(tracker.chunkAddress); - memcpy(userData.ptr, stagingBuffer, userData.size); - stagingQueue.pop(); + auto userDst = const_cast(userData.ptr); + if (userData.rowPitchData.rowSize < userData.rowPitchData.rowPitch) { + for (auto rowId = 0u; rowId < userData.rowPitchData.rowsInChunk; rowId++) { + auto offset = rowId * userData.rowPitchData.rowPitch; + memcpy(ptrOffset(userDst, offset), ptrOffset(stagingBuffer, offset), userData.rowPitchData.rowSize); + } + } else { + memcpy(userDst, stagingBuffer, userData.size); + } return WaitStatus::ready; } @@ -218,10 +236,10 @@ WaitStatus StagingBufferManager::fetchHead(StagingQueue &stagingQueue, StagingBu * Waits for all pending transfers to finish. * Releases staging buffers back to pool for reuse. */ -WaitStatus StagingBufferManager::drainAndReleaseStagingQueue(StagingQueue &stagingQueue) const { +WaitStatus StagingBufferManager::drainAndReleaseStagingQueue(const StagingQueue &stagingQueue, size_t numOfTransfers) const { StagingBufferTracker tracker{}; - while (!stagingQueue.empty()) { - auto status = fetchHead(stagingQueue, tracker); + for (auto i = 0u; i < numOfTransfers; i++) { + auto status = copyStagingToHost(stagingQueue[i], tracker); if (status == WaitStatus::gpuHang) { return status; } diff --git a/shared/source/utilities/staging_buffer_manager.h b/shared/source/utilities/staging_buffer_manager.h index 3037c614e8..f6015ebabf 100644 --- a/shared/source/utilities/staging_buffer_manager.h +++ b/shared/source/utilities/staging_buffer_manager.h @@ -58,9 +58,16 @@ struct StagingBufferTracker { void freeChunk() const; }; -struct UserDstData { - void *ptr; - size_t size; +struct RowPitchData { + size_t rowSize = 0; + size_t rowPitch = 0; + size_t rowsInChunk = 0; +}; + +struct UserData { + const void *ptr = nullptr; + size_t size = 0; + RowPitchData rowPitchData{}; }; struct StagingTransferStatus { @@ -68,7 +75,8 @@ struct StagingTransferStatus { WaitStatus waitStatus = WaitStatus::ready; }; -using StagingQueue = std::queue>; +constexpr size_t maxInFlightReads = 2u; +using StagingQueue = StackVec, maxInFlightReads>; class StagingBufferManager { public: @@ -83,7 +91,7 @@ class StagingBufferManager { bool isValidForStagingTransfer(const Device &device, const void *ptr, size_t size, bool hasDependencies); StagingTransferStatus performCopy(void *dstPtr, const void *srcPtr, size_t size, ChunkCopyFunction &chunkCopyFunc, CommandStreamReceiver *csr); - StagingTransferStatus performImageTransfer(const void *ptr, const size_t *globalOrigin, const size_t *globalRegion, size_t rowPitch, ChunkTransferImageFunc &chunkTransferImageFunc, CommandStreamReceiver *csr, bool isRead); + StagingTransferStatus performImageTransfer(const void *ptr, const size_t *globalOrigin, const size_t *globalRegion, size_t rowPitch, size_t bytesPerPixel, ChunkTransferImageFunc &chunkTransferImageFunc, CommandStreamReceiver *csr, bool isRead); StagingTransferStatus performBufferTransfer(const void *ptr, size_t globalOffset, size_t globalSize, ChunkTransferBufferFunc &chunkTransferBufferFunc, CommandStreamReceiver *csr, bool isRead); std::pair requestStagingBuffer(size_t &size); @@ -98,10 +106,10 @@ class StagingBufferManager { void clearTrackedChunks(); template - StagingTransferStatus performChunkTransfer(bool isRead, void *userPtr, size_t size, StagingQueue ¤tStagingBuffers, CommandStreamReceiver *csr, Func &func, Args... args); + StagingTransferStatus performChunkTransfer(size_t chunkTransferId, bool isRead, const UserData &userData, StagingQueue ¤tStagingBuffers, CommandStreamReceiver *csr, Func &func, Args... args); - WaitStatus fetchHead(StagingQueue &stagingQueue, StagingBufferTracker &tracker) const; - WaitStatus drainAndReleaseStagingQueue(StagingQueue &stagingQueue) const; + WaitStatus copyStagingToHost(const std::pair &transfer, StagingBufferTracker &tracker) const; + WaitStatus drainAndReleaseStagingQueue(const StagingQueue &stagingQueue, size_t numOfTransfers) const; bool isValidForStaging(const Device &device, const void *ptr, size_t size, bool hasDependencies); diff --git a/shared/test/unit_test/utilities/staging_buffer_manager_tests.cpp b/shared/test/unit_test/utilities/staging_buffer_manager_tests.cpp index 61c4412e4f..582ddfc796 100644 --- a/shared/test/unit_test/utilities/staging_buffer_manager_tests.cpp +++ b/shared/test/unit_test/utilities/staging_buffer_manager_tests.cpp @@ -85,20 +85,26 @@ class StagingBufferManagerFixture : public DeviceFixture { } void imageTransferThroughStagingBuffers(bool isRead, size_t rowPitch, const size_t *globalOrigin, const size_t *globalRegion, size_t expectedChunks) { - auto hostPtr = new unsigned char[stagingBufferSize * expectedChunks]; - auto imageData = new unsigned char[stagingBufferSize * expectedChunks]; + auto hostPtr = new unsigned char[stagingBufferSize * (expectedChunks + globalOrigin[1])]; + auto imageData = new unsigned char[stagingBufferSize * (expectedChunks + globalOrigin[1])]; if (isRead) { - memset(hostPtr, 0, stagingBufferSize * expectedChunks); - memset(imageData, 0xFF, stagingBufferSize * expectedChunks); + memset(hostPtr, 0, stagingBufferSize * (expectedChunks + globalOrigin[1])); + memset(imageData, 0xFF, stagingBufferSize * (expectedChunks + globalOrigin[1])); } else { - memset(hostPtr, 0xFF, stagingBufferSize * expectedChunks); - memset(imageData, 0, stagingBufferSize * expectedChunks); + memset(hostPtr, 0xFF, stagingBufferSize * (expectedChunks + globalOrigin[1])); + memset(imageData, 0, stagingBufferSize * (expectedChunks + globalOrigin[1])); } size_t chunkCounter = 0; size_t expectedOrigin = globalOrigin[1]; + auto rowSize = globalRegion[0] * pixelElemSize; auto expectedRowsPerChunk = std::min(std::max(1ul, stagingBufferSize / rowPitch), globalRegion[1]); auto numOfChunks = globalRegion[1] / expectedRowsPerChunk; auto remainder = globalRegion[1] % (expectedRowsPerChunk * numOfChunks); + + // This lambda function simulates chunk read/write on image. + // Iterates over rows in given image chunk, copies each row with offset origin[0] + // For writes, data is transferred in staging buffer -> image direction. + // For reads, it's image -> staging buffer. ChunkTransferImageFunc chunkTransfer = [&](void *stagingBuffer, const size_t *origin, const size_t *region) -> int32_t { EXPECT_NE(nullptr, stagingBuffer); EXPECT_NE(nullptr, origin); @@ -113,11 +119,14 @@ class StagingBufferManagerFixture : public DeviceFixture { } else { EXPECT_EQ(expectedRowsPerChunk, region[1]); } - auto offset = origin[1] - globalOrigin[1]; - if (isRead) { - memcpy(stagingBuffer, imageData + rowPitch * offset, rowPitch * region[1]); - } else { - memcpy(imageData + rowPitch * offset, stagingBuffer, rowPitch * region[1]); + + for (auto rowId = 0u; rowId < region[1]; rowId++) { + void *dst = ptrOffset(imageData, (origin[1] + rowId) * rowPitch + origin[0] * pixelElemSize); + void *src = ptrOffset(stagingBuffer, rowId * rowPitch); + if (isRead) { + std::swap(dst, src); + } + memcpy(dst, src, rowSize); } expectedOrigin += region[1]; chunkCounter++; @@ -125,10 +134,14 @@ class StagingBufferManagerFixture : public DeviceFixture { return 0; }; auto initialNumOfUsmAllocations = svmAllocsManager->svmAllocs.getNumAllocs(); - auto ret = stagingBufferManager->performImageTransfer(hostPtr, globalOrigin, globalRegion, rowPitch, chunkTransfer, csr, isRead); + auto ret = stagingBufferManager->performImageTransfer(hostPtr, globalOrigin, globalRegion, rowPitch, pixelElemSize, chunkTransfer, csr, isRead); auto newUsmAllocations = svmAllocsManager->svmAllocs.getNumAllocs() - initialNumOfUsmAllocations; - EXPECT_EQ(0, memcmp(hostPtr, imageData, rowPitch * (numOfChunks * expectedRowsPerChunk + remainder))); + for (auto rowId = 0u; rowId < globalRegion[1]; rowId++) { + auto offset = (globalOrigin[1] + rowId) * rowPitch; + EXPECT_EQ(0, memcmp(ptrOffset(hostPtr, rowId * rowPitch), ptrOffset(imageData, offset + globalOrigin[0] * pixelElemSize), rowSize)); + } + EXPECT_EQ(0, ret.chunkCopyStatus); EXPECT_EQ(WaitStatus::ready, ret.waitStatus); EXPECT_EQ(expectedChunks, chunkCounter); @@ -171,6 +184,7 @@ class StagingBufferManagerFixture : public DeviceFixture { } constexpr static size_t stagingBufferSize = MemoryConstants::megaByte * 2; + constexpr static size_t pixelElemSize = 1u; DebugManagerStateRestore restorer; std::unique_ptr svmAllocsManager; std::unique_ptr stagingBufferManager; @@ -500,13 +514,20 @@ TEST_F(StagingBufferManagerTest, givenStagingBufferWhenPerformImageWriteWithRema imageTransferThroughStagingBuffers(false, MemoryConstants::megaByte, globalOrigin, globalRegion, expectedChunks); } -TEST_F(StagingBufferManagerTest, givenStagingBufferWhenPerformImageReadThenWholeRegionCovered) { +TEST_F(StagingBufferManagerTest, givenStagingBufferWhenPerformImageReadThenRegionCovered) { size_t expectedChunks = 8; const size_t globalOrigin[3] = {0, 0, 0}; const size_t globalRegion[3] = {4, expectedChunks, 1}; imageTransferThroughStagingBuffers(true, stagingBufferSize, globalOrigin, globalRegion, expectedChunks); } +TEST_F(StagingBufferManagerTest, givenStagingBufferWhenPerformImageReadThenWholeRegionCovered) { + size_t expectedChunks = 8; + const size_t globalOrigin[3] = {0, 0, 0}; + const size_t globalRegion[3] = {stagingBufferSize, expectedChunks, 1}; + imageTransferThroughStagingBuffers(true, stagingBufferSize, globalOrigin, globalRegion, expectedChunks); +} + TEST_F(StagingBufferManagerTest, givenStagingBufferWhenPerformImageReadWithOriginThenWholeRegionCovered) { size_t expectedChunks = 8; const size_t globalOrigin[3] = {4, 4, 0}; @@ -528,6 +549,13 @@ TEST_F(StagingBufferManagerTest, givenStagingBufferWhenPerformImageReadWithRemai imageTransferThroughStagingBuffers(true, MemoryConstants::megaByte, globalOrigin, globalRegion, expectedChunks); } +TEST_F(StagingBufferManagerTest, givenStagingBufferWhenPerformImageReadWithRemainderAndTransfersWithinLimitThenWholeRegionCovered) { + size_t expectedChunks = 2; + const size_t globalOrigin[3] = {0, 0, 0}; + const size_t globalRegion[3] = {4, 3, 1}; + imageTransferThroughStagingBuffers(true, MemoryConstants::megaByte, globalOrigin, globalRegion, expectedChunks); +} + HWTEST_F(StagingBufferManagerTest, givenStagingBufferWhenGpuHangDuringChunkReadFromImageThenReturnImmediatelyWithFailure) { size_t expectedChunks = 4; const size_t globalOrigin[3] = {0, 0, 0}; @@ -541,7 +569,7 @@ HWTEST_F(StagingBufferManagerTest, givenStagingBufferWhenGpuHangDuringChunkReadF }; auto ultCsr = reinterpret_cast *>(csr); ultCsr->waitForTaskCountReturnValue = WaitStatus::gpuHang; - auto ret = stagingBufferManager->performImageTransfer(ptr, globalOrigin, globalRegion, MemoryConstants::megaByte, chunkWrite, csr, true); + auto ret = stagingBufferManager->performImageTransfer(ptr, globalOrigin, globalRegion, MemoryConstants::megaByte, pixelElemSize, chunkWrite, csr, true); EXPECT_EQ(0, ret.chunkCopyStatus); EXPECT_EQ(WaitStatus::gpuHang, ret.waitStatus); EXPECT_EQ(2u, chunkCounter); @@ -563,7 +591,7 @@ HWTEST_F(StagingBufferManagerTest, givenStagingBufferWhenGpuHangAfterChunkReadFr } return 0; }; - auto ret = stagingBufferManager->performImageTransfer(ptr, globalOrigin, globalRegion, MemoryConstants::megaByte, chunkWrite, csr, true); + auto ret = stagingBufferManager->performImageTransfer(ptr, globalOrigin, globalRegion, MemoryConstants::megaByte, pixelElemSize, chunkWrite, csr, true); EXPECT_EQ(0, ret.chunkCopyStatus); EXPECT_EQ(WaitStatus::gpuHang, ret.waitStatus); EXPECT_EQ(4u, chunkCounter); @@ -586,7 +614,7 @@ HWTEST_F(StagingBufferManagerTest, givenStagingBufferWhenGpuHangDuringRemainderC } return 0; }; - auto ret = stagingBufferManager->performImageTransfer(ptr, globalOrigin, globalRegion, MemoryConstants::megaByte, chunkWrite, csr, true); + auto ret = stagingBufferManager->performImageTransfer(ptr, globalOrigin, globalRegion, MemoryConstants::megaByte, pixelElemSize, chunkWrite, csr, true); EXPECT_EQ(0, ret.chunkCopyStatus); EXPECT_EQ(WaitStatus::gpuHang, ret.waitStatus); EXPECT_EQ(remainderCounter - 1, chunkCounter); @@ -605,7 +633,7 @@ TEST_F(StagingBufferManagerTest, givenStagingBufferWhenFailedChunkImageWriteThen ++chunkCounter; return expectedErrorCode; }; - auto ret = stagingBufferManager->performImageTransfer(ptr, globalOrigin, globalRegion, MemoryConstants::megaByte, chunkWrite, csr, false); + auto ret = stagingBufferManager->performImageTransfer(ptr, globalOrigin, globalRegion, MemoryConstants::megaByte, pixelElemSize, chunkWrite, csr, false); EXPECT_EQ(expectedErrorCode, ret.chunkCopyStatus); EXPECT_EQ(WaitStatus::ready, ret.waitStatus); EXPECT_EQ(1u, chunkCounter); @@ -628,7 +656,7 @@ TEST_F(StagingBufferManagerTest, givenStagingBufferWhenFailedChunkImageWriteWith } return 0; }; - auto ret = stagingBufferManager->performImageTransfer(ptr, globalOrigin, globalRegion, MemoryConstants::megaByte, chunkWrite, csr, false); + auto ret = stagingBufferManager->performImageTransfer(ptr, globalOrigin, globalRegion, MemoryConstants::megaByte, pixelElemSize, chunkWrite, csr, false); EXPECT_EQ(expectedErrorCode, ret.chunkCopyStatus); EXPECT_EQ(WaitStatus::ready, ret.waitStatus); EXPECT_EQ(remainderCounter, chunkCounter);