Track StateBaseAddresses from cmdQ and cmdList

Related-To: NEO-4637

Change-Id: Ia4b187df5f28fadf032ff24acb7ab32b05d0d261
Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:
Mateusz Hoppe
2020-07-27 17:37:51 +02:00
committed by sys_ocldev
parent 8daf71070d
commit a77f1de8a1
37 changed files with 528 additions and 47 deletions

View File

@@ -8,6 +8,7 @@ if(TESTS_GEN11)
target_sources(${TARGET_NAME} PRIVATE
${COMPUTE_RUNTIME_ULT_GEN11}
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/enable_l0_mocks_gen11.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_cmdqueue_thread_arbitration_policy_gen11.cpp
)
endif()

View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/core/test/unit_tests/mocks/mock_l0_debugger.h"
namespace NEO {
struct ICLFamily;
using GfxFamily = ICLFamily;
} // namespace NEO
namespace L0 {
namespace ult {
static MockDebuggerL0HwPopulateFactory<IGFX_GEN11_CORE, NEO::GfxFamily> mockDebuggerGen11;
}
} // namespace L0

View File

@@ -8,6 +8,7 @@ if(TESTS_GEN12LP)
target_sources(${TARGET_NAME} PRIVATE
${COMPUTE_RUNTIME_ULT_GEN12LP}
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/enable_l0_mocks_gen12lp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_device_gen12lp.cpp
)

View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/core/test/unit_tests/mocks/mock_l0_debugger.h"
namespace NEO {
struct TGLLPFamily;
using GfxFamily = TGLLPFamily;
} // namespace NEO
namespace L0 {
namespace ult {
static MockDebuggerL0HwPopulateFactory<IGFX_GEN12LP_CORE, NEO::GfxFamily> mockDebuggerGen12lp;
}
} // namespace L0

View File

