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

@ -192,6 +192,7 @@ struct CommandListCoreFamily : CommandListImp {
void appendEventForProfilingCopyCommand(ze_event_handle_t hEvent, bool beforeWalker);
void appendSignalEventPostWalker(ze_event_handle_t hEvent);
bool useMemCopyToBlitFill(size_t patternSize);
void programStateBaseAddress(NEO::CommandContainer &container);
uint64_t getInputBufferSize(NEO::ImageType imageType, uint64_t bytesPerPixel, const ze_image_region_t *region);
virtual AlignedAllocationData getAlignedAllocation(Device *device, const void *buffer, uint64_t bufferSize);

View File

@ -42,17 +42,16 @@ struct EncodeStateBaseAddress;
template <GFXCORE_FAMILY gfxCoreFamily>
bool CommandListCoreFamily<gfxCoreFamily>::initialize(Device *device, bool isCopyOnly) {
using GfxFamily = typename NEO::GfxFamilyMapper<gfxCoreFamily>::GfxFamily;
this->device = device;
this->commandListPreemptionMode = device->getDevicePreemptionMode();
this->isCopyOnlyCmdList = isCopyOnly;
if (!commandContainer.initialize(static_cast<DeviceImp *>(device)->neoDevice)) {
return false;
}
if (!isCopyOnly) {
NEO::EncodeStateBaseAddress<GfxFamily>::encode(commandContainer);
commandContainer.setDirtyStateForAllHeaps(false);
programStateBaseAddress(commandContainer);
}
this->device = device;
this->commandListPreemptionMode = device->getDevicePreemptionMode();
this->isCopyOnlyCmdList = isCopyOnly;
return true;
}
@ -1449,8 +1448,7 @@ ze_result_t CommandListCoreFamily<gfxCoreFamily>::reset() {
removeHostPtrAllocations();
commandContainer.reset();
NEO::EncodeStateBaseAddress<GfxFamily>::encode(commandContainer);
commandContainer.setDirtyStateForAllHeaps(false);
programStateBaseAddress(commandContainer);
return ZE_RESULT_SUCCESS;
}
@ -1486,4 +1484,13 @@ ze_result_t CommandListCoreFamily<gfxCoreFamily>::setGlobalWorkSizeIndirect(NEO:
return ZE_RESULT_SUCCESS;
}
template <GFXCORE_FAMILY gfxCoreFamily>
void CommandListCoreFamily<gfxCoreFamily>::programStateBaseAddress(NEO::CommandContainer &container) {
NEO::EncodeStateBaseAddress<GfxFamily>::encode(commandContainer);
if (device->getL0Debugger()) {
device->getL0Debugger()->captureStateBaseAddress(commandContainer);
}
commandContainer.setDirtyStateForAllHeaps(false);
}
} // namespace L0

View File

@ -60,6 +60,10 @@ void CommandQueueHw<gfxCoreFamily>::programGeneralStateBaseAddress(uint64_t gsba
gsbaInit = true;
if (device->getL0Debugger()) {
device->getL0Debugger()->programSbaTrackingCommands(commandStream, gsba, 0);
}
NEO::EncodeWA<GfxFamily>::encodeAdditionalPipelineSelect(*device->getNEODevice(), commandStream, false);
}
@ -70,6 +74,10 @@ size_t CommandQueueHw<gfxCoreFamily>::estimateStateBaseAddressCmdSize() {
using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL;
size_t size = sizeof(STATE_BASE_ADDRESS) + sizeof(PIPE_CONTROL) + NEO::EncodeWA<GfxFamily>::getAdditionalPipelineSelectSize(*device->getNEODevice());
if (device->getL0Debugger() != nullptr) {
size += device->getL0Debugger()->getSbaTrackingCommandsSize(1);
}
return size;
}

View File

@ -8,6 +8,7 @@ set(L0_SRCS_DEBUGGER
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/debugger_l0.cpp
${CMAKE_CURRENT_SOURCE_DIR}/debugger_l0.h
${CMAKE_CURRENT_SOURCE_DIR}/debugger_l0.inl
)
add_subdirectories()

View File

