Add unit tests for completion fence

Related-To: NEO-6575

Signed-off-by: Zbigniew Zdanowicz <zbigniew.zdanowicz@intel.com>
This commit is contained in:
Zbigniew Zdanowicz
2022-01-20 11:07:57 +00:00
committed by Compute-Runtime-Automation
parent 6968bfdb33
commit ec40b6562e
13 changed files with 252 additions and 74 deletions

View File

@ -5,77 +5,20 @@
*
*/
#include "shared/source/os_interface/linux/drm_buffer_object.h"
#include "shared/source/os_interface/linux/drm_memory_operations_handler_default.h"
#include "shared/source/os_interface/linux/os_context_linux.h"
#include "shared/source/os_interface/os_interface.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/engine_descriptor_helper.h"
#include "shared/test/common/libult/linux/drm_mock.h"
#include "shared/test/common/mocks/linux/mock_drm_allocation.h"
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/mocks/mock_gmm_helper.h"
#include "shared/test/common/os_interface/linux/device_command_stream_fixture.h"
#include "shared/test/common/os_interface/linux/drm_buffer_object_fixture.h"
#include "shared/test/common/test_macros/test.h"
#include "drm/i915_drm.h"
#include <memory>
using namespace NEO;
class TestedBufferObject : public BufferObject {
public:
TestedBufferObject(Drm *drm) : BufferObject(drm, 1, 0, 1) {
}
void tileBy(uint32_t mode) {
this->tiling_mode = mode;
}
void fillExecObject(drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) override {
BufferObject::fillExecObject(execObject, osContext, vmHandleId, drmContextId);
execObjectPointerFilled = &execObject;
}
void setSize(size_t size) {
this->size = size;
}
drm_i915_gem_exec_object2 *execObjectPointerFilled = nullptr;
};
class DrmBufferObjectFixture {
public:
std::unique_ptr<DrmMockCustom> mock;
TestedBufferObject *bo;
drm_i915_gem_exec_object2 execObjectsStorage[256];
std::unique_ptr<OsContextLinux> osContext;
void SetUp() {
this->mock = std::make_unique<DrmMockCustom>(*executionEnvironment.rootDeviceEnvironments[0]);
ASSERT_NE(nullptr, this->mock);
executionEnvironment.rootDeviceEnvironments[0]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*mock.get(), 0u);
osContext.reset(new OsContextLinux(*this->mock, 0u, EngineDescriptorHelper::getDefaultDescriptor()));
this->mock->reset();
bo = new TestedBufferObject(this->mock.get());
ASSERT_NE(nullptr, bo);
}
void TearDown() {
delete bo;
if (this->mock->ioctl_expected.total >= 0) {
EXPECT_EQ(this->mock->ioctl_expected.total, this->mock->ioctl_cnt.total);
}
mock->reset();
osContext.reset(nullptr);
mock.reset(nullptr);
}
MockExecutionEnvironment executionEnvironment;
};
typedef Test<DrmBufferObjectFixture> DrmBufferObjectTest;
using DrmMockBufferObjectFixture = DrmBufferObjectFixture<DrmMockCustom>;
using DrmBufferObjectTest = Test<DrmMockBufferObjectFixture>;
TEST_F(DrmBufferObjectTest, WhenCallingExecThenReturnIsCorrect) {
mock->ioctl_expected.total = 1;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2021 Intel Corporation
* Copyright (C) 2019-2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -84,12 +84,12 @@ class DrmCommandStreamTest : public ::testing::Test {
std::unique_ptr<OsContextLinux> osContext;
};
template <typename T>
template <typename DrmType>
class DrmCommandStreamEnhancedTemplate : public ::testing::Test {
public:
std::unique_ptr<DebugManagerStateRestore> dbgState;
MockExecutionEnvironment *executionEnvironment;
T *mock;
DrmType *mock;
CommandStreamReceiver *csr = nullptr;
const uint32_t rootDeviceIndex = 0u;
@ -105,7 +105,7 @@ class DrmCommandStreamEnhancedTemplate : public ::testing::Test {
//make sure this is disabled, we don't want to test this now
DebugManager.flags.EnableForcePin.set(false);
mock = new T(*executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]);
mock = new DrmType(*executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]);
executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->osInterface = std::make_unique<OSInterface>();
executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(mock));
executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*mock, rootDeviceIndex);
@ -149,7 +149,7 @@ class DrmCommandStreamEnhancedTemplate : public ::testing::Test {
protected:
class MockBufferObject : public BufferObject {
friend DrmCommandStreamEnhancedTemplate<T>;
friend DrmCommandStreamEnhancedTemplate<DrmType>;
protected:
MockBufferObject(Drm *drm, size_t size) : BufferObject(drm, 1, 0, 16u) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2021 Intel Corporation
* Copyright (C) 2018-2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -11,16 +11,29 @@
#include "shared/source/os_interface/linux/drm_memory_operations_handler.h"
#include "shared/source/os_interface/os_interface.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/libult/linux/drm_mock.h"
#include "shared/test/common/mocks/linux/mock_drm_allocation.h"
#include "shared/test/common/mocks/linux/mock_drm_memory_manager.h"
#include "shared/test/common/mocks/mock_allocation_properties.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/os_interface/linux/device_command_stream_fixture.h"
#include "shared/test/common/os_interface/linux/drm_buffer_object_fixture.h"
#include "shared/test/common/test_macros/test.h"
#include "opencl/source/platform/platform.h"
#include "opencl/test/unit_test/os_interface/linux/drm_command_stream_fixture.h"
using namespace NEO;
class DrmCommandStreamMMTest : public ::testing::Test {
using DrmCommandStreamMMTest = ::testing::Test;
struct DrmCommandStreamMemExecTest : public DrmCommandStreamEnhancedTemplate<DrmMockCustom> {
void SetUp() override {
DrmCommandStreamEnhancedTemplate::SetUp();
}
void TearDown() override {
DrmCommandStreamEnhancedTemplate::TearDown();
}
};
HWTEST_F(DrmCommandStreamMMTest, GivenForcePinThenMemoryManagerCreatesPinBb) {
@ -81,3 +94,35 @@ HWTEST_F(DrmCommandStreamMMTest, givenExecutionEnvironmentWithMoreThanOneRootDev
EXPECT_NE(nullptr, memoryManager->pinBBs[rootDeviceIndex]);
}
}
HWTEST_TEMPLATED_F(DrmCommandStreamMemExecTest, GivenDrmSupportsCompletionFenceWhenCallingCsrExecThenTagAllocationIsPassed) {
mock->completionFenceSupported = true;
TestedBufferObject bo(mock, 128);
MockDrmAllocation cmdBuffer(GraphicsAllocation::AllocationType::COMMAND_BUFFER, MemoryPool::System4KBPages);
cmdBuffer.bufferObjects[0] = &bo;
uint8_t buff[128];
LinearStream cs(&cmdBuffer, buff, 128);
CommandStreamReceiverHw<FamilyType>::addBatchBufferEnd(cs, nullptr);
EncodeNoop<FamilyType>::alignToCacheLine(cs);
BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 0, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false};
auto allocation = mm->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), MemoryConstants::pageSize});
csr->makeResident(cmdBuffer);
csr->makeResident(*allocation);
csr->makeResident(*csr->getTagAllocation());
uint64_t expectedCompletionGpuAddress = csr->getTagAllocation()->getGpuAddress() + Drm::completionFenceOffset;
auto *testCsr = static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr);
testCsr->latestSentTaskCount = 2;
int ret = testCsr->exec(batchBuffer, 1, 2);
EXPECT_EQ(0, ret);
EXPECT_EQ(expectedCompletionGpuAddress, bo.receivedCompletionGpuAddress);
EXPECT_EQ(testCsr->latestSentTaskCount, bo.receivedCompletionValue);
mm->freeGraphicsMemory(allocation);
}

