@@ -855,3 +855,160 @@ HWTEST_F(EnqueueReadBufferHw, givenHostPtrIsFromMappedBufferWhenReadBufferIsCall
855855 EXPECT_EQ (CL_SUCCESS, retVal);
856856 EXPECT_EQ (1u , csr.createAllocationForHostSurfaceCalled );
857857}
858+
859+ struct ReadBufferStagingBufferTest : public EnqueueReadBufferHw {
860+ void SetUp () override {
861+ REQUIRE_SVM_OR_SKIP (defaultHwInfo);
862+ EnqueueReadBufferHw::SetUp ();
863+ }
864+
865+ void TearDown () override {
866+ if (defaultHwInfo->capabilityTable .ftrSvm == false ) {
867+ return ;
868+ }
869+ EnqueueReadBufferHw::TearDown ();
870+ }
871+ constexpr static size_t chunkSize = MemoryConstants::megaByte * 2 ;
872+
873+ unsigned char ptr[MemoryConstants::cacheLineSize];
874+ MockBuffer buffer;
875+ cl_queue_properties props = {};
876+ };
877+
878+ HWTEST_F (ReadBufferStagingBufferTest, whenEnqueueStagingReadBufferCalledThenReturnSuccess) {
879+ MockCommandQueueHw<FamilyType> mockCommandQueueHw (context.get (), device.get (), &props);
880+ auto res = mockCommandQueueHw.enqueueStagingBufferTransfer (CL_COMMAND_READ_BUFFER, &buffer, false , 0 , buffer.getSize (), ptr, nullptr );
881+ EXPECT_TRUE (mockCommandQueueHw.flushCalled );
882+ EXPECT_EQ (res, CL_SUCCESS);
883+ EXPECT_EQ (1ul , mockCommandQueueHw.enqueueReadBufferCounter );
884+ auto &csr = device->getUltCommandStreamReceiver <FamilyType>();
885+ EXPECT_EQ (0u , csr.createAllocationForHostSurfaceCalled );
886+ }
887+
888+ HWTEST_F (ReadBufferStagingBufferTest, whenHostPtrRegisteredThenDontUseStagingUntilEventCompleted) {
889+ DebugManagerStateRestore restorer;
890+ debugManager.flags .EnableCopyWithStagingBuffers .set (1 );
891+ MockCommandQueueHw<FamilyType> mockCommandQueueHw (context.get (), device.get (), &props);
892+
893+ cl_event event;
894+ auto retVal = mockCommandQueueHw.enqueueReadBuffer (&buffer,
895+ CL_FALSE,
896+ 0 ,
897+ MemoryConstants::cacheLineSize,
898+ ptr,
899+ nullptr ,
900+ 0 ,
901+ nullptr ,
902+ &event);
903+ EXPECT_EQ (CL_SUCCESS, retVal);
904+ auto pEvent = castToObjectOrAbort<Event>(event);
905+
906+ EXPECT_TRUE (mockCommandQueueHw.isValidForStagingTransfer (&buffer, ptr, MemoryConstants::cacheLineSize, CL_COMMAND_READ_BUFFER, false , false ));
907+ EXPECT_FALSE (mockCommandQueueHw.isValidForStagingTransfer (&buffer, ptr, MemoryConstants::cacheLineSize, CL_COMMAND_READ_BUFFER, false , false ));
908+
909+ pEvent->updateExecutionStatus ();
910+ EXPECT_TRUE (mockCommandQueueHw.isValidForStagingTransfer (&buffer, ptr, MemoryConstants::cacheLineSize, CL_COMMAND_READ_BUFFER, false , false ));
911+
912+ pEvent->release ();
913+ }
914+
915+ HWTEST_F (ReadBufferStagingBufferTest, whenHostPtrRegisteredThenDontUseStagingUntilFinishCalled) {
916+ DebugManagerStateRestore restorer;
917+ debugManager.flags .EnableCopyWithStagingBuffers .set (1 );
918+ MockCommandQueueHw<FamilyType> mockCommandQueueHw (context.get (), device.get (), &props);
919+
920+ EXPECT_TRUE (mockCommandQueueHw.isValidForStagingTransfer (&buffer, ptr, MemoryConstants::cacheLineSize, CL_COMMAND_READ_BUFFER, false , false ));
921+ EXPECT_FALSE (mockCommandQueueHw.isValidForStagingTransfer (&buffer, ptr, MemoryConstants::cacheLineSize, CL_COMMAND_READ_BUFFER, false , false ));
922+
923+ mockCommandQueueHw.finish ();
924+ EXPECT_TRUE (mockCommandQueueHw.isValidForStagingTransfer (&buffer, ptr, MemoryConstants::cacheLineSize, CL_COMMAND_READ_BUFFER, false , false ));
925+ }
926+
927+ HWTEST_F (ReadBufferStagingBufferTest, whenEnqueueStagingReadBufferCalledWithLargeSizeThenSplitTransfer) {
928+ auto hostPtr = new unsigned char [chunkSize * 4 ];
929+ MockCommandQueueHw<FamilyType> mockCommandQueueHw (context.get (), device.get (), &props);
930+ auto retVal = CL_SUCCESS;
931+ std::unique_ptr<Buffer> buffer = std::unique_ptr<Buffer>(Buffer::create (context.get (),
932+ 0 ,
933+ chunkSize * 4 ,
934+ nullptr ,
935+ retVal));
936+ auto res = mockCommandQueueHw.enqueueStagingBufferTransfer (CL_COMMAND_READ_BUFFER, buffer.get (), false , 0 , chunkSize * 4 , hostPtr, nullptr );
937+ EXPECT_TRUE (mockCommandQueueHw.flushCalled );
938+ EXPECT_EQ (retVal, CL_SUCCESS);
939+ EXPECT_EQ (res, CL_SUCCESS);
940+ EXPECT_EQ (4ul , mockCommandQueueHw.enqueueReadBufferCounter );
941+ auto &csr = device->getUltCommandStreamReceiver <FamilyType>();
942+ EXPECT_EQ (0u , csr.createAllocationForHostSurfaceCalled );
943+
944+ delete[] hostPtr;
945+ }
946+
947+ HWTEST_F (ReadBufferStagingBufferTest, whenEnqueueStagingReadBufferCalledWithEventThenReturnValidEvent) {
948+ constexpr cl_command_type expectedLastCmd = CL_COMMAND_READ_BUFFER;
949+ MockCommandQueueHw<FamilyType> mockCommandQueueHw (context.get (), device.get (), &props);
950+ cl_event event;
951+ auto res = mockCommandQueueHw.enqueueStagingBufferTransfer (CL_COMMAND_READ_BUFFER, &buffer, false , 0 , MemoryConstants::cacheLineSize, ptr, &event);
952+ EXPECT_EQ (res, CL_SUCCESS);
953+
954+ auto pEvent = (Event *)event;
955+ EXPECT_EQ (expectedLastCmd, mockCommandQueueHw.lastCommandType );
956+ EXPECT_EQ (expectedLastCmd, pEvent->getCommandType ());
957+
958+ clReleaseEvent (event);
959+ }
960+
961+ HWTEST_F (ReadBufferStagingBufferTest, givenOutOfOrderQueueWhenEnqueueStagingReadBufferCalledWithSingleTransferThenNoBarrierEnqueued) {
962+ constexpr cl_command_type expectedLastCmd = CL_COMMAND_READ_BUFFER;
963+ MockCommandQueueHw<FamilyType> mockCommandQueueHw (context.get (), device.get (), &props);
964+ mockCommandQueueHw.setOoqEnabled ();
965+ cl_event event;
966+ auto res = mockCommandQueueHw.enqueueStagingBufferTransfer (CL_COMMAND_READ_BUFFER, &buffer, false , 0 , MemoryConstants::cacheLineSize, ptr, &event);
967+ EXPECT_EQ (res, CL_SUCCESS);
968+
969+ auto pEvent = (Event *)event;
970+ EXPECT_EQ (expectedLastCmd, mockCommandQueueHw.lastCommandType );
971+ EXPECT_EQ (expectedLastCmd, pEvent->getCommandType ());
972+
973+ clReleaseEvent (event);
974+ }
975+
976+ HWTEST_F (ReadBufferStagingBufferTest, givenCmdQueueWithProfilingWhenEnqueueStagingReadBufferThenTimestampsSetCorrectly) {
977+ cl_event event;
978+ MockCommandQueueHw<FamilyType> mockCommandQueueHw (context.get (), device.get (), &props);
979+ mockCommandQueueHw.setProfilingEnabled ();
980+ auto res = mockCommandQueueHw.enqueueStagingBufferTransfer (CL_COMMAND_READ_BUFFER, &buffer, false , 0 , MemoryConstants::cacheLineSize, ptr, &event);
981+ EXPECT_EQ (res, CL_SUCCESS);
982+
983+ auto pEvent = (Event *)event;
984+ EXPECT_FALSE (pEvent->isCPUProfilingPath ());
985+ EXPECT_TRUE (pEvent->isProfilingEnabled ());
986+
987+ clReleaseEvent (event);
988+ }
989+
990+ HWTEST_F (ReadBufferStagingBufferTest, whenEnqueueStagingReadBufferFailedThenPropagateErrorCode) {
991+ MockCommandQueueHw<FamilyType> mockCommandQueueHw (context.get (), device.get (), &props);
992+ mockCommandQueueHw.enqueueReadBufferCallBase = false ;
993+ auto res = mockCommandQueueHw.enqueueStagingBufferTransfer (CL_COMMAND_READ_BUFFER, &buffer, false , 0 , MemoryConstants::cacheLineSize, ptr, nullptr );
994+
995+ EXPECT_EQ (res, CL_INVALID_OPERATION);
996+ EXPECT_EQ (1ul , mockCommandQueueHw.enqueueReadBufferCounter );
997+ }
998+
999+ HWTEST_F (ReadBufferStagingBufferTest, whenIsValidForStagingTransferCalledThenReturnCorrectValue) {
1000+ MockCommandQueueHw<FamilyType> mockCommandQueueHw (context.get (), device.get (), &props);
1001+ auto isStagingBuffersEnabled = device->getProductHelper ().isStagingBuffersEnabled ();
1002+ unsigned char ptr[16 ];
1003+
1004+ EXPECT_EQ (isStagingBuffersEnabled, mockCommandQueueHw.isValidForStagingTransfer (&buffer, ptr, 16 , CL_COMMAND_READ_BUFFER, false , false ));
1005+ }
1006+
1007+ HWTEST_F (ReadBufferStagingBufferTest, whenIsValidForStagingTransferCalledAndCpuCopyAllowedThenReturnCorrectValue) {
1008+ DebugManagerStateRestore dbgRestore;
1009+ debugManager.flags .DoCpuCopyOnReadBuffer .set (1 );
1010+ MockCommandQueueHw<FamilyType> mockCommandQueueHw (context.get (), device.get (), &props);
1011+ unsigned char ptr[16 ];
1012+
1013+ EXPECT_FALSE (mockCommandQueueHw.isValidForStagingTransfer (&buffer, ptr, 16 , CL_COMMAND_READ_BUFFER, true , false ));
1014+ }
0 commit comments