@ -7,6 +7,7 @@
#include "level_zero/core/source/debugger/debugger_l0.h"
#include "shared/source/command_container/cmdcontainer.h"
#include "shared/source/device/device.h"
#include "shared/source/helpers/constants.h"
#include "shared/source/memory_manager/allocation_properties.h"
@ -16,6 +17,9 @@
#include <cstring>
namespace L0 {
DebugerL0CreateFn debuggerL0Factory[IGFX_MAX_CORE] = {};
DebuggerL0::DebuggerL0(NEO::Device *device) : device(device) {
isLegacyMode = false;
@ -54,4 +58,12 @@ bool DebuggerL0::isDebuggerActive() {
return true;
}
void DebuggerL0::captureStateBaseAddress(NEO::CommandContainer &container) {
uint64_t ssh = 0;
if (container.isHeapDirty(NEO::HeapType::SURFACE_STATE)) {
ssh = container.getIndirectHeap(NEO::HeapType::SURFACE_STATE)->getHeapGpuBase();
}
programSbaTrackingCommands(*container.getCommandStream(), 0, ssh);
}
} // namespace L0

View File

@ -16,6 +16,7 @@
namespace NEO {
class Device;
class GraphicsAllocation;
class LinearStream;
} // namespace NEO
namespace L0 {
@ -51,10 +52,38 @@ class DebuggerL0 : public NEO::Debugger, NEO::NonCopyableOrMovableClass {
return sbaTrackingGpuVa.address;
}
void captureStateBaseAddress(NEO::CommandContainer &container) override;
virtual size_t getSbaTrackingCommandsSize(size_t trackedAddressCount) const = 0;
virtual void programSbaTrackingCommands(NEO::LinearStream &cmdStream, uint64_t generalStateGpuVa, uint64_t surfaceStateGpuVa) const = 0;
protected:
NEO::Device *device = nullptr;
NEO::GraphicsAllocation *sbaAllocation = nullptr;
std::unordered_map<uint32_t, NEO::GraphicsAllocation *> perContextSbaAllocations;
NEO::AddressRange sbaTrackingGpuVa;
};
using DebugerL0CreateFn = DebuggerL0 *(*)(NEO::Device *device);
extern DebugerL0CreateFn debuggerL0Factory[];
template <typename GfxFamily>
class DebuggerL0Hw : public DebuggerL0 {
public:
static DebuggerL0 *allocate(NEO::Device *device);
size_t getSbaTrackingCommandsSize(size_t trackedAddressCount) const override;
void programSbaTrackingCommands(NEO::LinearStream &cmdStream, uint64_t generalStateGpuVa, uint64_t surfaceStateGpuVa) const override;
protected:
DebuggerL0Hw(NEO::Device *device) : DebuggerL0(device){};
};
template <uint32_t productFamily, typename GfxFamily>
struct DebuggerL0PopulateFactory {
DebuggerL0PopulateFactory() {
debuggerL0Factory[productFamily] = DebuggerL0Hw<GfxFamily>::allocate;
}
};
} // namespace L0

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_stream/linear_stream.h"
#include "shared/source/gmm_helper/gmm_helper.h"
#include "shared/source/helpers/hw_cmds.h"
#include "level_zero/core/source/debugger/debugger_l0.h"
namespace L0 {
template <typename GfxFamily>
size_t DebuggerL0Hw<GfxFamily>::getSbaTrackingCommandsSize(size_t trackedAddressCount) const {
return trackedAddressCount * sizeof(typename GfxFamily::MI_STORE_DATA_IMM);
}
template <typename GfxFamily>
void DebuggerL0Hw<GfxFamily>::programSbaTrackingCommands(NEO::LinearStream &cmdStream, uint64_t generalStateGpuVa, uint64_t surfaceStateGpuVa) const {
using MI_STORE_DATA_IMM = typename GfxFamily::MI_STORE_DATA_IMM;
auto gpuAddress = NEO::GmmHelper::decanonize(sbaTrackingGpuVa.address);
if (generalStateGpuVa) {
MI_STORE_DATA_IMM storeDataImmediate = GfxFamily::cmdInitStoreDataImm;
storeDataImmediate.setAddress(gpuAddress + offsetof(SbaTrackedAddresses, GeneralStateBaseAddress));
storeDataImmediate.setStoreQword(true);
storeDataImmediate.setDataDword0(static_cast<uint32_t>(generalStateGpuVa & 0x0000FFFFFFFFULL));
storeDataImmediate.setDataDword1(static_cast<uint32_t>(generalStateGpuVa >> 32));
auto storeDataImmediateSpace = cmdStream.getSpaceForCmd<MI_STORE_DATA_IMM>();
*storeDataImmediateSpace = storeDataImmediate;
}
if (surfaceStateGpuVa) {
MI_STORE_DATA_IMM storeDataImmediate = GfxFamily::cmdInitStoreDataImm;
storeDataImmediate.setAddress(gpuAddress + offsetof(SbaTrackedAddresses, SurfaceStateBaseAddress));
storeDataImmediate.setStoreQword(true);
storeDataImmediate.setDataDword0(static_cast<uint32_t>(surfaceStateGpuVa & 0x0000FFFFFFFFULL));
storeDataImmediate.setDataDword1(static_cast<uint32_t>(surfaceStateGpuVa >> 32));
auto storeDataImmediateSpace = cmdStream.getSpaceForCmd<MI_STORE_DATA_IMM>();
*storeDataImmediateSpace = storeDataImmediate;
}
}
template <typename GfxFamily>
DebuggerL0 *DebuggerL0Hw<GfxFamily>::allocate(NEO::Device *device) {
return new DebuggerL0Hw<GfxFamily>(device);
}
} // namespace L0