@@ -8,6 +8,7 @@ if(TESTS_GEN9)
target_sources(${TARGET_NAME} PRIVATE
${COMPUTE_RUNTIME_ULT_GEN9}
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/enable_l0_mocks_gen9.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_cmdlist_append_launch_kernel_gen9.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_cmdqueue_thread_arbitration_policy_gen9.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_device_gen9.cpp

View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/core/test/unit_tests/mocks/mock_l0_debugger.h"
namespace NEO {
struct SKLFamily;
using GfxFamily = SKLFamily;
} // namespace NEO
namespace L0 {
namespace ult {
static MockDebuggerL0HwPopulateFactory<IGFX_GEN9_CORE, NEO::GfxFamily> mockDebuggerGen9;
}
} // namespace L0

View File

@@ -8,6 +8,7 @@ set(TARGET_NAME ${TARGET_NAME_L0}_mocks)
set(L0_MOCKS_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/debugger_l0_create.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_built_ins.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_built_ins.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_cmdlist.h

View File

@@ -0,0 +1,21 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/core/test/unit_tests/mocks/mock_l0_debugger.h"
namespace L0 {
namespace ult {
DebugerL0CreateFn mockDebuggerL0HwFactory[IGFX_MAX_CORE];
}
} // namespace L0
namespace L0 {
std::unique_ptr<NEO::Debugger> DebuggerL0::create(NEO::Device *device) {
return std::unique_ptr<DebuggerL0>(ult::mockDebuggerL0HwFactory[device->getHardwareInfo().platform.eRenderCoreFamily](device));
}
} // namespace L0

View File

@@ -23,6 +23,7 @@ struct WhiteBox<::L0::CommandQueue> : public ::L0::CommandQueueImp {
using BaseClass::device;
using BaseClass::printfFunctionContainer;
using BaseClass::synchronizeByPollingForTaskCount;
using CommandQueue::commandQueuePerThreadScratchSize;
WhiteBox(Device *device, NEO::CommandStreamReceiver *csr,
const ze_command_queue_desc_t *desc);

View File

@@ -10,12 +10,33 @@
namespace L0 {
namespace ult {
extern DebugerL0CreateFn mockDebuggerL0HwFactory[];
class MockDebuggerL0 : public L0::DebuggerL0 {
template <typename GfxFamily>
class MockDebuggerL0Hw : public L0::DebuggerL0Hw<GfxFamily> {
public:
using L0::DebuggerL0::DebuggerL0;
using L0::DebuggerL0::perContextSbaAllocations;
~MockDebuggerL0() override = default;
using L0::DebuggerL0::sbaTrackingGpuVa;
MockDebuggerL0Hw(NEO::Device *device) : L0::DebuggerL0Hw<GfxFamily>(device) {}
~MockDebuggerL0Hw() override = default;
static DebuggerL0 *allocate(NEO::Device *device) {
return new MockDebuggerL0Hw<GfxFamily>(device);
}
void captureStateBaseAddress(NEO::CommandContainer &container) override {
captureStateBaseAddressCount++;
L0::DebuggerL0Hw<GfxFamily>::captureStateBaseAddress(container);
}
uint32_t captureStateBaseAddressCount = 0;
};
template <uint32_t productFamily, typename GfxFamily>
struct MockDebuggerL0HwPopulateFactory {
MockDebuggerL0HwPopulateFactory() {
mockDebuggerL0HwFactory[productFamily] = MockDebuggerL0Hw<GfxFamily>::allocate;
}
};
} // namespace ult

View File

@@ -43,13 +43,14 @@ struct L0DebuggerFixture {
L0::Device *device = nullptr;
};
struct MockL0DebuggerFixture : public L0DebuggerFixture {
struct L0DebuggerHwFixture : public L0DebuggerFixture {
void SetUp() {
L0DebuggerFixture::SetUp();
mockDebugger = new MockDebuggerL0(neoDevice);
neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[neoDevice->getRootDeviceIndex()]->debugger.reset(mockDebugger);
debuggerHw = mockDebuggerL0HwFactory[neoDevice->getHardwareInfo().platform.eRenderCoreFamily](neoDevice);
neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[neoDevice->getRootDeviceIndex()]->debugger.reset(debuggerHw);
neoDevice->setDebuggerActive(true);
neoDevice->setPreemptionMode(PreemptionMode::Disabled);
auto debugSurface = neoDevice->getMemoryManager()->allocateGraphicsMemoryWithProperties(
{device->getRootDeviceIndex(), true,
NEO::SipKernel::maxDbgSurfaceSize,
@@ -62,9 +63,13 @@ struct MockL0DebuggerFixture : public L0DebuggerFixture {
void TearDown() {
L0DebuggerFixture::TearDown();
mockDebugger = nullptr;
debuggerHw = nullptr;
}
MockDebuggerL0 *mockDebugger = nullptr;
template <typename GfxFamily>
MockDebuggerL0Hw<GfxFamily> *getMockDebuggerL0Hw() {
return static_cast<MockDebuggerL0Hw<GfxFamily> *>(debuggerHw);
}
DebuggerL0 *debuggerHw = nullptr;
};
} // namespace ult

View File

@@ -7,6 +7,7 @@
#include "shared/source/command_stream/linear_stream.h"
#include "shared/source/gen_common/reg_configs/reg_configs_common.h"
#include "shared/source/gmm_helper/gmm_helper.h"
#include "shared/source/helpers/preamble.h"
#include "shared/source/os_interface/os_context.h"
#include "shared/test/unit_test/cmd_parse/gen_cmd_parse.h"
@@ -20,7 +21,7 @@
namespace L0 {
namespace ult {
using L0DebuggerTest = Test<MockL0DebuggerFixture>;
using L0DebuggerTest = Test<L0DebuggerHwFixture>;
TEST_F(L0DebuggerTest, givenL0DebuggerWhenCallingIsLegacyThenFalseIsReturned) {
EXPECT_FALSE(neoDevice->getDebugger()->isLegacy());
@@ -38,7 +39,7 @@ TEST_F(L0DebuggerTest, givenL0DebuggerWhenCallingIsDebuggerActiveThenTrueIsRetur
EXPECT_TRUE(neoDevice->getDebugger()->isDebuggerActive());
}
TEST_F(L0DebuggerTest, givenL0DebuggerWhenCreatedThenPerContextSbaTrackingBuffersAreAllocated) {
HWTEST_F(L0DebuggerTest, givenL0DebuggerWhenCreatedThenPerContextSbaTrackingBuffersAreAllocated) {
auto debugger = device->getL0Debugger();
ASSERT_NE(nullptr, debugger);
@@ -57,14 +58,14 @@ TEST_F(L0DebuggerTest, givenL0DebuggerWhenCreatedThenPerContextSbaTrackingBuffer
EXPECT_NE(allocations[i], allocations[i + 1]);
}
EXPECT_EQ(device->getNEODevice()->getEngines().size(), mockDebugger->perContextSbaAllocations.size());
EXPECT_EQ(device->getNEODevice()->getEngines().size(), getMockDebuggerL0Hw<FamilyType>()->perContextSbaAllocations.size());
}
TEST_F(L0DebuggerTest, givenCreatedL0DebuggerThenSbaTrackingBuffersContainValidHeader) {
HWTEST_F(L0DebuggerTest, givenCreatedL0DebuggerThenSbaTrackingBuffersContainValidHeader) {
auto debugger = device->getL0Debugger();
ASSERT_NE(nullptr, debugger);
for (auto &sbaBuffer : mockDebugger->perContextSbaAllocations) {
for (auto &sbaBuffer : getMockDebuggerL0Hw<FamilyType>()->perContextSbaAllocations) {
auto sbaAllocation = sbaBuffer.second;
ASSERT_NE(nullptr, sbaAllocation);
@@ -229,6 +230,93 @@ HWTEST_F(L0DebuggerTest, givenDebuggingEnabledWhenCommandListIsExecutedTwiceThen
commandQueue->destroy();
}
using NotGen8Or11 = AreNotGfxCores<IGFX_GEN8_CORE, IGFX_GEN11_CORE>;
HWTEST2_F(L0DebuggerTest, givenDebuggingEnabledAndRequiredGsbaWhenCommandListIsExecutedThenProgramGsbaWritesToSbaTrackingBuffer, NotGen8Or11) {
using MI_STORE_DATA_IMM = typename FamilyType::MI_STORE_DATA_IMM;
using STATE_BASE_ADDRESS = typename FamilyType::STATE_BASE_ADDRESS;
ze_command_queue_desc_t queueDesc = {};
auto cmdQ = CommandQueue::create(productFamily, device, neoDevice->getDefaultEngine().commandStreamReceiver, &queueDesc, false);
ASSERT_NE(nullptr, cmdQ);
auto commandQueue = whitebox_cast(cmdQ);
auto cmdQHw = static_cast<CommandQueueHw<gfxCoreFamily> *>(cmdQ);
if (cmdQHw->estimateStateBaseAddressCmdSize() == 0) {
commandQueue->destroy();
GTEST_SKIP();
}
commandQueue->commandQueuePerThreadScratchSize = 4096;
auto usedSpaceBefore = commandQueue->commandStream->getUsed();
ze_command_list_handle_t commandLists[] = {
CommandList::create(productFamily, device, false)->toHandle()};
uint32_t numCommandLists = sizeof(commandLists) / sizeof(commandLists[0]);
auto result = commandQueue->executeCommandLists(numCommandLists, commandLists, nullptr, true);
ASSERT_EQ(ZE_RESULT_SUCCESS, result);
auto usedSpaceAfter = commandQueue->commandStream->getUsed();
ASSERT_GT(usedSpaceAfter, usedSpaceBefore);
GenCmdList cmdList;
ASSERT_TRUE(FamilyType::PARSE::parseCommandBuffer(
cmdList, ptrOffset(commandQueue->commandStream->getCpuBase(), 0), usedSpaceAfter));
auto sbaItor = find<STATE_BASE_ADDRESS *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), sbaItor);
auto cmdSba = genCmdCast<STATE_BASE_ADDRESS *>(*sbaItor);
auto sdiItor = find<MI_STORE_DATA_IMM *>(sbaItor, cmdList.end());
ASSERT_NE(cmdList.end(), sdiItor);
auto cmdSdi = genCmdCast<MI_STORE_DATA_IMM *>(*sdiItor);
uint64_t gsbaGpuVa = cmdSba->getGeneralStateBaseAddress();
EXPECT_EQ(static_cast<uint32_t>(gsbaGpuVa & 0x0000FFFFFFFFULL), cmdSdi->getDataDword0());
EXPECT_EQ(static_cast<uint32_t>(gsbaGpuVa >> 32), cmdSdi->getDataDword1());
auto expectedGpuVa = GmmHelper::decanonize(device->getL0Debugger()->getSbaTrackingGpuVa()) + offsetof(SbaTrackedAddresses, GeneralStateBaseAddress);
EXPECT_EQ(expectedGpuVa, cmdSdi->getAddress());
for (auto i = 0u; i < numCommandLists; i++) {
auto commandList = CommandList::fromHandle(commandLists[i]);
commandList->destroy();
}
commandQueue->destroy();
}
HWTEST2_F(L0DebuggerTest, givenDebuggingEnabledWhenNonCopyCommandListIsInititalizedOrResetThenSSHAddressIsTracked, NotGen8Or11) {
using STATE_BASE_ADDRESS = typename FamilyType::STATE_BASE_ADDRESS;
size_t usedSpaceBefore = 0;
ze_command_list_handle_t commandListHandle = CommandList::create(productFamily, device, false)->toHandle();
auto commandList = CommandList::fromHandle(commandListHandle);
auto usedSpaceAfter = commandList->commandContainer.getCommandStream()->getUsed();
ASSERT_GT(usedSpaceAfter, usedSpaceBefore);
GenCmdList cmdList;
ASSERT_TRUE(FamilyType::PARSE::parseCommandBuffer(
cmdList, commandList->commandContainer.getCommandStream()->getCpuBase(), usedSpaceAfter));
auto sbaItor = find<STATE_BASE_ADDRESS *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), sbaItor);
auto cmdSba = genCmdCast<STATE_BASE_ADDRESS *>(*sbaItor);
uint64_t sshGpuVa = cmdSba->getSurfaceStateBaseAddress();
auto expectedGpuVa = commandList->commandContainer.getIndirectHeap(NEO::HeapType::SURFACE_STATE)->getHeapGpuBase();
EXPECT_EQ(expectedGpuVa, sshGpuVa);
EXPECT_EQ(1u, getMockDebuggerL0Hw<FamilyType>()->captureStateBaseAddressCount);
commandList->reset();
EXPECT_EQ(2u, getMockDebuggerL0Hw<FamilyType>()->captureStateBaseAddressCount);
commandList->destroy();
}
HWTEST_F(L0DebuggerTest, givenDebuggerWhenAppendingKernelToCommandListThenBindlessSurfaceStateForDebugSurfaceIsProgrammedAtOffsetZero) {
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
@@ -257,5 +345,86 @@ HWTEST_F(L0DebuggerTest, givenDebuggerWhenAppendingKernelToCommandListThenBindle
EXPECT_EQ(RENDER_SURFACE_STATE::COHERENCY_TYPE_IA_COHERENT, debugSurfaceState->getCoherencyType());
}
using L0DebuggerSimpleTest = Test<DeviceFixture>;
HWTEST_F(L0DebuggerSimpleTest, givenNonZeroGpuVasWhenProgrammingSbaTrackingThenCorrectCmdsAreAddedToStream) {
using MI_STORE_DATA_IMM = typename FamilyType::MI_STORE_DATA_IMM;
auto debugger = std::make_unique<MockDebuggerL0Hw<FamilyType>>(neoDevice);
debugger->sbaTrackingGpuVa.address = 0x45670000;
auto expectedGpuVa = debugger->sbaTrackingGpuVa.address + offsetof(SbaTrackedAddresses, GeneralStateBaseAddress);
StackVec<char, 4096> buffer(4096);
NEO::LinearStream cmdStream(buffer.begin(), buffer.size());
uint64_t gsba = 0x60000;
uint64_t ssba = 0x1234567000;
debugger->programSbaTrackingCommands(cmdStream, gsba, ssba);
GenCmdList cmdList;
ASSERT_TRUE(FamilyType::PARSE::parseCommandBuffer(cmdList, cmdStream.getCpuBase(), cmdStream.getUsed()));
EXPECT_EQ(2 * sizeof(MI_STORE_DATA_IMM), cmdStream.getUsed());
auto sdiItor = find<MI_STORE_DATA_IMM *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), sdiItor);
auto cmdSdi = genCmdCast<MI_STORE_DATA_IMM *>(*sdiItor);
EXPECT_EQ(static_cast<uint32_t>(gsba & 0x0000FFFFFFFFULL), cmdSdi->getDataDword0());
EXPECT_EQ(static_cast<uint32_t>(gsba >> 32), cmdSdi->getDataDword1());
EXPECT_EQ(expectedGpuVa, cmdSdi->getAddress());
EXPECT_TRUE(cmdSdi->getStoreQword());
sdiItor++;
cmdSdi = genCmdCast<MI_STORE_DATA_IMM *>(*sdiItor);
expectedGpuVa = debugger->sbaTrackingGpuVa.address + offsetof(SbaTrackedAddresses, SurfaceStateBaseAddress);
EXPECT_EQ(static_cast<uint32_t>(ssba & 0x0000FFFFFFFFULL), cmdSdi->getDataDword0());
EXPECT_EQ(static_cast<uint32_t>(ssba >> 32), cmdSdi->getDataDword1());
EXPECT_EQ(expectedGpuVa, cmdSdi->getAddress());
EXPECT_TRUE(cmdSdi->getStoreQword());
}
HWTEST_F(L0DebuggerSimpleTest, givenZeroGpuVasWhenProgrammingSbaTrackingThenStreamIsNotUsed) {
using MI_STORE_DATA_IMM = typename FamilyType::MI_STORE_DATA_IMM;
auto debugger = std::make_unique<MockDebuggerL0Hw<FamilyType>>(neoDevice);
debugger->sbaTrackingGpuVa.address = 0x45670000;
StackVec<char, 4096> buffer(4096);
NEO::LinearStream cmdStream(buffer.begin(), buffer.size());
uint64_t gsba = 0;
uint64_t ssba = 0;
debugger->programSbaTrackingCommands(cmdStream, gsba, ssba);
EXPECT_EQ(0u, cmdStream.getUsed());
}
HWTEST_F(L0DebuggerSimpleTest, whenAllocateCalledThenDebuggerIsCreated) {
auto debugger = DebuggerL0Hw<FamilyType>::allocate(neoDevice);
EXPECT_NE(nullptr, debugger);
delete debugger;
}
HWTEST_F(L0DebuggerSimpleTest, givenNotDirtySSHWhenCapturingSBAThenNoTrackingCmdsAreAdded) {
auto debugger = std::make_unique<MockDebuggerL0Hw<FamilyType>>(neoDevice);
debugger->sbaTrackingGpuVa.address = 0x45670000;
NEO::CommandContainer container;
container.initialize(neoDevice);
debugger->captureStateBaseAddress(container);
auto sizeUsed = container.getCommandStream()->getUsed();
EXPECT_NE(0u, sizeUsed);
container.setDirtyStateForAllHeaps(false);
debugger->captureStateBaseAddress(container);
auto sizeUsed2 = container.getCommandStream()->getUsed();
EXPECT_EQ(sizeUsed, sizeUsed2);
}
} // namespace ult
} // namespace L0