From e898b9e218676211d807fb607ad447eae485fef7 Mon Sep 17 00:00:00 2001 From: "Hoppe, Mateusz" Date: Tue, 10 Apr 2018 13:49:26 +0200 Subject: [PATCH] Source Level Debugger: SIP programming in preamble - program SIP_STATE when either MidThread preemption is enabled or kernel debugging is active - device creates correct sip based on preemption mode and active kernel debugging Change-Id: I3e43b66ad00d24c2389fa4fc766dd47044b6af80 --- runtime/command_stream/preemption.inl | 36 ++-- runtime/device/device.cpp | 7 +- runtime/device/device.h | 4 +- .../command_stream_receiver_hw_tests.cpp | 133 +------------- unit_tests/fixtures/CMakeLists.txt | 1 + .../ult_command_stream_receiver_fixture.h | 166 ++++++++++++++++++ unit_tests/gen9/CMakeLists.txt | 2 + .../gen9/command_stream_receiver_hw_tests.cpp | 94 ++++++++++ unit_tests/gen9/preamble_tests.cpp | 59 +++++++ .../libult/ult_command_stream_receiver.h | 1 + unit_tests/mocks/mock_builtins.h | 2 + unit_tests/mocks/mock_device.h | 6 +- .../source_level_debugger/CMakeLists.txt | 27 +++ .../source_level_debugger/device_tests.cpp | 87 +++++++++ .../source_level_debugger_preamble_test.h | 46 +++++ .../source_level_debugger_preamble_test.inl | 152 ++++++++++++++++ 16 files changed, 669 insertions(+), 154 deletions(-) create mode 100644 unit_tests/fixtures/ult_command_stream_receiver_fixture.h create mode 100644 unit_tests/gen9/command_stream_receiver_hw_tests.cpp create mode 100644 unit_tests/gen9/preamble_tests.cpp create mode 100644 unit_tests/source_level_debugger/CMakeLists.txt create mode 100644 unit_tests/source_level_debugger/device_tests.cpp create mode 100644 unit_tests/source_level_debugger/source_level_debugger_preamble_test.h create mode 100644 unit_tests/source_level_debugger/source_level_debugger_preamble_test.inl diff --git a/runtime/command_stream/preemption.inl b/runtime/command_stream/preemption.inl index ab4188d1d0..0409dd9988 100644 --- a/runtime/command_stream/preemption.inl +++ b/runtime/command_stream/preemption.inl @@ -76,22 +76,22 @@ void PreemptionHelper::applyPreemptionWaCmdsEnd(LinearStream *pCommandStream, co template void PreemptionHelper::programPreamble(LinearStream &preambleCmdStream, Device &device, const GraphicsAllocation *preemptionCsr) { - if (device.getPreemptionMode() != PreemptionMode::MidThread) { - return; - } - - UNRECOVERABLE_IF(nullptr == preemptionCsr); using GPGPU_CSR_BASE_ADDRESS = typename GfxFamily::GPGPU_CSR_BASE_ADDRESS; using STATE_SIP = typename GfxFamily::STATE_SIP; + bool sourceLevelDebuggerActive = device.isSourceLevelDebuggerActive(); + if (device.getPreemptionMode() == PreemptionMode::MidThread) { + UNRECOVERABLE_IF(nullptr == preemptionCsr); - auto csr = reinterpret_cast(preambleCmdStream.getSpace(sizeof(GPGPU_CSR_BASE_ADDRESS))); - csr->init(); - csr->setGpgpuCsrBaseAddress(preemptionCsr->getGpuAddressToPatch()); - - auto sip = reinterpret_cast(preambleCmdStream.getSpace(sizeof(STATE_SIP))); - sip->init(); - auto sipType = SipKernel::getSipKernelType(device.getHardwareInfo().pPlatform->eRenderCoreFamily, device.isSourceLevelDebuggerActive()); - sip->setSystemInstructionPointer(BuiltIns::getInstance().getSipKernel(sipType, device).getSipAllocation()->getGpuAddressToPatch()); + auto csr = reinterpret_cast(preambleCmdStream.getSpace(sizeof(GPGPU_CSR_BASE_ADDRESS))); + csr->init(); + csr->setGpgpuCsrBaseAddress(preemptionCsr->getGpuAddressToPatch()); + } + if (device.getPreemptionMode() == PreemptionMode::MidThread || sourceLevelDebuggerActive) { + auto sip = reinterpret_cast(preambleCmdStream.getSpace(sizeof(STATE_SIP))); + sip->init(); + auto sipType = SipKernel::getSipKernelType(device.getHardwareInfo().pPlatform->eRenderCoreFamily, sourceLevelDebuggerActive); + sip->setSystemInstructionPointer(BuiltIns::getInstance().getSipKernel(sipType, device).getSipAllocation()->getGpuAddressToPatch()); + } } template @@ -124,11 +124,15 @@ size_t PreemptionHelper::getRequiredCmdStreamSize(PreemptionMode newPreemptionMo template size_t PreemptionHelper::getRequiredPreambleSize(const Device &device) { - if (device.getPreemptionMode() != PreemptionMode::MidThread) { - return 0; + size_t size = 0; + if (device.getPreemptionMode() == PreemptionMode::MidThread) { + size += sizeof(typename GfxFamily::GPGPU_CSR_BASE_ADDRESS); + } + if (device.getPreemptionMode() == PreemptionMode::MidThread || device.isSourceLevelDebuggerActive()) { + size += sizeof(typename GfxFamily::STATE_SIP); } - return sizeof(typename GfxFamily::GPGPU_CSR_BASE_ADDRESS) + sizeof(typename GfxFamily::STATE_SIP); + return size; } template diff --git a/runtime/device/device.cpp b/runtime/device/device.cpp index 77b64036fe..669bcb4d94 100644 --- a/runtime/device/device.cpp +++ b/runtime/device/device.cpp @@ -165,7 +165,7 @@ bool Device::createDeviceImpl(const HardwareInfo *pHwInfo, outDevice.memoryManager->setForce32BitAllocations(pDevice->getDeviceInfo().force32BitAddressess); outDevice.memoryManager->device = pDevice; - if (pDevice->preemptionMode == PreemptionMode::MidThread) { + if (pDevice->preemptionMode == PreemptionMode::MidThread || pDevice->isSourceLevelDebuggerActive()) { size_t requiredSize = pHwInfo->capabilityTable.requiredPreemptionSurfaceSize; size_t alignment = 256 * MemoryConstants::kiloByte; bool uncacheable = pDevice->getWaTable()->waCSRUncachable; @@ -174,7 +174,8 @@ bool Device::createDeviceImpl(const HardwareInfo *pHwInfo, return false; } commandStreamReceiver->setPreemptionCsrAllocation(pDevice->preemptionAllocation); - BuiltIns::getInstance().getSipKernel(SipKernelType::Csr, *pDevice); + auto sipType = SipKernel::getSipKernelType(pHwInfo->pPlatform->eRenderCoreFamily, pDevice->isSourceLevelDebuggerActive()); + BuiltIns::getInstance().getSipKernel(sipType, *pDevice); } return true; @@ -255,7 +256,7 @@ GFXCORE_FAMILY Device::getRenderCoreFamily() const { return this->getHardwareInfo().pPlatform->eRenderCoreFamily; } -bool Device::isSourceLevelDebuggerActive() { +bool Device::isSourceLevelDebuggerActive() const { return deviceInfo.sourceLevelDebuggerActive; } } // namespace OCLRT diff --git a/runtime/device/device.h b/runtime/device/device.h index 924c056b08..28f35ab66e 100644 --- a/runtime/device/device.h +++ b/runtime/device/device.h @@ -133,7 +133,7 @@ class Device : public BaseObject<_cl_device_id> { std::vector simultaneousInterops; std::string deviceExtensions; bool getEnabled64kbPages(); - bool isSourceLevelDebuggerActive(); + bool isSourceLevelDebuggerActive() const; protected: Device() = delete; @@ -143,7 +143,7 @@ class Device : public BaseObject<_cl_device_id> { static bool createDeviceImpl(const HardwareInfo *pHwInfo, bool isRootDevice, Device &outDevice); static const HardwareInfo *getDeviceInitHwInfo(const HardwareInfo *pHwInfoIn); - void initializeCaps(); + MOCKABLE_VIRTUAL void initializeCaps(); void appendOSExtensions(std::string &deviceExtensions); unsigned int enabledClVersion; diff --git a/unit_tests/command_stream/command_stream_receiver_hw_tests.cpp b/unit_tests/command_stream/command_stream_receiver_hw_tests.cpp index 891904b869..f29aeef295 100644 --- a/unit_tests/command_stream/command_stream_receiver_hw_tests.cpp +++ b/unit_tests/command_stream/command_stream_receiver_hw_tests.cpp @@ -38,6 +38,7 @@ #include "unit_tests/libult/ult_command_stream_receiver.h" #include "unit_tests/fixtures/device_fixture.h" #include "unit_tests/fixtures/built_in_fixture.h" +#include "unit_tests/fixtures/ult_command_stream_receiver_fixture.h" #include "unit_tests/helpers/hw_parse.h" #include "unit_tests/helpers/debug_manager_state_restore.h" #include "unit_tests/mocks/mock_buffer.h" @@ -59,138 +60,6 @@ using namespace OCLRT; using ::testing::_; using ::testing::Invoke; -struct UltCommandStreamReceiverTest - : public DeviceFixture, - public BuiltInFixture, - public HardwareParse, - ::testing::Test { - - void SetUp() override { - DeviceFixture::SetUp(); - BuiltInFixture::SetUp(pDevice); - HardwareParse::SetUp(); - - size_t sizeStream = 256; - size_t alignmentStream = 0x1000; - cmdBuffer = alignedMalloc(sizeStream, alignmentStream); - dshBuffer = alignedMalloc(sizeStream, alignmentStream); - iohBuffer = alignedMalloc(sizeStream, alignmentStream); - sshBuffer = alignedMalloc(sizeStream, alignmentStream); - - ASSERT_NE(nullptr, cmdBuffer); - ASSERT_NE(nullptr, dshBuffer); - ASSERT_NE(nullptr, iohBuffer); - ASSERT_NE(nullptr, sshBuffer); - - commandStream.replaceBuffer(cmdBuffer, sizeStream); - auto graphicsAllocation = new GraphicsAllocation(cmdBuffer, sizeStream); - commandStream.replaceGraphicsAllocation(graphicsAllocation); - - dsh.replaceBuffer(dshBuffer, sizeStream); - graphicsAllocation = new GraphicsAllocation(dshBuffer, sizeStream); - dsh.replaceGraphicsAllocation(graphicsAllocation); - - ioh.replaceBuffer(iohBuffer, sizeStream); - - graphicsAllocation = new GraphicsAllocation(iohBuffer, sizeStream); - ioh.replaceGraphicsAllocation(graphicsAllocation); - - ssh.replaceBuffer(sshBuffer, sizeStream); - graphicsAllocation = new GraphicsAllocation(sshBuffer, sizeStream); - ssh.replaceGraphicsAllocation(graphicsAllocation); - } - - void TearDown() override { - pDevice->getCommandStreamReceiver().flushBatchedSubmissions(); - delete dsh.getGraphicsAllocation(); - delete ioh.getGraphicsAllocation(); - delete ssh.getGraphicsAllocation(); - delete commandStream.getGraphicsAllocation(); - - alignedFree(sshBuffer); - alignedFree(iohBuffer); - alignedFree(dshBuffer); - alignedFree(cmdBuffer); - HardwareParse::TearDown(); - BuiltInFixture::TearDown(); - DeviceFixture::TearDown(); - } - - template - CompletionStamp flushTask(CommandStreamReceiverType &commandStreamReceiver, - bool block = false, - size_t startOffset = 0, - bool requiresCoherency = false, - bool lowPriority = false) { - - flushTaskFlags.blocking = block; - flushTaskFlags.requiresCoherency = requiresCoherency; - flushTaskFlags.lowPriority = lowPriority; - - return commandStreamReceiver.flushTask( - commandStream, - startOffset, - dsh, - ioh, - ssh, - taskLevel, - flushTaskFlags); - } - - template - void configureCSRHeapStatesToNonDirty() { - auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver(); - commandStreamReceiver.dshState.updateAndCheck(&dsh); - commandStreamReceiver.iohState.updateAndCheck(&ioh); - commandStreamReceiver.sshState.updateAndCheck(&ssh); - } - - template - void configureCSRtoNonDirtyState() { - bool slmUsed = false; - if (DebugManager.flags.ForceSLML3Config.get()) { - slmUsed = true; - } - - uint32_t L3Config = PreambleHelper::getL3Config(*platformDevices[0], slmUsed); - - auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver(); - commandStreamReceiver.isPreambleSent = true; - commandStreamReceiver.lastPreemptionMode = pDevice->getPreemptionMode(); - commandStreamReceiver.overrideMediaVFEStateDirty(false); - commandStreamReceiver.latestSentStatelessMocsConfig = CacheSettings::l3CacheOn; - commandStreamReceiver.lastSentL3Config = L3Config; - configureCSRHeapStatesToNonDirty(); - commandStreamReceiver.taskLevel = taskLevel; - - commandStreamReceiver.requiredThreadArbitrationPolicy = PreambleHelper::getDefaultThreadArbitrationPolicy(); - commandStreamReceiver.lastSentThreadArbitrationPolicy = commandStreamReceiver.requiredThreadArbitrationPolicy; - commandStreamReceiver.lastSentCoherencyRequest = 0; - commandStreamReceiver.lastMediaSamplerConfig = 0; - } - - template - UltCommandStreamReceiver &getUltCommandStreamReceiver() { - return reinterpret_cast &>(pDevice->getCommandStreamReceiver()); - } - - DispatchFlags flushTaskFlags = {}; - uint32_t taskLevel = 42; - LinearStream commandStream; - LinearStream dsh; - LinearStream ioh; - LinearStream ssh; - - void *cmdBuffer = nullptr; - void *dshBuffer = nullptr; - void *iohBuffer = nullptr; - void *sshBuffer = nullptr; - - uint32_t latestSentDcFlushTaskCount; - uint32_t latestSentNonDcFlushTaskCount; - uint32_t dcFlushRequiredTaskCount; -}; - HWTEST_F(UltCommandStreamReceiverTest, requiredCmdSizeForPreamble) { auto expectedCmdSize = sizeof(typename FamilyType::MI_LOAD_REGISTER_IMM) + diff --git a/unit_tests/fixtures/CMakeLists.txt b/unit_tests/fixtures/CMakeLists.txt index 99a91736f1..fbdf7e3f04 100644 --- a/unit_tests/fixtures/CMakeLists.txt +++ b/unit_tests/fixtures/CMakeLists.txt @@ -49,6 +49,7 @@ set(IGDRCL_SRCS_tests_fixtures ${CMAKE_CURRENT_SOURCE_DIR}/simple_arg_fixture.h ${CMAKE_CURRENT_SOURCE_DIR}/simple_arg_kernel_fixture.h ${CMAKE_CURRENT_SOURCE_DIR}/two_walker_fixture.h + ${CMAKE_CURRENT_SOURCE_DIR}/ult_command_stream_receiver_fixture.h ) target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_fixtures}) set_property(GLOBAL PROPERTY IGDRCL_SRCS_tests_fixtures ${IGDRCL_SRCS_tests_fixtures}) \ No newline at end of file diff --git a/unit_tests/fixtures/ult_command_stream_receiver_fixture.h b/unit_tests/fixtures/ult_command_stream_receiver_fixture.h new file mode 100644 index 0000000000..903c90cb2d --- /dev/null +++ b/unit_tests/fixtures/ult_command_stream_receiver_fixture.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2018, Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once +#include "runtime/command_stream/command_stream_receiver.h" +#include "runtime/command_stream/linear_stream.h" +#include "runtime/helpers/cache_policy.h" +#include "runtime/memory_manager/graphics_allocation.h" +#include "unit_tests/fixtures/device_fixture.h" +#include "unit_tests/fixtures/built_in_fixture.h" +#include "unit_tests/helpers/hw_parse.h" +#include "unit_tests/libult/ult_command_stream_receiver.h" + +namespace OCLRT { + +struct UltCommandStreamReceiverTest + : public DeviceFixture, + public BuiltInFixture, + public HardwareParse, + ::testing::Test { + + void SetUp() override { + DeviceFixture::SetUp(); + BuiltInFixture::SetUp(pDevice); + HardwareParse::SetUp(); + + size_t sizeStream = 256; + size_t alignmentStream = 0x1000; + cmdBuffer = alignedMalloc(sizeStream, alignmentStream); + dshBuffer = alignedMalloc(sizeStream, alignmentStream); + iohBuffer = alignedMalloc(sizeStream, alignmentStream); + sshBuffer = alignedMalloc(sizeStream, alignmentStream); + + ASSERT_NE(nullptr, cmdBuffer); + ASSERT_NE(nullptr, dshBuffer); + ASSERT_NE(nullptr, iohBuffer); + ASSERT_NE(nullptr, sshBuffer); + + commandStream.replaceBuffer(cmdBuffer, sizeStream); + auto graphicsAllocation = new GraphicsAllocation(cmdBuffer, sizeStream); + commandStream.replaceGraphicsAllocation(graphicsAllocation); + + dsh.replaceBuffer(dshBuffer, sizeStream); + graphicsAllocation = new GraphicsAllocation(dshBuffer, sizeStream); + dsh.replaceGraphicsAllocation(graphicsAllocation); + + ioh.replaceBuffer(iohBuffer, sizeStream); + + graphicsAllocation = new GraphicsAllocation(iohBuffer, sizeStream); + ioh.replaceGraphicsAllocation(graphicsAllocation); + + ssh.replaceBuffer(sshBuffer, sizeStream); + graphicsAllocation = new GraphicsAllocation(sshBuffer, sizeStream); + ssh.replaceGraphicsAllocation(graphicsAllocation); + } + + void TearDown() override { + pDevice->getCommandStreamReceiver().flushBatchedSubmissions(); + delete dsh.getGraphicsAllocation(); + delete ioh.getGraphicsAllocation(); + delete ssh.getGraphicsAllocation(); + delete commandStream.getGraphicsAllocation(); + + alignedFree(sshBuffer); + alignedFree(iohBuffer); + alignedFree(dshBuffer); + alignedFree(cmdBuffer); + HardwareParse::TearDown(); + BuiltInFixture::TearDown(); + DeviceFixture::TearDown(); + } + + template + CompletionStamp flushTask(CommandStreamReceiverType &commandStreamReceiver, + bool block = false, + size_t startOffset = 0, + bool requiresCoherency = false, + bool lowPriority = false) { + + flushTaskFlags.blocking = block; + flushTaskFlags.requiresCoherency = requiresCoherency; + flushTaskFlags.lowPriority = lowPriority; + + return commandStreamReceiver.flushTask( + commandStream, + startOffset, + dsh, + ioh, + ssh, + taskLevel, + flushTaskFlags); + } + + template + void configureCSRHeapStatesToNonDirty() { + auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver(); + commandStreamReceiver.dshState.updateAndCheck(&dsh); + commandStreamReceiver.iohState.updateAndCheck(&ioh); + commandStreamReceiver.sshState.updateAndCheck(&ssh); + } + + template + void configureCSRtoNonDirtyState() { + bool slmUsed = false; + if (DebugManager.flags.ForceSLML3Config.get()) { + slmUsed = true; + } + + uint32_t L3Config = PreambleHelper::getL3Config(*platformDevices[0], slmUsed); + + auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver(); + commandStreamReceiver.isPreambleSent = true; + commandStreamReceiver.lastPreemptionMode = pDevice->getPreemptionMode(); + commandStreamReceiver.overrideMediaVFEStateDirty(false); + commandStreamReceiver.latestSentStatelessMocsConfig = CacheSettings::l3CacheOn; + commandStreamReceiver.lastSentL3Config = L3Config; + configureCSRHeapStatesToNonDirty(); + commandStreamReceiver.taskLevel = taskLevel; + + commandStreamReceiver.requiredThreadArbitrationPolicy = PreambleHelper::getDefaultThreadArbitrationPolicy(); + commandStreamReceiver.lastSentThreadArbitrationPolicy = commandStreamReceiver.requiredThreadArbitrationPolicy; + commandStreamReceiver.lastSentCoherencyRequest = 0; + commandStreamReceiver.lastMediaSamplerConfig = 0; + } + + template + UltCommandStreamReceiver &getUltCommandStreamReceiver() { + return reinterpret_cast &>(pDevice->getCommandStreamReceiver()); + } + + DispatchFlags flushTaskFlags = {}; + uint32_t taskLevel = 42; + LinearStream commandStream; + LinearStream dsh; + LinearStream ioh; + LinearStream ssh; + + void *cmdBuffer = nullptr; + void *dshBuffer = nullptr; + void *iohBuffer = nullptr; + void *sshBuffer = nullptr; + + uint32_t latestSentDcFlushTaskCount; + uint32_t latestSentNonDcFlushTaskCount; + uint32_t dcFlushRequiredTaskCount; +}; +} // namespace OCLRT diff --git a/unit_tests/gen9/CMakeLists.txt b/unit_tests/gen9/CMakeLists.txt index 880ee05924..d0a127ce88 100644 --- a/unit_tests/gen9/CMakeLists.txt +++ b/unit_tests/gen9/CMakeLists.txt @@ -22,11 +22,13 @@ if(TESTS_GEN9) set(IGDRCL_SRCS_tests_gen9 ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/coherency_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/command_stream_receiver_hw_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/enqueue_kernel.cpp ${CMAKE_CURRENT_SOURCE_DIR}/enqueue_media_kernel.cpp ${CMAKE_CURRENT_SOURCE_DIR}/hw_helper_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/image_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/kernel_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/preamble_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sampler_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sip_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_device_caps.cpp diff --git a/unit_tests/gen9/command_stream_receiver_hw_tests.cpp b/unit_tests/gen9/command_stream_receiver_hw_tests.cpp new file mode 100644 index 0000000000..a492ecd39b --- /dev/null +++ b/unit_tests/gen9/command_stream_receiver_hw_tests.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2018, Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "runtime/built_ins/built_ins.h" +#include "runtime/command_queue/command_queue_hw.h" +#include "runtime/command_stream/command_stream_receiver.h" +#include "unit_tests/fixtures/ult_command_stream_receiver_fixture.h" +#include "unit_tests/mocks/mock_graphics_allocation.h" + +#include "test.h" +using namespace OCLRT; + +GEN9TEST_F(UltCommandStreamReceiverTest, givenNotSentPreambleAndMidThreadPreemptionWhenPreambleIsProgrammedThenCorrectSipKernelGpuAddressIsProgrammed) { + using STATE_SIP = typename FamilyType::STATE_SIP; + auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver(); + commandStreamReceiver.isPreambleSent = false; + + size_t minCsrSize = pDevice->getHardwareInfo().pSysInfo->CsrSizeInMb * MemoryConstants::megaByte; + uint64_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte; + MockGraphicsAllocation csrSurface((void *)minCsrAlignment, minCsrSize); + commandStreamReceiver.setPreemptionCsrAllocation(&csrSurface); + + pDevice->setPreemptionMode(PreemptionMode::MidThread); + uint32_t newL3Config; + DispatchFlags dispatchFlags; + + auto cmdSizePreambleMidThread = getSizeRequiredPreambleCS(*pDevice); + StackVec preemptionBuffer; + preemptionBuffer.resize(cmdSizePreambleMidThread); + LinearStream preambleStream(&*preemptionBuffer.begin(), preemptionBuffer.size()); + auto sipAllocation = BuiltIns::getInstance().getSipKernel(SipKernelType::Csr, *pDevice).getSipAllocation(); + commandStreamReceiver.programPreamble(preambleStream, dispatchFlags, newL3Config); + + this->parseCommands(preambleStream); + auto itorStateSip = find(this->cmdList.begin(), this->cmdList.end()); + ASSERT_NE(this->cmdList.end(), itorStateSip); + + STATE_SIP *stateSipCmd = (STATE_SIP *)*itorStateSip; + auto sipAddress = stateSipCmd->getSystemInstructionPointer(); + EXPECT_EQ(sipAllocation->getGpuAddressToPatch(), sipAddress); +} + +GEN9TEST_F(UltCommandStreamReceiverTest, givenNotSentPreambleAndKernelDebuggingActiveWhenPreambleIsProgrammedThenCorrectSipKernelGpuAddressIsProgrammed) { + using STATE_SIP = typename FamilyType::STATE_SIP; + auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver(); + commandStreamReceiver.isPreambleSent = false; + size_t minCsrSize = pDevice->getHardwareInfo().pSysInfo->CsrSizeInMb * MemoryConstants::megaByte; + uint64_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte; + MockGraphicsAllocation csrSurface((void *)minCsrAlignment, minCsrSize); + commandStreamReceiver.setPreemptionCsrAllocation(&csrSurface); + + pDevice->setPreemptionMode(PreemptionMode::Disabled); + pDevice->setSourceLevelDebuggerActive(true); + uint32_t newL3Config; + DispatchFlags dispatchFlags; + + auto cmdSizePreambleMidThread = getSizeRequiredPreambleCS(*pDevice); + StackVec preemptionBuffer; + preemptionBuffer.resize(cmdSizePreambleMidThread); + LinearStream preambleStream(&*preemptionBuffer.begin(), preemptionBuffer.size()); + auto dbgLocalSipAllocation = BuiltIns::getInstance().getSipKernel(SipKernelType::DbgCsrLocal, *pDevice).getSipAllocation(); + auto sipAllocation = BuiltIns::getInstance().getSipKernel(SipKernelType::Csr, *pDevice).getSipAllocation(); + + ASSERT_NE(sipAllocation, dbgLocalSipAllocation); + + commandStreamReceiver.programPreamble(preambleStream, dispatchFlags, newL3Config); + + this->parseCommands(preambleStream); + auto itorStateSip = find(this->cmdList.begin(), this->cmdList.end()); + ASSERT_NE(this->cmdList.end(), itorStateSip); + + STATE_SIP *stateSipCmd = (STATE_SIP *)*itorStateSip; + auto sipAddress = stateSipCmd->getSystemInstructionPointer(); + EXPECT_EQ(dbgLocalSipAllocation->getGpuAddressToPatch(), sipAddress); +} diff --git a/unit_tests/gen9/preamble_tests.cpp b/unit_tests/gen9/preamble_tests.cpp new file mode 100644 index 0000000000..71aa0823cf --- /dev/null +++ b/unit_tests/gen9/preamble_tests.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018, Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "unit_tests/source_level_debugger/source_level_debugger_preamble_test.h" +#include "gtest/gtest.h" + +using namespace OCLRT; +typedef SKLFamily GfxFamily; + +#include "unit_tests/source_level_debugger/source_level_debugger_preamble_test.inl" + +using PreambleTestGen9 = ::testing::Test; + +GEN9TEST_F(PreambleTestGen9, givenMidThreadPreemptionAndDebuggingActiveWhenPreambleIsPrograamedThenCorrectSipKernelIsUsed) { + SourceLevelDebuggerPreambleTest::givenMidThreadPreemptionAndDebuggingActiveWhenPreambleIsPrograamedThenCorrectSipKernelIsUsedTest(); +} + +GEN9TEST_F(PreambleTestGen9, givenMidThreadPreemptionAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturned) { + SourceLevelDebuggerPreambleTest::givenMidThreadPreemptionAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest(); +} + +GEN9TEST_F(PreambleTestGen9, givenPreemptionDisabledAndDebuggingActiveWhenPreambleIsProgrammedThenCorrectSipKernelIsUsed) { + SourceLevelDebuggerPreambleTest::givenPreemptionDisabledAndDebuggingActiveWhenPreambleIsProgrammedThenCorrectSipKernelIsUsedTest(); +} + +GEN9TEST_F(PreambleTestGen9, givenPreemptionDisabledAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturned) { + SourceLevelDebuggerPreambleTest::givenPreemptionDisabledAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest(); +} + +GEN9TEST_F(PreambleTestGen9, givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleIsPrograamedThenCorrectSipKernelIsUsed) { + SourceLevelDebuggerPreambleTest::givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleIsPrograamedThenCorrectSipKernelIsUsedTest(); +} + +GEN9TEST_F(PreambleTestGen9, givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturned) { + SourceLevelDebuggerPreambleTest::givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest(); +} + +GEN9TEST_F(PreambleTestGen9, givenDisabledPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturned) { + SourceLevelDebuggerPreambleTest::givenDisabledPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest(); +} diff --git a/unit_tests/libult/ult_command_stream_receiver.h b/unit_tests/libult/ult_command_stream_receiver.h index 74a5ee05d7..64636580c6 100644 --- a/unit_tests/libult/ult_command_stream_receiver.h +++ b/unit_tests/libult/ult_command_stream_receiver.h @@ -53,6 +53,7 @@ class UltCommandStreamReceiver : public CommandStreamReceiverHw { using BaseClass::CommandStreamReceiver::requiredThreadArbitrationPolicy; using BaseClass::CommandStreamReceiver::taskCount; using BaseClass::CommandStreamReceiver::taskLevel; + using BaseClass::programPreamble; UltCommandStreamReceiver(const UltCommandStreamReceiver &) = delete; UltCommandStreamReceiver &operator=(const UltCommandStreamReceiver &) = delete; diff --git a/unit_tests/mocks/mock_builtins.h b/unit_tests/mocks/mock_builtins.h index ad33103e01..b880e2e3c5 100644 --- a/unit_tests/mocks/mock_builtins.h +++ b/unit_tests/mocks/mock_builtins.h @@ -57,6 +57,7 @@ class MockBuiltins : public OCLRT::BuiltIns { return *sipKernelsOverride[type]; } getSipKernelCalled = true; + getSipKernelType = type; return BuiltIns::getSipKernel(type, device); } @@ -67,4 +68,5 @@ class MockBuiltins : public OCLRT::BuiltIns { OCLRT::BuiltIns *originalGlobalBuiltins = nullptr; std::map> sipKernelsOverride; bool getSipKernelCalled = false; + OCLRT::SipKernelType getSipKernelType = OCLRT::SipKernelType::COUNT; }; diff --git a/unit_tests/mocks/mock_device.h b/unit_tests/mocks/mock_device.h index 10624c14f1..ffac548b3a 100644 --- a/unit_tests/mocks/mock_device.h +++ b/unit_tests/mocks/mock_device.h @@ -52,7 +52,7 @@ class MockDevice : public Device { return &this->deviceInfo; } - void initializeCaps() { + void initializeCaps() override { Device::initializeCaps(); } @@ -92,6 +92,10 @@ class MockDevice : public Device { GraphicsAllocation *getTagAllocation() { return tagAllocation; } + void setSourceLevelDebuggerActive(bool active) { + this->deviceInfo.sourceLevelDebuggerActive = active; + } + private: bool forceWhitelistedRegs = false; WhitelistedRegisters mockWhitelistedRegs = {0}; diff --git a/unit_tests/source_level_debugger/CMakeLists.txt b/unit_tests/source_level_debugger/CMakeLists.txt new file mode 100644 index 0000000000..512cea51c1 --- /dev/null +++ b/unit_tests/source_level_debugger/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright (c) 2018, Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +set(IGDRCL_SRCS_tests_source_level_debugger + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/device_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source_level_debugger_preamble_test.h + ${CMAKE_CURRENT_SOURCE_DIR}/source_level_debugger_preamble_test.inl +) +target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_source_level_debugger}) diff --git a/unit_tests/source_level_debugger/device_tests.cpp b/unit_tests/source_level_debugger/device_tests.cpp new file mode 100644 index 0000000000..20650ec120 --- /dev/null +++ b/unit_tests/source_level_debugger/device_tests.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2018, Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "unit_tests/fixtures/device_fixture.h" +#include "unit_tests/helpers/debug_manager_state_restore.h" +#include "unit_tests/mocks/mock_builtins.h" +#include "unit_tests/mocks/mock_device.h" + +#include "test.h" + +using PreambleTest = ::testing::Test; +using namespace OCLRT; + +class MockDeviceWithActiveDebugger : public MockDevice { + public: + MockDeviceWithActiveDebugger(const HardwareInfo &hwInfo, bool isRootDevice = true) : MockDevice(hwInfo, isRootDevice) {} + + void initializeCaps() override { + MockDevice::initializeCaps(); + this->setSourceLevelDebuggerActive(true); + } +}; + +TEST(DeviceCreation, givenDeviceWithMidThreadPreemptionAndDebuggingActiveWhenDeviceIsCreatedThenCorrectSipKernelIsCreated) { + + DebugManagerStateRestore dbgRestorer; + { + BuiltIns::shutDown(); + + std::unique_ptr mockBuiltins(new MockBuiltins); + EXPECT_EQ(nullptr, mockBuiltins->peekCurrentInstance()); + mockBuiltins->overrideGlobalBuiltins(); + EXPECT_EQ(mockBuiltins.get(), mockBuiltins->peekCurrentInstance()); + EXPECT_FALSE(mockBuiltins->getSipKernelCalled); + + DebugManager.flags.ForcePreemptionMode.set((int32_t)PreemptionMode::MidThread); + auto device = std::unique_ptr(Device::create(nullptr)); + + EXPECT_TRUE(mockBuiltins->getSipKernelCalled); + EXPECT_LE(SipKernelType::DbgCsr, mockBuiltins->getSipKernelType); + mockBuiltins->restoreGlobalBuiltins(); + //make sure to release builtins prior to device as they use device + mockBuiltins.reset(); + } +} + +TEST(DeviceCreation, givenDeviceWithDisabledPreemptionAndDebuggingActiveWhenDeviceIsCreatedThenCorrectSipKernelIsCreated) { + + DebugManagerStateRestore dbgRestorer; + { + BuiltIns::shutDown(); + + std::unique_ptr mockBuiltins(new MockBuiltins); + EXPECT_EQ(nullptr, mockBuiltins->peekCurrentInstance()); + mockBuiltins->overrideGlobalBuiltins(); + EXPECT_EQ(mockBuiltins.get(), mockBuiltins->peekCurrentInstance()); + EXPECT_FALSE(mockBuiltins->getSipKernelCalled); + + DebugManager.flags.ForcePreemptionMode.set((int32_t)PreemptionMode::Disabled); + auto device = std::unique_ptr(Device::create(nullptr)); + + EXPECT_TRUE(mockBuiltins->getSipKernelCalled); + EXPECT_LE(SipKernelType::DbgCsr, mockBuiltins->getSipKernelType); + mockBuiltins->restoreGlobalBuiltins(); + //make sure to release builtins prior to device as they use device + mockBuiltins.reset(); + } +} diff --git a/unit_tests/source_level_debugger/source_level_debugger_preamble_test.h b/unit_tests/source_level_debugger/source_level_debugger_preamble_test.h new file mode 100644 index 0000000000..39f16ddd79 --- /dev/null +++ b/unit_tests/source_level_debugger/source_level_debugger_preamble_test.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018, Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once +#include "runtime/built_ins/built_ins.h" +#include "runtime/command_stream/preemption.h" +#include "runtime/helpers/preamble.h" +#include "unit_tests/helpers/hw_parse.h" +#include "unit_tests/mocks/mock_device.h" +#include "unit_tests/mocks/mock_graphics_allocation.h" + +#include "test.h" +#include + +template +class SourceLevelDebuggerPreambleTest { + public: + SourceLevelDebuggerPreambleTest() {} + + static void givenMidThreadPreemptionAndDebuggingActiveWhenPreambleIsPrograamedThenCorrectSipKernelIsUsedTest(); + static void givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleIsPrograamedThenCorrectSipKernelIsUsedTest(); + static void givenPreemptionDisabledAndDebuggingActiveWhenPreambleIsProgrammedThenCorrectSipKernelIsUsedTest(); + static void givenMidThreadPreemptionAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest(); + static void givenPreemptionDisabledAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest(); + static void givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest(); + static void givenDisabledPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest(); +}; diff --git a/unit_tests/source_level_debugger/source_level_debugger_preamble_test.inl b/unit_tests/source_level_debugger/source_level_debugger_preamble_test.inl new file mode 100644 index 0000000000..0d13314223 --- /dev/null +++ b/unit_tests/source_level_debugger/source_level_debugger_preamble_test.inl @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2018, Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +using namespace OCLRT; + +template +void SourceLevelDebuggerPreambleTest::givenMidThreadPreemptionAndDebuggingActiveWhenPreambleIsPrograamedThenCorrectSipKernelIsUsedTest() { + using STATE_SIP = typename GfxFamily::STATE_SIP; + auto mockDevice = std::unique_ptr(MockDevice::create(nullptr)); + + mockDevice->setSourceLevelDebuggerActive(true); + mockDevice->setPreemptionMode(PreemptionMode::MidThread); + auto cmdSizePreemptionMidThread = PreemptionHelper::getRequiredPreambleSize(*mockDevice); + + StackVec preambleBuffer; + preambleBuffer.resize(cmdSizePreemptionMidThread); + LinearStream preambleStream(&*preambleBuffer.begin(), preambleBuffer.size()); + + uintptr_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte; + MockGraphicsAllocation csrSurface(reinterpret_cast(minCsrAlignment), 1024); + + PreemptionHelper::programPreamble(preambleStream, *mockDevice, &csrSurface); + + HardwareParse hwParser; + hwParser.parseCommands(preambleStream); + auto itorStateSip = find(hwParser.cmdList.begin(), hwParser.cmdList.end()); + ASSERT_NE(hwParser.cmdList.end(), itorStateSip); + STATE_SIP *stateSipCmd = (STATE_SIP *)*itorStateSip; + auto sipAddress = stateSipCmd->getSystemInstructionPointer(); + + auto sipType = SipKernel::getSipKernelType(mockDevice->getHardwareInfo().pPlatform->eRenderCoreFamily, mockDevice->isSourceLevelDebuggerActive()); + EXPECT_EQ(BuiltIns::getInstance().getSipKernel(sipType, *mockDevice).getSipAllocation()->getGpuAddressToPatch(), sipAddress); +} + +template +void SourceLevelDebuggerPreambleTest::givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleIsPrograamedThenCorrectSipKernelIsUsedTest() { + using STATE_SIP = typename GfxFamily::STATE_SIP; + auto mockDevice = std::unique_ptr(MockDevice::create(nullptr)); + + mockDevice->setSourceLevelDebuggerActive(false); + mockDevice->setPreemptionMode(PreemptionMode::MidThread); + auto cmdSizePreemptionMidThread = PreemptionHelper::getRequiredPreambleSize(*mockDevice); + + StackVec preambleBuffer; + preambleBuffer.resize(cmdSizePreemptionMidThread); + LinearStream preambleStream(&*preambleBuffer.begin(), preambleBuffer.size()); + + uintptr_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte; + MockGraphicsAllocation csrSurface(reinterpret_cast(minCsrAlignment), 1024); + + PreemptionHelper::programPreamble(preambleStream, *mockDevice, &csrSurface); + + HardwareParse hwParser; + hwParser.parseCommands(preambleStream); + auto itorStateSip = find(hwParser.cmdList.begin(), hwParser.cmdList.end()); + ASSERT_NE(hwParser.cmdList.end(), itorStateSip); + STATE_SIP *stateSipCmd = (STATE_SIP *)*itorStateSip; + auto sipAddress = stateSipCmd->getSystemInstructionPointer(); + + auto sipType = SipKernel::getSipKernelType(mockDevice->getHardwareInfo().pPlatform->eRenderCoreFamily, mockDevice->isSourceLevelDebuggerActive()); + EXPECT_EQ(BuiltIns::getInstance().getSipKernel(sipType, *mockDevice).getSipAllocation()->getGpuAddressToPatch(), sipAddress); +} + +template +void SourceLevelDebuggerPreambleTest::givenPreemptionDisabledAndDebuggingActiveWhenPreambleIsProgrammedThenCorrectSipKernelIsUsedTest() { + using STATE_SIP = typename GfxFamily::STATE_SIP; + auto mockDevice = std::unique_ptr(MockDevice::create(nullptr)); + + mockDevice->setSourceLevelDebuggerActive(true); + mockDevice->setPreemptionMode(PreemptionMode::Disabled); + auto cmdSizePreemptionMidThread = PreemptionHelper::getRequiredPreambleSize(*mockDevice); + + StackVec preambleBuffer; + preambleBuffer.resize(cmdSizePreemptionMidThread); + LinearStream preambleStream(&*preambleBuffer.begin(), preambleBuffer.size()); + + uintptr_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte; + MockGraphicsAllocation csrSurface(reinterpret_cast(minCsrAlignment), 1024); + + PreemptionHelper::programPreamble(preambleStream, *mockDevice, &csrSurface); + + HardwareParse hwParser; + hwParser.parseCommands(preambleStream); + auto itorStateSip = find(hwParser.cmdList.begin(), hwParser.cmdList.end()); + ASSERT_NE(hwParser.cmdList.end(), itorStateSip); + STATE_SIP *stateSipCmd = (STATE_SIP *)*itorStateSip; + auto sipAddress = stateSipCmd->getSystemInstructionPointer(); + + auto sipType = SipKernel::getSipKernelType(mockDevice->getHardwareInfo().pPlatform->eRenderCoreFamily, mockDevice->isSourceLevelDebuggerActive()); + EXPECT_EQ(BuiltIns::getInstance().getSipKernel(sipType, *mockDevice).getSipAllocation()->getGpuAddressToPatch(), sipAddress); +} + +template +void SourceLevelDebuggerPreambleTest::givenMidThreadPreemptionAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest() { + auto mockDevice = std::unique_ptr(MockDevice::create(nullptr)); + mockDevice->setSourceLevelDebuggerActive(true); + mockDevice->setPreemptionMode(PreemptionMode::MidThread); + size_t requiredPreambleSize = PreemptionHelper::getRequiredPreambleSize(*mockDevice); + auto sizeExpected = sizeof(typename GfxFamily::GPGPU_CSR_BASE_ADDRESS) + sizeof(typename GfxFamily::STATE_SIP); + EXPECT_EQ(sizeExpected, requiredPreambleSize); +} + +template +void SourceLevelDebuggerPreambleTest::givenPreemptionDisabledAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest() { + auto mockDevice = std::unique_ptr(MockDevice::create(nullptr)); + mockDevice->setSourceLevelDebuggerActive(true); + mockDevice->setPreemptionMode(PreemptionMode::Disabled); + size_t requiredPreambleSize = PreemptionHelper::getRequiredPreambleSize(*mockDevice); + auto sizeExpected = sizeof(typename GfxFamily::STATE_SIP); + EXPECT_EQ(sizeExpected, requiredPreambleSize); +} + +template +void SourceLevelDebuggerPreambleTest::givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest() { + auto mockDevice = std::unique_ptr(MockDevice::create(nullptr)); + mockDevice->setSourceLevelDebuggerActive(false); + mockDevice->setPreemptionMode(PreemptionMode::MidThread); + size_t requiredPreambleSize = PreemptionHelper::getRequiredPreambleSize(*mockDevice); + auto sizeExpected = sizeof(typename GfxFamily::GPGPU_CSR_BASE_ADDRESS) + sizeof(typename GfxFamily::STATE_SIP); + EXPECT_EQ(sizeExpected, requiredPreambleSize); +} + +template +void SourceLevelDebuggerPreambleTest::givenDisabledPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest() { + auto mockDevice = std::unique_ptr(MockDevice::create(nullptr)); + mockDevice->setSourceLevelDebuggerActive(false); + mockDevice->setPreemptionMode(PreemptionMode::Disabled); + size_t requiredPreambleSize = PreemptionHelper::getRequiredPreambleSize(*mockDevice); + size_t sizeExpected = 0u; + EXPECT_EQ(sizeExpected, requiredPreambleSize); +} + +template class SourceLevelDebuggerPreambleTest;