From fc9de71febb8d25ee140acaef806329eb656fd3e Mon Sep 17 00:00:00 2001 From: Dominik Dabek Date: Tue, 16 Jul 2024 10:18:29 +0000 Subject: [PATCH] fix(ocl): finish in release ogl object if needed Finish cache flushes before exiting api call if releasing displayable ogl object or dcflush is mitigated. Related-To: NEO-11694 Signed-off-by: Dominik Dabek --- opencl/source/command_queue/command_queue.cpp | 5 +++ .../command_queue_hw_1_tests.cpp | 38 ++++++++++++++++++- .../command_queue/command_queue_tests.cpp | 37 +----------------- opencl/test/unit_test/mocks/CMakeLists.txt | 1 + .../test/unit_test/mocks/mock_command_queue.h | 6 ++- .../unit_test/mocks/mock_sharing_handler.h | 17 +++++++++ 6 files changed, 66 insertions(+), 38 deletions(-) create mode 100644 opencl/test/unit_test/mocks/mock_sharing_handler.h diff --git a/opencl/source/command_queue/command_queue.cpp b/opencl/source/command_queue/command_queue.cpp index fa4bc50436..a2802001d8 100644 --- a/opencl/source/command_queue/command_queue.cpp +++ b/opencl/source/command_queue/command_queue.cpp @@ -640,6 +640,11 @@ cl_int CommandQueue::enqueueReleaseSharedObjects(cl_uint numObjects, const cl_me if (this->getDevice().getProductHelper().isDcFlushMitigated() || isDisplayableReleased) { this->getGpgpuCommandStreamReceiver().registerDcFlushForDcMitigation(); this->getGpgpuCommandStreamReceiver().sendRenderStateCacheFlush(); + { + TakeOwnershipWrapper queueOwnership(*this); + this->taskCount = this->getGpgpuCommandStreamReceiver().peekTaskCount(); + } + this->finish(); } else if (isImageReleased) { this->getGpgpuCommandStreamReceiver().sendRenderStateCacheFlush(); } diff --git a/opencl/test/unit_test/command_queue/command_queue_hw_1_tests.cpp b/opencl/test/unit_test/command_queue/command_queue_hw_1_tests.cpp index 7f61d18ac8..af9b704078 100644 --- a/opencl/test/unit_test/command_queue/command_queue_hw_1_tests.cpp +++ b/opencl/test/unit_test/command_queue/command_queue_hw_1_tests.cpp @@ -25,7 +25,7 @@ #include "opencl/test/unit_test/mocks/mock_command_queue.h" #include "opencl/test/unit_test/mocks/mock_event.h" #include "opencl/test/unit_test/mocks/mock_kernel.h" - +#include "opencl/test/unit_test/mocks/mock_sharing_handler.h" using namespace NEO; HWTEST_F(CommandQueueHwTest, givenNoTimestampPacketsWhenWaitForTimestampsThenNoWaitAndTagIsNotUpdated) { @@ -1433,3 +1433,39 @@ HWTEST_F(CommandQueueHwTest, givenNotBlockedIOQWhenCpuTransferIsBlockedOutEventP EXPECT_EQ(1, commandQueue->enqueueMarkerWithWaitListCalledCount); clReleaseEvent(returnEvent); } + +HWTEST_F(CommandQueueHwTest, givenDirectSubmissionAndSharedDisplayableImageWhenReleasingSharedObjectThenFlushRenderStateCacheAndForceDcFlush) { + MockCommandQueueHw mockCmdQueueHw{context, pClDevice, nullptr}; + MockSharingHandler *mockSharingHandler = new MockSharingHandler; + + auto &ultCsr = mockCmdQueueHw.getUltCommandStreamReceiver(); + ultCsr.heapStorageRequiresRecyclingTag = false; + + auto directSubmission = new MockDirectSubmissionHw>(ultCsr); + ultCsr.directSubmission.reset(directSubmission); + + auto image = std::unique_ptr(ImageHelper::create(context)); + image->setSharingHandler(mockSharingHandler); + image->getGraphicsAllocation(0u)->setAllocationType(AllocationType::sharedImage); + + cl_mem memObject = image.get(); + cl_uint numObjects = 1; + cl_mem *memObjects = &memObject; + + cl_int result = mockCmdQueueHw.enqueueAcquireSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0); + EXPECT_EQ(result, CL_SUCCESS); + image->setIsDisplayable(true); + + ultCsr.directSubmissionAvailable = true; + ultCsr.callBaseSendRenderStateCacheFlush = true; + EXPECT_FALSE(ultCsr.renderStateCacheFlushed); + + const auto taskCountBefore = mockCmdQueueHw.taskCount; + const auto finishCalledBefore = mockCmdQueueHw.finishCalledCount; + result = mockCmdQueueHw.enqueueReleaseSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0); + EXPECT_EQ(result, CL_SUCCESS); + EXPECT_TRUE(ultCsr.renderStateCacheFlushed); + EXPECT_TRUE(ultCsr.renderStateCacheDcFlushForced); + EXPECT_EQ(finishCalledBefore + 1u, mockCmdQueueHw.finishCalledCount); + EXPECT_EQ(taskCountBefore + 1u, mockCmdQueueHw.taskCount); +} \ No newline at end of file diff --git a/opencl/test/unit_test/command_queue/command_queue_tests.cpp b/opencl/test/unit_test/command_queue/command_queue_tests.cpp index fe8341c273..d31e7aba32 100644 --- a/opencl/test/unit_test/command_queue/command_queue_tests.cpp +++ b/opencl/test/unit_test/command_queue/command_queue_tests.cpp @@ -55,6 +55,7 @@ #include "opencl/test/unit_test/mocks/mock_kernel.h" #include "opencl/test/unit_test/mocks/mock_mdi.h" #include "opencl/test/unit_test/mocks/mock_program.h" +#include "opencl/test/unit_test/mocks/mock_sharing_handler.h" #include "gtest/gtest.h" @@ -1311,13 +1312,6 @@ TEST(CommandQueue, givenEnqueueAcquireSharedObjectsWhenNoObjectsThenReturnSucces EXPECT_EQ(result, CL_SUCCESS); } -class MockSharingHandler : public SharingHandler { - public: - void synchronizeObject(UpdateData &updateData) override { - updateData.synchronizationStatus = ACQUIRE_SUCCESFUL; - } -}; - using CommandQueueTests = ::testing::Test; HWTEST_F(CommandQueueTests, givenEnqueuesForSharedObjectsWithImageWhenUsingSharingHandlerThenReturnSuccess) { MockContext context; @@ -1371,35 +1365,6 @@ HWTEST_F(CommandQueueTests, givenDirectSubmissionAndSharedImageWhenReleasingShar EXPECT_EQ(ultCsr->renderStateCacheDcFlushForced, context.getDevice(0)->getProductHelper().isDcFlushMitigated()); } -HWTEST_F(CommandQueueTests, givenDirectSubmissionAndSharedDisplayableImageWhenReleasingSharedObjectThenFlushRenderStateCacheAndForceDcFlush) { - MockContext context; - MockCommandQueue cmdQ(&context, context.getDevice(0), 0, false); - MockSharingHandler *mockSharingHandler = new MockSharingHandler; - - auto image = std::unique_ptr(ImageHelper::create(&context)); - image->setSharingHandler(mockSharingHandler); - image->getGraphicsAllocation(0u)->setAllocationType(AllocationType::sharedImage); - - cl_mem memObject = image.get(); - cl_uint numObjects = 1; - cl_mem *memObjects = &memObject; - - cl_int result = cmdQ.enqueueAcquireSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0); - EXPECT_EQ(result, CL_SUCCESS); - image->setIsDisplayable(true); - - auto ultCsr = static_cast *>(&cmdQ.getGpgpuCommandStreamReceiver()); - ultCsr->directSubmissionAvailable = true; - ultCsr->callBaseSendRenderStateCacheFlush = false; - ultCsr->flushReturnValue = SubmissionStatus::success; - EXPECT_FALSE(ultCsr->renderStateCacheFlushed); - - result = cmdQ.enqueueReleaseSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0); - EXPECT_EQ(result, CL_SUCCESS); - EXPECT_TRUE(ultCsr->renderStateCacheFlushed); - EXPECT_TRUE(ultCsr->renderStateCacheDcFlushForced); -} - HWTEST_F(CommandQueueTests, givenDcFlushMitigationAndDirectSubmissionAndBufferWhenReleasingSharedObjectThenFlushRenderStateCacheAndForceDcFlush) { DebugManagerStateRestore restorer; debugManager.flags.AllowDcFlush.set(0); diff --git a/opencl/test/unit_test/mocks/CMakeLists.txt b/opencl/test/unit_test/mocks/CMakeLists.txt index bd9e0e1fc1..d38c60f21c 100644 --- a/opencl/test/unit_test/mocks/CMakeLists.txt +++ b/opencl/test/unit_test/mocks/CMakeLists.txt @@ -30,6 +30,7 @@ set(IGDRCL_SRCS_tests_mocks ${CMAKE_CURRENT_SOURCE_DIR}/mock_program.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_sampler.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_sharing_factory.h + ${CMAKE_CURRENT_SOURCE_DIR}/mock_sharing_handler.h ${CMAKE_CURRENT_SOURCE_DIR}/ult_cl_device_factory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ult_cl_device_factory.h ${NEO_SHARED_DIRECTORY}/gmm_helper/page_table_mngr_impl.cpp diff --git a/opencl/test/unit_test/mocks/mock_command_queue.h b/opencl/test/unit_test/mocks/mock_command_queue.h index 0d3359557e..cc2aca8b70 100644 --- a/opencl/test/unit_test/mocks/mock_command_queue.h +++ b/opencl/test/unit_test/mocks/mock_command_queue.h @@ -230,7 +230,10 @@ class MockCommandQueue : public CommandQueue { cl_int enqueueResourceBarrier(BarrierCommand *resourceBarrier, cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event) override { return CL_SUCCESS; } - cl_int finish() override { return CL_SUCCESS; } + cl_int finish() override { + ++finishCalledCount; + return CL_SUCCESS; + } cl_int flush() override { return CL_SUCCESS; } @@ -253,6 +256,7 @@ class MockCommandQueue : public CommandQueue { bool releaseIndirectHeapCalled = false; bool waitForTimestampsCalled = false; cl_int writeBufferRetValue = CL_SUCCESS; + uint32_t finishCalledCount = 0; uint32_t isCompletedCalled = 0; uint32_t writeBufferCounter = 0; bool writeBufferBlocking = false; diff --git a/opencl/test/unit_test/mocks/mock_sharing_handler.h b/opencl/test/unit_test/mocks/mock_sharing_handler.h new file mode 100644 index 0000000000..26e8285fe1 --- /dev/null +++ b/opencl/test/unit_test/mocks/mock_sharing_handler.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2024 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "opencl/source/sharings/sharing.h" + +class MockSharingHandler : public SharingHandler { + public: + void synchronizeObject(UpdateData &updateData) override { + updateData.synchronizationStatus = ACQUIRE_SUCCESFUL; + } +};