diff --git a/opencl/source/api/api.cpp b/opencl/source/api/api.cpp index e5292844e6..2d5f827150 100644 --- a/opencl/source/api/api.cpp +++ b/opencl/source/api/api.cpp @@ -2542,7 +2542,7 @@ cl_int CL_API_CALL clEnqueueWriteBuffer(cl_command_queue commandQueue, return retVal; } - if (pCommandQueue->isValidForStagingTransfer(pBuffer, ptr, numEventsInWaitList > 0)) { + if (pCommandQueue->isValidForStagingTransfer(pBuffer, ptr, cb, CL_COMMAND_WRITE_BUFFER, blockingWrite, numEventsInWaitList > 0)) { retVal = pCommandQueue->enqueueStagingWriteBuffer( pBuffer, blockingWrite, @@ -2899,7 +2899,7 @@ cl_int CL_API_CALL clEnqueueReadImage(cl_command_queue commandQueue, return retVal; } - if (pCommandQueue->isValidForStagingTransfer(pImage, ptr, numEventsInWaitList > 0)) { + if (pCommandQueue->isValidForStagingTransfer(pImage, ptr, pImage->getSize(), CL_COMMAND_READ_IMAGE, blockingRead, numEventsInWaitList > 0)) { retVal = pCommandQueue->enqueueStagingImageTransfer(CL_COMMAND_READ_IMAGE, pImage, blockingRead, origin, region, rowPitch, slicePitch, ptr, event); } else { retVal = pCommandQueue->enqueueReadImage( @@ -2975,7 +2975,7 @@ cl_int CL_API_CALL clEnqueueWriteImage(cl_command_queue commandQueue, TRACING_EXIT(ClEnqueueWriteImage, &retVal); return retVal; } - if (pCommandQueue->isValidForStagingTransfer(pImage, ptr, numEventsInWaitList > 0)) { + if (pCommandQueue->isValidForStagingTransfer(pImage, ptr, pImage->getSize(), CL_COMMAND_WRITE_IMAGE, blockingWrite, numEventsInWaitList > 0)) { retVal = pCommandQueue->enqueueStagingImageTransfer(CL_COMMAND_WRITE_IMAGE, pImage, blockingWrite, origin, region, inputRowPitch, inputSlicePitch, ptr, event); } else { retVal = pCommandQueue->enqueueWriteImage( diff --git a/opencl/source/command_queue/command_queue.h b/opencl/source/command_queue/command_queue.h index f20ea08652..11162f097f 100644 --- a/opencl/source/command_queue/command_queue.h +++ b/opencl/source/command_queue/command_queue.h @@ -408,7 +408,7 @@ class CommandQueue : public BaseObject<_cl_command_queue> { cl_int enqueueStagingWriteBuffer(Buffer *buffer, cl_bool blockingCopy, size_t offset, size_t size, const void *ptr, cl_event *event); bool isValidForStagingBufferCopy(Device &device, void *dstPtr, const void *srcPtr, size_t size, bool hasDependencies); - bool isValidForStagingTransfer(MemObj *memObj, const void *ptr, bool hasDependencies); + bool isValidForStagingTransfer(MemObj *memObj, const void *ptr, size_t size, cl_command_type commandType, bool isBlocking, bool hasDependencies); protected: void *enqueueReadMemObjForMap(TransferProperties &transferProperties, EventsRequest &eventsRequest, cl_int &errcodeRet); diff --git a/opencl/source/command_queue/command_queue_staging.cpp b/opencl/source/command_queue/command_queue_staging.cpp index ee2f1ec0e2..96be5ffbf9 100644 --- a/opencl/source/command_queue/command_queue_staging.cpp +++ b/opencl/source/command_queue/command_queue_staging.cpp @@ -15,6 +15,7 @@ #include "opencl/source/context/context.h" #include "opencl/source/event/user_event.h" #include "opencl/source/helpers/base_object.h" +#include "opencl/source/mem_obj/buffer.h" #include "opencl/source/mem_obj/image.h" #include "CL/cl_ext.h" @@ -167,9 +168,9 @@ bool CommandQueue::isValidForStagingBufferCopy(Device &device, void *dstPtr, con return stagingBufferManager->isValidForCopy(device, dstPtr, srcPtr, size, hasDependencies, osContextId); } -bool CommandQueue::isValidForStagingTransfer(MemObj *memObj, const void *ptr, bool hasDependencies) { +bool CommandQueue::isValidForStagingTransfer(MemObj *memObj, const void *ptr, size_t size, cl_command_type commandType, bool isBlocking, bool hasDependencies) { GraphicsAllocation *allocation = nullptr; - context->tryGetExistingMapAllocation(ptr, memObj->getSize(), allocation); + context->tryGetExistingMapAllocation(ptr, size, allocation); if (allocation != nullptr) { // Direct transfer from mapped allocation is faster than staging buffer return false; @@ -178,11 +179,13 @@ bool CommandQueue::isValidForStagingTransfer(MemObj *memObj, const void *ptr, bo if (!stagingBufferManager) { return false; } + auto isValidForStaging = stagingBufferManager->isValidForStagingTransfer(this->getDevice(), ptr, size, hasDependencies); switch (memObj->peekClMemObjType()) { + case CL_MEM_OBJECT_BUFFER: + return isValidForStaging && !this->bufferCpuCopyAllowed(castToObject(memObj), commandType, isBlocking, size, const_cast(ptr), 0, nullptr); case CL_MEM_OBJECT_IMAGE1D: case CL_MEM_OBJECT_IMAGE2D: - case CL_MEM_OBJECT_BUFFER: - return stagingBufferManager->isValidForStagingTransfer(this->getDevice(), ptr, memObj->getSize(), hasDependencies); + return isValidForStaging; default: return false; } diff --git a/opencl/test/unit_test/api/cl_enqueue_write_buffer_tests.inl b/opencl/test/unit_test/api/cl_enqueue_write_buffer_tests.inl index aca86c18bb..30461c328a 100644 --- a/opencl/test/unit_test/api/cl_enqueue_write_buffer_tests.inl +++ b/opencl/test/unit_test/api/cl_enqueue_write_buffer_tests.inl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2023 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -19,10 +19,13 @@ using ClEnqueueWriteBufferTests = ApiTests; namespace ULT { TEST_F(ClEnqueueWriteBufferTests, GivenCorrectArgumentsWhenWritingBufferThenSuccessIsReturned) { - MockBuffer buffer{}; + MockContext context{}; + MockGraphicsAllocation allocation{}; + MockBuffer buffer{&context, allocation}; + MockCommandQueue commandQueue{context}; auto data = 1; auto retVal = clEnqueueWriteBuffer( - pCommandQueue, + &commandQueue, &buffer, false, 0, diff --git a/opencl/test/unit_test/command_queue/enqueue_write_buffer_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_write_buffer_tests.cpp index c1af836bc1..1d7022b05e 100644 --- a/opencl/test/unit_test/command_queue/enqueue_write_buffer_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_write_buffer_tests.cpp @@ -678,11 +678,11 @@ HWTEST_F(WriteBufferStagingBufferTest, whenHostPtrRegisteredThenDontUseStagingUn EXPECT_EQ(CL_SUCCESS, retVal); auto pEvent = castToObjectOrAbort(event); - EXPECT_TRUE(mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, false)); - EXPECT_FALSE(mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, false)); + EXPECT_TRUE(mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, MemoryConstants::cacheLineSize, CL_COMMAND_WRITE_BUFFER, false, false)); + EXPECT_FALSE(mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, MemoryConstants::cacheLineSize, CL_COMMAND_WRITE_BUFFER, false, false)); pEvent->updateExecutionStatus(); - EXPECT_TRUE(mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, false)); + EXPECT_TRUE(mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, MemoryConstants::cacheLineSize, CL_COMMAND_WRITE_BUFFER, false, false)); pEvent->release(); } @@ -692,11 +692,11 @@ HWTEST_F(WriteBufferStagingBufferTest, whenHostPtrRegisteredThenDontUseStagingUn debugManager.flags.EnableCopyWithStagingBuffers.set(1); MockCommandQueueHw mockCommandQueueHw(context.get(), device.get(), &props); - EXPECT_TRUE(mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, false)); - EXPECT_FALSE(mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, false)); + EXPECT_TRUE(mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, MemoryConstants::cacheLineSize, CL_COMMAND_WRITE_BUFFER, false, false)); + EXPECT_FALSE(mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, MemoryConstants::cacheLineSize, CL_COMMAND_WRITE_BUFFER, false, false)); mockCommandQueueHw.finish(); - EXPECT_TRUE(mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, false)); + EXPECT_TRUE(mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, MemoryConstants::cacheLineSize, CL_COMMAND_WRITE_BUFFER, false, false)); } HWTEST_F(WriteBufferStagingBufferTest, whenEnqueueStagingWriteBufferCalledWithLargeSizeThenSplitTransfer) { @@ -776,5 +776,14 @@ HWTEST_F(WriteBufferStagingBufferTest, whenIsValidForStagingTransferCalledThenRe auto isStagingBuffersEnabled = device->getProductHelper().isStagingBuffersEnabled(); unsigned char ptr[16]; - EXPECT_EQ(isStagingBuffersEnabled, mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, false)); + EXPECT_EQ(isStagingBuffersEnabled, mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, 16, CL_COMMAND_WRITE_BUFFER, false, false)); +} + +HWTEST_F(WriteBufferStagingBufferTest, whenIsValidForStagingTransferCalledAndCpuCopyAllowedThenReturnCorrectValue) { + DebugManagerStateRestore dbgRestore; + debugManager.flags.DoCpuCopyOnWriteBuffer.set(1); + MockCommandQueueHw mockCommandQueueHw(context.get(), device.get(), &props); + unsigned char ptr[16]; + + EXPECT_FALSE(mockCommandQueueHw.isValidForStagingTransfer(&buffer, ptr, 16, CL_COMMAND_WRITE_BUFFER, true, false)); } \ No newline at end of file diff --git a/opencl/test/unit_test/command_queue/enqueue_write_image_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_write_image_tests.cpp index 9a6ea97250..a8df155577 100644 --- a/opencl/test/unit_test/command_queue/enqueue_write_image_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_write_image_tests.cpp @@ -810,14 +810,14 @@ HWTEST_F(EnqueueWriteImageTest, whenisValidForStagingTransferCalledThenReturnCor unsigned char ptr[16]; std::unique_ptr image(Image1dHelper<>::create(context)); - EXPECT_EQ(isStagingBuffersEnabled, pCmdQ->isValidForStagingTransfer(image.get(), ptr, false)); + EXPECT_EQ(isStagingBuffersEnabled, pCmdQ->isValidForStagingTransfer(image.get(), ptr, image->getSize(), CL_COMMAND_WRITE_IMAGE, false, false)); pCmdQ->finish(); image.reset(Image2dHelper<>::create(context)); - EXPECT_EQ(isStagingBuffersEnabled, pCmdQ->isValidForStagingTransfer(image.get(), ptr, false)); + EXPECT_EQ(isStagingBuffersEnabled, pCmdQ->isValidForStagingTransfer(image.get(), ptr, image->getSize(), CL_COMMAND_WRITE_IMAGE, false, false)); image.reset(Image3dHelper<>::create(context)); - EXPECT_FALSE(pCmdQ->isValidForStagingTransfer(image.get(), ptr, false)); + EXPECT_FALSE(pCmdQ->isValidForStagingTransfer(image.get(), ptr, image->getSize(), CL_COMMAND_WRITE_IMAGE, false, false)); } struct WriteImageStagingBufferTest : public EnqueueWriteImageTest { @@ -949,6 +949,6 @@ HWTEST_F(WriteImageStagingBufferTest, givenIsValidForStagingTransferWhenUserPtrI cl_int retVal = CL_SUCCESS; auto mappedPtr = mockCommandQueueHw.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_READ, 0, buffer->getSize(), 0, nullptr, nullptr, retVal); EXPECT_EQ(CL_SUCCESS, retVal); - EXPECT_FALSE(mockCommandQueueHw.isValidForStagingTransfer(buffer, mappedPtr, false)); + EXPECT_FALSE(mockCommandQueueHw.isValidForStagingTransfer(buffer, mappedPtr, buffer->getSize(), CL_COMMAND_WRITE_IMAGE, false, false)); delete buffer; } \ No newline at end of file