View File

@ -1,18 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "level_zero/core/source/debugger/debugger_l0.h"
namespace L0 {
class DebuggerL0Linux : public DebuggerL0 {
public:
DebuggerL0Linux(NEO::Device *device) : DebuggerL0(device) {
}
~DebuggerL0Linux() override = default;
};
} // namespace L0

View File

@ -8,4 +8,10 @@ set(L0_SRCS_DLL
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/disallow_deferred_deleter.cpp
)
add_subdirectories()
if(WIN32)
append_sources_from_properties(L0_SRCS_DLL L0_SRCS_DLL_WINDOWS)
else()
append_sources_from_properties(L0_SRCS_DLL L0_SRCS_DLL_LINUX)
endif()
set_property(GLOBAL PROPERTY L0_SRCS_DLL ${L0_SRCS_DLL})

View File

@ -4,10 +4,9 @@
# SPDX-License-Identifier: MIT
#
set(L0_SRCS_DEBUGGER_LINUX
set(L0_SRCS_DLL_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/debugger_l0_linux.cpp
${CMAKE_CURRENT_SOURCE_DIR}/debugger_l0_linux.h
)
set_property(GLOBAL PROPERTY L0_SRCS_DEBUGGER_LINUX ${L0_SRCS_DEBUGGER_LINUX})
set_property(GLOBAL PROPERTY L0_SRCS_DLL_LINUX ${L0_SRCS_DLL_LINUX})

View File

@ -5,11 +5,11 @@
*
*/
#include "level_zero/core/source/debugger/linux/debugger_l0_linux.h"
#include "level_zero/core/source/debugger/debugger_l0.h"
namespace L0 {
std::unique_ptr<NEO::Debugger> DebuggerL0::create(NEO::Device *device) {
return std::make_unique<DebuggerL0Linux>(device);
return std::unique_ptr<DebuggerL0>(debuggerL0Factory[device->getHardwareInfo().platform.eRenderCoreFamily](device));
}
} // namespace L0

View File

@ -4,11 +4,9 @@
# SPDX-License-Identifier: MIT
#
set(L0_SRCS_DEBUGGER_WINDOWS
set(L0_SRCS_DLL_WINDOWS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/debugger_l0_windows.cpp
)
if(WIN32)
set_property(GLOBAL PROPERTY L0_SRCS_DEBUGGER_WINDOWS ${L0_SRCS_DEBUGGER_WINDOWS})
endif()
set_property(GLOBAL PROPERTY L0_SRCS_DLL_WINDOWS ${L0_SRCS_DLL_WINDOWS})

View File

@ -8,6 +8,7 @@ if(SUPPORT_GEN11)
set(HW_SOURCES_GEN11
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/cmdlist_gen11.inl
${CMAKE_CURRENT_SOURCE_DIR}/debugger_gen11.cpp
${CMAKE_CURRENT_SOURCE_DIR}/enable_family_full_l0_gen11.cpp
)
add_subdirectories()

View File

@ -0,0 +1,18 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/core/source/debugger/debugger_l0.inl"
namespace NEO {
struct ICLFamily;
using GfxFamily = ICLFamily;
} // namespace NEO
namespace L0 {
template class DebuggerL0Hw<NEO::GfxFamily>;
static DebuggerL0PopulateFactory<IGFX_GEN11_CORE, NEO::GfxFamily> debuggerGen11;
} // namespace L0

View File

@ -8,6 +8,7 @@ if(SUPPORT_GEN12LP)
set(HW_SOURCES_GEN12LP
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/cmdlist_gen12lp.h
${CMAKE_CURRENT_SOURCE_DIR}/debugger_gen12lp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/definitions${BRANCH_DIR_SUFFIX}/cache_flush_gen12lp.inl
${CMAKE_CURRENT_SOURCE_DIR}/enable_family_full_l0_gen12lp.cpp
)

View File

@ -0,0 +1,18 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/core/source/debugger/debugger_l0.inl"
namespace NEO {
struct TGLLPFamily;
using GfxFamily = TGLLPFamily;
} // namespace NEO
namespace L0 {
template class DebuggerL0Hw<NEO::GfxFamily>;
static DebuggerL0PopulateFactory<IGFX_GEN12LP_CORE, NEO::GfxFamily> debuggerGen12lp;
} // namespace L0

View File

@ -7,6 +7,7 @@
if(SUPPORT_GEN8)
set(HW_SOURCES_GEN8
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/debugger_gen8.cpp
${CMAKE_CURRENT_SOURCE_DIR}/enable_family_full_l0_gen8.cpp
)

View File

@ -0,0 +1,19 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/core/source/debugger/debugger_l0.inl"
namespace NEO {
struct BDWFamily;
using GfxFamily = BDWFamily;
} // namespace NEO
namespace L0 {
template class DebuggerL0Hw<NEO::GfxFamily>;
} // namespace L0

View File

@ -8,6 +8,7 @@ if(SUPPORT_GEN9)
set(HW_SOURCES_GEN9
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/cmdlist_gen9.inl
${CMAKE_CURRENT_SOURCE_DIR}/debugger_gen9.cpp
${CMAKE_CURRENT_SOURCE_DIR}/enable_family_full_l0_gen9.cpp
)

View File

@ -0,0 +1,18 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/core/source/debugger/debugger_l0.inl"
namespace NEO {
struct SKLFamily;
using GfxFamily = SKLFamily;
} // namespace NEO
namespace L0 {
template class DebuggerL0Hw<NEO::GfxFamily>;
static DebuggerL0PopulateFactory<IGFX_GEN9_CORE, NEO::GfxFamily> debuggerGen9;
} // namespace L0

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

View File

@ -5,6 +5,7 @@
*
*/
#include "shared/source/command_container/cmdcontainer.h"
#include "shared/source/device/device.h"
#include "shared/source/os_interface/os_interface.h"
#include "shared/source/source_level_debugger/source_level_debugger.h"
@ -601,3 +602,15 @@ TEST(SourceLevelDebugger, givenMultipleRootDevicesWhenTheyAreCreatedTheyUseDedic
EXPECT_NE(sourceLevelDebugger, device2->getDebugger());
}
}
TEST(SourceLevelDebugger, whenCaptureSBACalledThenNoCommandsAreAddedToStream) {
ExecutionEnvironment *executionEnvironment = platform()->peekExecutionEnvironment();
auto device = std::unique_ptr<Device>(Device::create<MockDevice>(executionEnvironment, 0u));
MockSourceLevelDebugger debugger;
CommandContainer container;
container.initialize(device.get());
debugger.captureStateBaseAddress(container);
EXPECT_EQ(0u, container.getCommandStream()->getUsed());
}

View File

@ -9,13 +9,16 @@
#include <memory>
namespace NEO {
struct HardwareInfo;
class CommandContainer;
class IndirectHeap;
class Debugger {
public:
static std::unique_ptr<Debugger> create(HardwareInfo *hwInfo);
virtual ~Debugger() = default;
virtual bool isDebuggerActive() = 0;
bool isLegacy() const { return isLegacyMode; }
virtual void captureStateBaseAddress(CommandContainer &container) = 0;
void *getDebugSurfaceReservedSurfaceState(IndirectHeap &ssh);

View File

@ -31,6 +31,8 @@ class SourceLevelDebugger : public Debugger {
MOCKABLE_VIRTUAL bool notifyKernelDebugData(const DebugData *debugData, const std::string &name, const void *isa, size_t isaSize) const;
MOCKABLE_VIRTUAL bool initialize(bool useLocalMemory);
void captureStateBaseAddress(CommandContainer &container) override{};
protected:
class SourceLevelDebuggerInterface;
SourceLevelDebuggerInterface *sourceLevelDebuggerInterface = nullptr;

View File

@ -997,6 +997,14 @@ struct IsGfxCore {
}
};
template <GFXCORE_FAMILY gfxCoreFamily, GFXCORE_FAMILY gfxCoreFamily2>
struct AreNotGfxCores {
template <PRODUCT_FAMILY productFamily>
static constexpr bool isMatched() {
return NEO::ToGfxCoreFamily<productFamily>::get() != gfxCoreFamily && NEO::ToGfxCoreFamily<productFamily>::get() != gfxCoreFamily2;
}
};
template <GFXCORE_FAMILY gfxCoreFamily>
struct IsAtMostGfxCore {
template <PRODUCT_FAMILY productFamily>