View File

@ -5796,4 +5796,85 @@ TEST(DistanceInfoTest, givenDistanceInfosWhenAssignRegionsFromDistancesThenCorre
EXPECT_EQ(0u, memoryInfo->getMemoryRegionSize(4));
}
TEST_F(DrmMemoryManagerTest, GivenEligbleAllocationTypeWhenCheckingAllocationEligbleForCompletionFenceThenReturnTrue) {
GraphicsAllocation::AllocationType validAllocations[] = {
GraphicsAllocation::AllocationType::COMMAND_BUFFER,
GraphicsAllocation::AllocationType::RING_BUFFER,
GraphicsAllocation::AllocationType::SEMAPHORE_BUFFER,
GraphicsAllocation::AllocationType::TAG_BUFFER};
for (size_t i = 0; i < 4; i++) {
EXPECT_TRUE(memoryManager->allocationTypeForCompletionFence(validAllocations[i]));
}
}
TEST_F(DrmMemoryManagerTest, GivenNotEligbleAllocationTypeWhenCheckingAllocationEligbleForCompletionFenceThenReturnFalse) {
GraphicsAllocation::AllocationType validAllocations[] = {
GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY,
GraphicsAllocation::AllocationType::CONSTANT_SURFACE,
GraphicsAllocation::AllocationType::FILL_PATTERN,
GraphicsAllocation::AllocationType::GLOBAL_SURFACE};
for (size_t i = 0; i < 4; i++) {
EXPECT_FALSE(memoryManager->allocationTypeForCompletionFence(validAllocations[i]));
}
}
TEST_F(DrmMemoryManagerTest, givenCompletionFenceEnabledWhenHandlingCompletionOfUsedAndEligbleAllocationThenCallWaitUserFence) {
mock->ioctl_expected.total = -1;
VariableBackup<bool> backupFenceSupported{&mock->completionFenceSupported, true};
VariableBackup<bool> backupVmBindCallParent{&mock->isVmBindAvailableCall.callParent, false};
VariableBackup<bool> backupVmBindReturnValue{&mock->isVmBindAvailableCall.returnValue, true};
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{rootDeviceIndex, 1024, GraphicsAllocation::AllocationType::COMMAND_BUFFER});
auto engine = memoryManager->getRegisteredEngines()[0];
allocation->updateTaskCount(2, engine.osContext->getContextId());
uint64_t expectedFenceAddress = castToUint64(const_cast<uint32_t *>(engine.commandStreamReceiver->getTagAddress())) + Drm::completionFenceOffset;
constexpr uint64_t expectedValue = 2;
memoryManager->handleFenceCompletion(allocation);
EXPECT_EQ(1u, mock->waitUserFenceCall.called);
EXPECT_EQ(expectedFenceAddress, mock->waitUserFenceCall.address);
EXPECT_EQ(expectedValue, mock->waitUserFenceCall.value);
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerTest, givenCompletionFenceEnabledWhenHandlingCompletionOfNotUsedAndEligbleAllocationThenDoNotCallWaitUserFence) {
mock->ioctl_expected.total = -1;
VariableBackup<bool> backupFenceSupported{&mock->completionFenceSupported, true};
VariableBackup<bool> backupVmBindCallParent{&mock->isVmBindAvailableCall.callParent, false};
VariableBackup<bool> backupVmBindReturnValue{&mock->isVmBindAvailableCall.returnValue, true};
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{rootDeviceIndex, 1024, GraphicsAllocation::AllocationType::COMMAND_BUFFER});
memoryManager->handleFenceCompletion(allocation);
EXPECT_EQ(0u, mock->waitUserFenceCall.called);
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerTest, givenCompletionFenceEnabledWhenHandlingCompletionOfUsedAndNotEligbleAllocationThenDoNotCallWaitUserFence) {
mock->ioctl_expected.total = -1;
VariableBackup<bool> backupFenceSupported{&mock->completionFenceSupported, true};
VariableBackup<bool> backupVmBindCallParent{&mock->isVmBindAvailableCall.callParent, false};
VariableBackup<bool> backupVmBindReturnValue{&mock->isVmBindAvailableCall.returnValue, true};
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{rootDeviceIndex, 1024, GraphicsAllocation::AllocationType::GLOBAL_SURFACE});
auto engine = memoryManager->getRegisteredEngines()[0];
allocation->updateTaskCount(2, engine.osContext->getContextId());
memoryManager->handleFenceCompletion(allocation);
EXPECT_EQ(0u, mock->waitUserFenceCall.called);
memoryManager->freeGraphicsMemory(allocation);
}
} // namespace NEO

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2021 Intel Corporation
* Copyright (C) 2018-2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -938,3 +938,20 @@ TEST(DrmQueryTest, givenUapiPrelimVersionWithInvalidPathThenReturnEmptyString) {
EXPECT_TRUE(prelimVersion.empty());
}
TEST(DrmTest, GivenCompletionFenceDebugFlagWhenCreatingDrmObjectThenExpectCorrectSetting) {
DebugManagerStateRestore restore;
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
executionEnvironment->prepareRootDeviceEnvironments(1);
DrmMock drmDefault{*executionEnvironment->rootDeviceEnvironments[0]};
EXPECT_FALSE(drmDefault.completionFenceSupported);
DebugManager.flags.EnableDrmCompletionFence.set(1);
DrmMock drmEnabled{*executionEnvironment->rootDeviceEnvironments[0]};
EXPECT_TRUE(drmEnabled.completionFenceSupported);
DebugManager.flags.EnableDrmCompletionFence.set(0);
DrmMock drmDisabled{*executionEnvironment->rootDeviceEnvironments[0]};
EXPECT_FALSE(drmDisabled.completionFenceSupported);
}