mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-08 22:12:59 +08:00
Enhance GPU breakpoint capabilities
Change-Id: Id28afb7ab584eeb5063c7311fed41d7a31edbec7 Signed-off-by: Bartosz Dunajski <bartosz.dunajski@intel.com>
This commit is contained in:
committed by
sys_ocldev
parent
8d0df0c8a7
commit
f92f01e190
@@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "shared/source/helpers/pause_on_gpu_properties.h"
|
||||||
#include "shared/source/memory_manager/internal_allocation_storage.h"
|
#include "shared/source/memory_manager/internal_allocation_storage.h"
|
||||||
|
|
||||||
#include "opencl/source/command_queue/gpgpu_walker.h"
|
#include "opencl/source/command_queue/gpgpu_walker.h"
|
||||||
@@ -121,7 +122,10 @@ void HardwareInterface<GfxFamily>::dispatchWalker(
|
|||||||
DEBUG_BREAK_IF(offsetInterfaceDescriptorTable % 64 != 0);
|
DEBUG_BREAK_IF(offsetInterfaceDescriptorTable % 64 != 0);
|
||||||
|
|
||||||
dispatchProfilingPerfStartCommands(hwTimeStamps, hwPerfCounter, commandStream, commandQueue);
|
dispatchProfilingPerfStartCommands(hwTimeStamps, hwPerfCounter, commandStream, commandQueue);
|
||||||
dispatchDebugPauseCommands(commandStream, commandQueue, DebugPauseState::waitingForUserStartConfirmation, DebugPauseState::hasUserStartConfirmation);
|
|
||||||
|
if (PauseOnGpuProperties::pauseModeAllowed(DebugManager.flags.PauseOnEnqueue.get(), commandQueue.getGpgpuCommandStreamReceiver().peekTaskCount(), PauseOnGpuProperties::PauseMode::BeforeWorkload)) {
|
||||||
|
dispatchDebugPauseCommands(commandStream, commandQueue, DebugPauseState::waitingForUserStartConfirmation, DebugPauseState::hasUserStartConfirmation);
|
||||||
|
}
|
||||||
|
|
||||||
size_t currentDispatchIndex = 0;
|
size_t currentDispatchIndex = 0;
|
||||||
for (auto &dispatchInfo : multiDispatchInfo) {
|
for (auto &dispatchInfo : multiDispatchInfo) {
|
||||||
@@ -144,7 +148,10 @@ void HardwareInterface<GfxFamily>::dispatchWalker(
|
|||||||
HardwareCommandsHelper<GfxFamily>::programCacheFlushAfterWalkerCommand(commandStream, commandQueue, mainKernel, postSyncAddress);
|
HardwareCommandsHelper<GfxFamily>::programCacheFlushAfterWalkerCommand(commandStream, commandQueue, mainKernel, postSyncAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatchDebugPauseCommands(commandStream, commandQueue, DebugPauseState::waitingForUserEndConfirmation, DebugPauseState::hasUserEndConfirmation);
|
if (PauseOnGpuProperties::pauseModeAllowed(DebugManager.flags.PauseOnEnqueue.get(), commandQueue.getGpgpuCommandStreamReceiver().peekTaskCount(), PauseOnGpuProperties::PauseMode::AfterWorkload)) {
|
||||||
|
dispatchDebugPauseCommands(commandStream, commandQueue, DebugPauseState::waitingForUserEndConfirmation, DebugPauseState::hasUserEndConfirmation);
|
||||||
|
}
|
||||||
|
|
||||||
dispatchProfilingPerfEndCommands(hwTimeStamps, hwPerfCounter, commandStream, commandQueue);
|
dispatchProfilingPerfEndCommands(hwTimeStamps, hwPerfCounter, commandStream, commandQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,8 +290,7 @@ inline void HardwareInterface<GfxFamily>::dispatchDebugPauseCommands(
|
|||||||
DebugPauseState confirmationTrigger,
|
DebugPauseState confirmationTrigger,
|
||||||
DebugPauseState waitCondition) {
|
DebugPauseState waitCondition) {
|
||||||
|
|
||||||
if (static_cast<int32_t>(commandQueue.getGpgpuCommandStreamReceiver().peekTaskCount()) == DebugManager.flags.PauseOnEnqueue.get() &&
|
if (!commandQueue.isSpecial()) {
|
||||||
!commandQueue.isSpecial()) {
|
|
||||||
auto address = commandQueue.getGpgpuCommandStreamReceiver().getDebugPauseStateGPUAddress();
|
auto address = commandQueue.getGpgpuCommandStreamReceiver().getDebugPauseStateGPUAddress();
|
||||||
{
|
{
|
||||||
using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL;
|
using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "shared/source/helpers/pause_on_gpu_properties.h"
|
||||||
#include "shared/source/helpers/vec.h"
|
#include "shared/source/helpers/vec.h"
|
||||||
#include "shared/test/unit_test/cmd_parse/hw_parse.h"
|
#include "shared/test/unit_test/cmd_parse/hw_parse.h"
|
||||||
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
|
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
|
||||||
@@ -863,84 +864,219 @@ HWTEST_TEMPLATED_F(BlitEnqueueWithNoTimestampPacketTests, givenNoTimestampPacket
|
|||||||
verifySemaphore<FamilyType>(cmdFound, bcsSignalAddress);
|
verifySemaphore<FamilyType>(cmdFound, bcsSignalAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
using BlitEnqueueWithDebugCapabilityTests = BlitEnqueueTests<0>;
|
struct BlitEnqueueWithDebugCapabilityTests : public BlitEnqueueTests<0> {
|
||||||
|
template <typename MI_SEMAPHORE_WAIT>
|
||||||
|
void findSemaphores(GenCmdList &cmdList) {
|
||||||
|
auto semaphore = find<MI_SEMAPHORE_WAIT *>(cmdList.begin(), cmdList.end());
|
||||||
|
|
||||||
|
while (semaphore != cmdList.end()) {
|
||||||
|
auto semaphoreCmd = genCmdCast<MI_SEMAPHORE_WAIT *>(*semaphore);
|
||||||
|
if (static_cast<uint32_t>(DebugPauseState::hasUserStartConfirmation) == semaphoreCmd->getSemaphoreDataDword() &&
|
||||||
|
debugPauseStateAddress == semaphoreCmd->getSemaphoreGraphicsAddress()) {
|
||||||
|
|
||||||
|
EXPECT_EQ(MI_SEMAPHORE_WAIT::COMPARE_OPERATION::COMPARE_OPERATION_SAD_EQUAL_SDD, semaphoreCmd->getCompareOperation());
|
||||||
|
EXPECT_EQ(MI_SEMAPHORE_WAIT::WAIT_MODE::WAIT_MODE_POLLING_MODE, semaphoreCmd->getWaitMode());
|
||||||
|
|
||||||
|
semaphoreBeforeCopyFound++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static_cast<uint32_t>(DebugPauseState::hasUserEndConfirmation) == semaphoreCmd->getSemaphoreDataDword() &&
|
||||||
|
debugPauseStateAddress == semaphoreCmd->getSemaphoreGraphicsAddress()) {
|
||||||
|
|
||||||
|
EXPECT_EQ(MI_SEMAPHORE_WAIT::COMPARE_OPERATION::COMPARE_OPERATION_SAD_EQUAL_SDD, semaphoreCmd->getCompareOperation());
|
||||||
|
EXPECT_EQ(MI_SEMAPHORE_WAIT::WAIT_MODE::WAIT_MODE_POLLING_MODE, semaphoreCmd->getWaitMode());
|
||||||
|
|
||||||
|
semaphoreAfterCopyFound++;
|
||||||
|
}
|
||||||
|
|
||||||
|
semaphore = find<MI_SEMAPHORE_WAIT *>(++semaphore, cmdList.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename MI_FLUSH_DW>
|
||||||
|
void findMiFlushes(GenCmdList &cmdList) {
|
||||||
|
auto miFlush = find<MI_FLUSH_DW *>(cmdList.begin(), cmdList.end());
|
||||||
|
|
||||||
|
while (miFlush != cmdList.end()) {
|
||||||
|
auto miFlushCmd = genCmdCast<MI_FLUSH_DW *>(*miFlush);
|
||||||
|
if (static_cast<uint32_t>(DebugPauseState::waitingForUserStartConfirmation) == miFlushCmd->getImmediateData() &&
|
||||||
|
debugPauseStateAddress == miFlushCmd->getDestinationAddress()) {
|
||||||
|
|
||||||
|
EXPECT_EQ(MI_FLUSH_DW::POST_SYNC_OPERATION_WRITE_IMMEDIATE_DATA_QWORD, miFlushCmd->getPostSyncOperation());
|
||||||
|
|
||||||
|
miFlushBeforeCopyFound++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static_cast<uint32_t>(DebugPauseState::waitingForUserEndConfirmation) == miFlushCmd->getImmediateData() &&
|
||||||
|
debugPauseStateAddress == miFlushCmd->getDestinationAddress()) {
|
||||||
|
|
||||||
|
EXPECT_EQ(MI_FLUSH_DW::POST_SYNC_OPERATION_WRITE_IMMEDIATE_DATA_QWORD, miFlushCmd->getPostSyncOperation());
|
||||||
|
|
||||||
|
miFlushAfterCopyFound++;
|
||||||
|
}
|
||||||
|
|
||||||
|
miFlush = find<MI_FLUSH_DW *>(++miFlush, cmdList.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t semaphoreBeforeCopyFound = 0;
|
||||||
|
uint32_t semaphoreAfterCopyFound = 0;
|
||||||
|
uint32_t miFlushBeforeCopyFound = 0;
|
||||||
|
uint32_t miFlushAfterCopyFound = 0;
|
||||||
|
|
||||||
|
ReleaseableObjectPtr<Buffer> buffer;
|
||||||
|
uint64_t debugPauseStateAddress = 0;
|
||||||
|
int hostPtr = 0;
|
||||||
|
};
|
||||||
|
|
||||||
HWTEST_TEMPLATED_F(BlitEnqueueWithDebugCapabilityTests, givenDebugFlagSetWhenDispatchingBlitEnqueueThenAddPausingCommands) {
|
HWTEST_TEMPLATED_F(BlitEnqueueWithDebugCapabilityTests, givenDebugFlagSetWhenDispatchingBlitEnqueueThenAddPausingCommands) {
|
||||||
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
||||||
using MI_FLUSH_DW = typename FamilyType::MI_FLUSH_DW;
|
using MI_FLUSH_DW = typename FamilyType::MI_FLUSH_DW;
|
||||||
|
|
||||||
DebugManager.flags.PauseOnBlitCopy.set(1);
|
|
||||||
|
|
||||||
auto ultBcsCsr = static_cast<UltCommandStreamReceiver<FamilyType> *>(bcsCsr);
|
auto ultBcsCsr = static_cast<UltCommandStreamReceiver<FamilyType> *>(bcsCsr);
|
||||||
|
|
||||||
auto debugPauseStateAddress = ultBcsCsr->getDebugPauseStateGPUAddress();
|
debugPauseStateAddress = ultBcsCsr->getDebugPauseStateGPUAddress();
|
||||||
|
|
||||||
auto buffer = createBuffer(1, false);
|
buffer = createBuffer(1, false);
|
||||||
buffer->forceDisallowCPUCopy = true;
|
buffer->forceDisallowCPUCopy = true;
|
||||||
int hostPtr = 0;
|
|
||||||
|
DebugManager.flags.PauseOnBlitCopy.set(1);
|
||||||
|
|
||||||
commandQueue->enqueueWriteBuffer(buffer.get(), true, 0, 1, &hostPtr, nullptr, 0, nullptr, nullptr);
|
commandQueue->enqueueWriteBuffer(buffer.get(), true, 0, 1, &hostPtr, nullptr, 0, nullptr, nullptr);
|
||||||
commandQueue->enqueueWriteBuffer(buffer.get(), true, 0, 1, &hostPtr, nullptr, 0, nullptr, nullptr);
|
commandQueue->enqueueWriteBuffer(buffer.get(), true, 0, 1, &hostPtr, nullptr, 0, nullptr, nullptr);
|
||||||
|
|
||||||
HardwareParse hwParser;
|
HardwareParse hwParser;
|
||||||
hwParser.parseCommands<FamilyType>(ultBcsCsr->commandStream);
|
hwParser.parseCommands<FamilyType>(ultBcsCsr->commandStream);
|
||||||
auto &cmdList = hwParser.cmdList;
|
|
||||||
|
|
||||||
auto semaphore = find<MI_SEMAPHORE_WAIT *>(cmdList.begin(), cmdList.end());
|
findSemaphores<MI_SEMAPHORE_WAIT>(hwParser.cmdList);
|
||||||
bool semaphoreBeforeCopyFound = false;
|
|
||||||
bool semaphoreAfterCopyFound = false;
|
|
||||||
while (semaphore != cmdList.end()) {
|
|
||||||
auto semaphoreCmd = genCmdCast<MI_SEMAPHORE_WAIT *>(*semaphore);
|
|
||||||
if (static_cast<uint32_t>(DebugPauseState::hasUserStartConfirmation) == semaphoreCmd->getSemaphoreDataDword()) {
|
|
||||||
EXPECT_EQ(debugPauseStateAddress, semaphoreCmd->getSemaphoreGraphicsAddress());
|
|
||||||
EXPECT_EQ(MI_SEMAPHORE_WAIT::COMPARE_OPERATION::COMPARE_OPERATION_SAD_EQUAL_SDD, semaphoreCmd->getCompareOperation());
|
|
||||||
EXPECT_EQ(MI_SEMAPHORE_WAIT::WAIT_MODE::WAIT_MODE_POLLING_MODE, semaphoreCmd->getWaitMode());
|
|
||||||
|
|
||||||
semaphoreBeforeCopyFound = true;
|
EXPECT_EQ(1u, semaphoreBeforeCopyFound);
|
||||||
}
|
EXPECT_EQ(1u, semaphoreAfterCopyFound);
|
||||||
|
|
||||||
if (static_cast<uint32_t>(DebugPauseState::hasUserEndConfirmation) == semaphoreCmd->getSemaphoreDataDword()) {
|
findMiFlushes<MI_FLUSH_DW>(hwParser.cmdList);
|
||||||
EXPECT_TRUE(semaphoreBeforeCopyFound);
|
|
||||||
EXPECT_EQ(debugPauseStateAddress, semaphoreCmd->getSemaphoreGraphicsAddress());
|
|
||||||
EXPECT_EQ(MI_SEMAPHORE_WAIT::COMPARE_OPERATION::COMPARE_OPERATION_SAD_EQUAL_SDD, semaphoreCmd->getCompareOperation());
|
|
||||||
EXPECT_EQ(MI_SEMAPHORE_WAIT::WAIT_MODE::WAIT_MODE_POLLING_MODE, semaphoreCmd->getWaitMode());
|
|
||||||
|
|
||||||
semaphoreAfterCopyFound = true;
|
EXPECT_EQ(1u, miFlushBeforeCopyFound);
|
||||||
break;
|
EXPECT_EQ(1u, miFlushAfterCopyFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
semaphore = find<MI_SEMAPHORE_WAIT *>(++semaphore, cmdList.end());
|
HWTEST_TEMPLATED_F(BlitEnqueueWithDebugCapabilityTests, givenDebugFlagSetToMinusTwoWhenDispatchingBlitEnqueueThenAddPausingCommandsForEachEnqueue) {
|
||||||
}
|
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
||||||
|
using MI_FLUSH_DW = typename FamilyType::MI_FLUSH_DW;
|
||||||
|
|
||||||
EXPECT_TRUE(semaphoreAfterCopyFound);
|
auto ultBcsCsr = static_cast<UltCommandStreamReceiver<FamilyType> *>(bcsCsr);
|
||||||
|
|
||||||
auto miFlush = find<MI_FLUSH_DW *>(cmdList.begin(), cmdList.end());
|
debugPauseStateAddress = ultBcsCsr->getDebugPauseStateGPUAddress();
|
||||||
bool miFlushBeforeCopyFound = false;
|
|
||||||
bool miFlushAfterCopyFound = false;
|
|
||||||
while (miFlush != cmdList.end()) {
|
|
||||||
auto miFlushCmd = genCmdCast<MI_FLUSH_DW *>(*miFlush);
|
|
||||||
if (static_cast<uint32_t>(DebugPauseState::waitingForUserStartConfirmation) == miFlushCmd->getImmediateData() &&
|
|
||||||
debugPauseStateAddress == miFlushCmd->getDestinationAddress()) {
|
|
||||||
|
|
||||||
EXPECT_EQ(MI_FLUSH_DW::POST_SYNC_OPERATION_WRITE_IMMEDIATE_DATA_QWORD, miFlushCmd->getPostSyncOperation());
|
buffer = createBuffer(1, false);
|
||||||
|
buffer->forceDisallowCPUCopy = true;
|
||||||
|
|
||||||
miFlushBeforeCopyFound = true;
|
DebugManager.flags.PauseOnBlitCopy.set(-2);
|
||||||
}
|
|
||||||
|
|
||||||
if (static_cast<uint32_t>(DebugPauseState::waitingForUserEndConfirmation) == miFlushCmd->getImmediateData() &&
|
commandQueue->enqueueWriteBuffer(buffer.get(), true, 0, 1, &hostPtr, nullptr, 0, nullptr, nullptr);
|
||||||
debugPauseStateAddress == miFlushCmd->getDestinationAddress()) {
|
commandQueue->enqueueWriteBuffer(buffer.get(), true, 0, 1, &hostPtr, nullptr, 0, nullptr, nullptr);
|
||||||
EXPECT_TRUE(miFlushBeforeCopyFound);
|
|
||||||
|
|
||||||
EXPECT_EQ(MI_FLUSH_DW::POST_SYNC_OPERATION_WRITE_IMMEDIATE_DATA_QWORD, miFlushCmd->getPostSyncOperation());
|
HardwareParse hwParser;
|
||||||
|
hwParser.parseCommands<FamilyType>(ultBcsCsr->commandStream);
|
||||||
|
|
||||||
miFlushAfterCopyFound = true;
|
findSemaphores<MI_SEMAPHORE_WAIT>(hwParser.cmdList);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
miFlush = find<MI_FLUSH_DW *>(++miFlush, cmdList.end());
|
EXPECT_EQ(2u, semaphoreBeforeCopyFound);
|
||||||
}
|
EXPECT_EQ(2u, semaphoreAfterCopyFound);
|
||||||
|
|
||||||
EXPECT_TRUE(miFlushAfterCopyFound);
|
findMiFlushes<MI_FLUSH_DW>(hwParser.cmdList);
|
||||||
|
|
||||||
|
EXPECT_EQ(2u, miFlushBeforeCopyFound);
|
||||||
|
EXPECT_EQ(2u, miFlushAfterCopyFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
HWTEST_TEMPLATED_F(BlitEnqueueWithDebugCapabilityTests, givenPauseModeSetToBeforeOnlyWhenDispatchingBlitEnqueueThenAddPauseCommandsOnlyBeforeEnqueue) {
|
||||||
|
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
||||||
|
using MI_FLUSH_DW = typename FamilyType::MI_FLUSH_DW;
|
||||||
|
|
||||||
|
auto ultBcsCsr = static_cast<UltCommandStreamReceiver<FamilyType> *>(bcsCsr);
|
||||||
|
|
||||||
|
debugPauseStateAddress = ultBcsCsr->getDebugPauseStateGPUAddress();
|
||||||
|
|
||||||
|
buffer = createBuffer(1, false);
|
||||||
|
buffer->forceDisallowCPUCopy = true;
|
||||||
|
|
||||||
|
DebugManager.flags.PauseOnBlitCopy.set(0);
|
||||||
|
DebugManager.flags.PauseOnGpuMode.set(PauseOnGpuProperties::PauseMode::BeforeWorkload);
|
||||||
|
|
||||||
|
commandQueue->enqueueWriteBuffer(buffer.get(), true, 0, 1, &hostPtr, nullptr, 0, nullptr, nullptr);
|
||||||
|
|
||||||
|
HardwareParse hwParser;
|
||||||
|
hwParser.parseCommands<FamilyType>(ultBcsCsr->commandStream);
|
||||||
|
|
||||||
|
findSemaphores<MI_SEMAPHORE_WAIT>(hwParser.cmdList);
|
||||||
|
|
||||||
|
EXPECT_EQ(1u, semaphoreBeforeCopyFound);
|
||||||
|
EXPECT_EQ(0u, semaphoreAfterCopyFound);
|
||||||
|
|
||||||
|
findMiFlushes<MI_FLUSH_DW>(hwParser.cmdList);
|
||||||
|
|
||||||
|
EXPECT_EQ(1u, miFlushBeforeCopyFound);
|
||||||
|
EXPECT_EQ(0u, miFlushAfterCopyFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
HWTEST_TEMPLATED_F(BlitEnqueueWithDebugCapabilityTests, givenPauseModeSetToAfterOnlyWhenDispatchingBlitEnqueueThenAddPauseCommandsOnlyAfterEnqueue) {
|
||||||
|
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
||||||
|
using MI_FLUSH_DW = typename FamilyType::MI_FLUSH_DW;
|
||||||
|
|
||||||
|
auto ultBcsCsr = static_cast<UltCommandStreamReceiver<FamilyType> *>(bcsCsr);
|
||||||
|
|
||||||
|
debugPauseStateAddress = ultBcsCsr->getDebugPauseStateGPUAddress();
|
||||||
|
|
||||||
|
buffer = createBuffer(1, false);
|
||||||
|
buffer->forceDisallowCPUCopy = true;
|
||||||
|
|
||||||
|
DebugManager.flags.PauseOnBlitCopy.set(0);
|
||||||
|
DebugManager.flags.PauseOnGpuMode.set(PauseOnGpuProperties::PauseMode::AfterWorkload);
|
||||||
|
|
||||||
|
commandQueue->enqueueWriteBuffer(buffer.get(), true, 0, 1, &hostPtr, nullptr, 0, nullptr, nullptr);
|
||||||
|
|
||||||
|
HardwareParse hwParser;
|
||||||
|
hwParser.parseCommands<FamilyType>(ultBcsCsr->commandStream);
|
||||||
|
|
||||||
|
findSemaphores<MI_SEMAPHORE_WAIT>(hwParser.cmdList);
|
||||||
|
|
||||||
|
EXPECT_EQ(0u, semaphoreBeforeCopyFound);
|
||||||
|
EXPECT_EQ(1u, semaphoreAfterCopyFound);
|
||||||
|
|
||||||
|
findMiFlushes<MI_FLUSH_DW>(hwParser.cmdList);
|
||||||
|
|
||||||
|
EXPECT_EQ(0u, miFlushBeforeCopyFound);
|
||||||
|
EXPECT_EQ(1u, miFlushAfterCopyFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
HWTEST_TEMPLATED_F(BlitEnqueueWithDebugCapabilityTests, givenPauseModeSetToBeforeAndAfterWorkloadWhenDispatchingBlitEnqueueThenAddPauseCommandsAroundEnqueue) {
|
||||||
|
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
||||||
|
using MI_FLUSH_DW = typename FamilyType::MI_FLUSH_DW;
|
||||||
|
|
||||||
|
auto ultBcsCsr = static_cast<UltCommandStreamReceiver<FamilyType> *>(bcsCsr);
|
||||||
|
|
||||||
|
debugPauseStateAddress = ultBcsCsr->getDebugPauseStateGPUAddress();
|
||||||
|
|
||||||
|
buffer = createBuffer(1, false);
|
||||||
|
buffer->forceDisallowCPUCopy = true;
|
||||||
|
|
||||||
|
DebugManager.flags.PauseOnBlitCopy.set(0);
|
||||||
|
DebugManager.flags.PauseOnGpuMode.set(PauseOnGpuProperties::PauseMode::BeforeAndAfterWorkload);
|
||||||
|
|
||||||
|
commandQueue->enqueueWriteBuffer(buffer.get(), true, 0, 1, &hostPtr, nullptr, 0, nullptr, nullptr);
|
||||||
|
|
||||||
|
HardwareParse hwParser;
|
||||||
|
hwParser.parseCommands<FamilyType>(ultBcsCsr->commandStream);
|
||||||
|
|
||||||
|
findSemaphores<MI_SEMAPHORE_WAIT>(hwParser.cmdList);
|
||||||
|
|
||||||
|
EXPECT_EQ(1u, semaphoreBeforeCopyFound);
|
||||||
|
EXPECT_EQ(1u, semaphoreAfterCopyFound);
|
||||||
|
|
||||||
|
findMiFlushes<MI_FLUSH_DW>(hwParser.cmdList);
|
||||||
|
|
||||||
|
EXPECT_EQ(1u, miFlushBeforeCopyFound);
|
||||||
|
EXPECT_EQ(1u, miFlushAfterCopyFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
HWTEST_TEMPLATED_F(BlitEnqueueWithDebugCapabilityTests, givenDebugFlagSetWhenCreatingCsrThenCreateDebugThread) {
|
HWTEST_TEMPLATED_F(BlitEnqueueWithDebugCapabilityTests, givenDebugFlagSetWhenCreatingCsrThenCreateDebugThread) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "shared/source/helpers/pause_on_gpu_properties.h"
|
||||||
#include "shared/test/unit_test/cmd_parse/hw_parse.h"
|
#include "shared/test/unit_test/cmd_parse/hw_parse.h"
|
||||||
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
|
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
|
||||||
|
|
||||||
@@ -1291,151 +1292,240 @@ HWTEST_F(EnqueueKernelTest, whenEnqueueKernelWithEngineHintsThenEpilogRequiredIs
|
|||||||
EXPECT_EQ(csr.recordedDispatchFlags.engineHints, 1u);
|
EXPECT_EQ(csr.recordedDispatchFlags.engineHints, 1u);
|
||||||
}
|
}
|
||||||
|
|
||||||
HWTEST_F(EnqueueKernelTest, givenPauseOnEnqueueFlagSetWhenDispatchWalkersThenInsertPauseCommandsAroundSpecifiedEnqueue) {
|
struct PauseOnGpuTests : public EnqueueKernelTest {
|
||||||
using WALKER_TYPE = typename FamilyType::WALKER_TYPE;
|
void SetUp() override {
|
||||||
|
EnqueueKernelTest::SetUp();
|
||||||
|
|
||||||
|
auto &csr = pDevice->getGpgpuCommandStreamReceiver();
|
||||||
|
debugPauseStateAddress = csr.getDebugPauseStateGPUAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename MI_SEMAPHORE_WAIT>
|
||||||
|
bool verifySemaphore(const GenCmdList::iterator &iterator, uint64_t debugPauseStateAddress, DebugPauseState requiredDebugPauseState) {
|
||||||
|
auto semaphoreCmd = genCmdCast<MI_SEMAPHORE_WAIT *>(*iterator);
|
||||||
|
|
||||||
|
if ((static_cast<uint32_t>(requiredDebugPauseState) == semaphoreCmd->getSemaphoreDataDword()) &&
|
||||||
|
(debugPauseStateAddress == semaphoreCmd->getSemaphoreGraphicsAddress())) {
|
||||||
|
|
||||||
|
EXPECT_EQ(MI_SEMAPHORE_WAIT::COMPARE_OPERATION::COMPARE_OPERATION_SAD_EQUAL_SDD, semaphoreCmd->getCompareOperation());
|
||||||
|
EXPECT_EQ(MI_SEMAPHORE_WAIT::WAIT_MODE::WAIT_MODE_POLLING_MODE, semaphoreCmd->getWaitMode());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PIPE_CONTROL>
|
||||||
|
bool verifyPipeControl(const GenCmdList::iterator &iterator, uint64_t debugPauseStateAddress, DebugPauseState requiredDebugPauseState) {
|
||||||
|
auto pipeControlCmd = genCmdCast<PIPE_CONTROL *>(*iterator);
|
||||||
|
|
||||||
|
if ((static_cast<uint32_t>(requiredDebugPauseState) == pipeControlCmd->getImmediateData()) &&
|
||||||
|
(static_cast<uint32_t>(debugPauseStateAddress & 0x0000FFFFFFFFULL) == pipeControlCmd->getAddress()) &&
|
||||||
|
(static_cast<uint32_t>(debugPauseStateAddress >> 32) == pipeControlCmd->getAddressHigh())) {
|
||||||
|
|
||||||
|
EXPECT_TRUE(pipeControlCmd->getCommandStreamerStallEnable());
|
||||||
|
EXPECT_TRUE(pipeControlCmd->getDcFlushEnable());
|
||||||
|
|
||||||
|
EXPECT_EQ(PIPE_CONTROL::POST_SYNC_OPERATION::POST_SYNC_OPERATION_WRITE_IMMEDIATE_DATA, pipeControlCmd->getPostSyncOperation());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename MI_SEMAPHORE_WAIT>
|
||||||
|
void findSemaphores(GenCmdList &cmdList) {
|
||||||
|
auto semaphore = find<MI_SEMAPHORE_WAIT *>(cmdList.begin(), cmdList.end());
|
||||||
|
|
||||||
|
while (semaphore != cmdList.end()) {
|
||||||
|
if (verifySemaphore<MI_SEMAPHORE_WAIT>(semaphore, debugPauseStateAddress, DebugPauseState::hasUserStartConfirmation)) {
|
||||||
|
semaphoreBeforeWalkerFound++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verifySemaphore<MI_SEMAPHORE_WAIT>(semaphore, debugPauseStateAddress, DebugPauseState::hasUserEndConfirmation)) {
|
||||||
|
semaphoreAfterWalkerFound++;
|
||||||
|
}
|
||||||
|
|
||||||
|
semaphore = find<MI_SEMAPHORE_WAIT *>(++semaphore, cmdList.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PIPE_CONTROL>
|
||||||
|
void findPipeControls(GenCmdList &cmdList) {
|
||||||
|
auto pipeControl = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
|
||||||
|
|
||||||
|
while (pipeControl != cmdList.end()) {
|
||||||
|
if (verifyPipeControl<PIPE_CONTROL>(pipeControl, debugPauseStateAddress, DebugPauseState::waitingForUserStartConfirmation)) {
|
||||||
|
pipeControlBeforeWalkerFound++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verifyPipeControl<PIPE_CONTROL>(pipeControl, debugPauseStateAddress, DebugPauseState::waitingForUserEndConfirmation)) {
|
||||||
|
pipeControlAfterWalkerFound++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeControl = find<PIPE_CONTROL *>(++pipeControl, cmdList.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugManagerStateRestore restore;
|
||||||
|
|
||||||
|
const size_t off[3] = {0, 0, 0};
|
||||||
|
const size_t gws[3] = {1, 1, 1};
|
||||||
|
|
||||||
|
uint64_t debugPauseStateAddress = 0;
|
||||||
|
|
||||||
|
uint32_t semaphoreBeforeWalkerFound = 0;
|
||||||
|
uint32_t semaphoreAfterWalkerFound = 0;
|
||||||
|
uint32_t pipeControlBeforeWalkerFound = 0;
|
||||||
|
uint32_t pipeControlAfterWalkerFound = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
HWTEST_F(PauseOnGpuTests, givenPauseOnEnqueueFlagSetWhenDispatchWalkersThenInsertPauseCommandsAroundSpecifiedEnqueue) {
|
||||||
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
||||||
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
|
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
|
||||||
DebugManagerStateRestore restore;
|
|
||||||
DebugManager.flags.PauseOnEnqueue.set(1);
|
DebugManager.flags.PauseOnEnqueue.set(1);
|
||||||
|
|
||||||
auto &csr = pDevice->getGpgpuCommandStreamReceiver();
|
|
||||||
auto debugPauseStateAddress = csr.getDebugPauseStateGPUAddress();
|
|
||||||
|
|
||||||
MockKernelWithInternals mockKernel(*pClDevice);
|
MockKernelWithInternals mockKernel(*pClDevice);
|
||||||
|
|
||||||
size_t off[3] = {0, 0, 0};
|
|
||||||
size_t gws[3] = {1, 1, 1};
|
|
||||||
|
|
||||||
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
|
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
|
||||||
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
|
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
|
||||||
|
|
||||||
HardwareParse hwParser;
|
HardwareParse hwParser;
|
||||||
hwParser.parseCommands<FamilyType>(*pCmdQ);
|
hwParser.parseCommands<FamilyType>(*pCmdQ);
|
||||||
auto &cmdList = hwParser.cmdList;
|
|
||||||
|
|
||||||
auto semaphore = find<MI_SEMAPHORE_WAIT *>(cmdList.begin(), cmdList.end());
|
findSemaphores<MI_SEMAPHORE_WAIT>(hwParser.cmdList);
|
||||||
bool semaphoreBeforeWalkerFound = false;
|
|
||||||
bool semaphoreAfterWalkerFound = false;
|
|
||||||
while (semaphore != cmdList.end()) {
|
|
||||||
auto semaphoreCmd = genCmdCast<MI_SEMAPHORE_WAIT *>(*semaphore);
|
|
||||||
if (static_cast<uint32_t>(DebugPauseState::hasUserStartConfirmation) == semaphoreCmd->getSemaphoreDataDword()) {
|
|
||||||
EXPECT_EQ(debugPauseStateAddress, semaphoreCmd->getSemaphoreGraphicsAddress());
|
|
||||||
EXPECT_EQ(MI_SEMAPHORE_WAIT::COMPARE_OPERATION::COMPARE_OPERATION_SAD_EQUAL_SDD, semaphoreCmd->getCompareOperation());
|
|
||||||
EXPECT_EQ(MI_SEMAPHORE_WAIT::WAIT_MODE::WAIT_MODE_POLLING_MODE, semaphoreCmd->getWaitMode());
|
|
||||||
|
|
||||||
semaphoreBeforeWalkerFound = true;
|
EXPECT_EQ(1u, semaphoreBeforeWalkerFound);
|
||||||
}
|
EXPECT_EQ(1u, semaphoreAfterWalkerFound);
|
||||||
|
|
||||||
if (static_cast<uint32_t>(DebugPauseState::hasUserEndConfirmation) == semaphoreCmd->getSemaphoreDataDword()) {
|
findPipeControls<PIPE_CONTROL>(hwParser.cmdList);
|
||||||
EXPECT_TRUE(semaphoreBeforeWalkerFound);
|
|
||||||
EXPECT_EQ(debugPauseStateAddress, semaphoreCmd->getSemaphoreGraphicsAddress());
|
|
||||||
EXPECT_EQ(MI_SEMAPHORE_WAIT::COMPARE_OPERATION::COMPARE_OPERATION_SAD_EQUAL_SDD, semaphoreCmd->getCompareOperation());
|
|
||||||
EXPECT_EQ(MI_SEMAPHORE_WAIT::WAIT_MODE::WAIT_MODE_POLLING_MODE, semaphoreCmd->getWaitMode());
|
|
||||||
|
|
||||||
semaphoreAfterWalkerFound = true;
|
EXPECT_EQ(1u, pipeControlBeforeWalkerFound);
|
||||||
break;
|
EXPECT_EQ(1u, pipeControlAfterWalkerFound);
|
||||||
}
|
|
||||||
|
|
||||||
semaphore = find<MI_SEMAPHORE_WAIT *>(++semaphore, cmdList.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_TRUE(semaphoreAfterWalkerFound);
|
|
||||||
|
|
||||||
auto pipeControl = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
|
|
||||||
bool pipeControlBeforeWalkerFound = false;
|
|
||||||
bool pipeControlAfterWalkerFound = false;
|
|
||||||
while (pipeControl != cmdList.end()) {
|
|
||||||
auto pipeControlCmd = genCmdCast<PIPE_CONTROL *>(*pipeControl);
|
|
||||||
if (static_cast<uint32_t>(DebugPauseState::waitingForUserStartConfirmation) == pipeControlCmd->getImmediateData()) {
|
|
||||||
EXPECT_TRUE(pipeControlCmd->getCommandStreamerStallEnable());
|
|
||||||
EXPECT_TRUE(pipeControlCmd->getDcFlushEnable());
|
|
||||||
EXPECT_EQ(static_cast<uint32_t>(debugPauseStateAddress & 0x0000FFFFFFFFULL), pipeControlCmd->getAddress());
|
|
||||||
EXPECT_EQ(static_cast<uint32_t>(debugPauseStateAddress >> 32), pipeControlCmd->getAddressHigh());
|
|
||||||
EXPECT_EQ(PIPE_CONTROL::POST_SYNC_OPERATION::POST_SYNC_OPERATION_WRITE_IMMEDIATE_DATA, pipeControlCmd->getPostSyncOperation());
|
|
||||||
|
|
||||||
pipeControlBeforeWalkerFound = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (static_cast<uint32_t>(DebugPauseState::waitingForUserEndConfirmation) == pipeControlCmd->getImmediateData()) {
|
|
||||||
EXPECT_TRUE(pipeControlBeforeWalkerFound);
|
|
||||||
EXPECT_TRUE(pipeControlCmd->getCommandStreamerStallEnable());
|
|
||||||
EXPECT_TRUE(pipeControlCmd->getDcFlushEnable());
|
|
||||||
EXPECT_EQ(static_cast<uint32_t>(debugPauseStateAddress & 0x0000FFFFFFFFULL), pipeControlCmd->getAddress());
|
|
||||||
EXPECT_EQ(static_cast<uint32_t>(debugPauseStateAddress >> 32), pipeControlCmd->getAddressHigh());
|
|
||||||
EXPECT_EQ(PIPE_CONTROL::POST_SYNC_OPERATION::POST_SYNC_OPERATION_WRITE_IMMEDIATE_DATA, pipeControlCmd->getPostSyncOperation());
|
|
||||||
|
|
||||||
pipeControlAfterWalkerFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pipeControl = find<PIPE_CONTROL *>(++pipeControl, cmdList.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_TRUE(pipeControlAfterWalkerFound);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HWTEST_F(EnqueueKernelTest, givenPauseOnEnqueueFlagSetWhenDispatchWalkersThenDontInsertPauseCommandsWhenUsingSpecialQueue) {
|
HWTEST_F(PauseOnGpuTests, givenPauseOnEnqueueFlagSetToMinusTwoWhenDispatchWalkersThenInsertPauseCommandsAroundEachEnqueue) {
|
||||||
using WALKER_TYPE = typename FamilyType::WALKER_TYPE;
|
|
||||||
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
||||||
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
|
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
|
||||||
DebugManagerStateRestore restore;
|
|
||||||
DebugManager.flags.PauseOnEnqueue.set(0);
|
|
||||||
|
|
||||||
auto &csr = pDevice->getGpgpuCommandStreamReceiver();
|
DebugManager.flags.PauseOnEnqueue.set(-2);
|
||||||
auto debugPauseStateAddress = csr.getDebugPauseStateGPUAddress();
|
|
||||||
|
MockKernelWithInternals mockKernel(*pClDevice);
|
||||||
|
|
||||||
|
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
|
||||||
|
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
|
||||||
|
|
||||||
|
HardwareParse hwParser;
|
||||||
|
hwParser.parseCommands<FamilyType>(*pCmdQ);
|
||||||
|
|
||||||
|
findSemaphores<MI_SEMAPHORE_WAIT>(hwParser.cmdList);
|
||||||
|
|
||||||
|
findPipeControls<PIPE_CONTROL>(hwParser.cmdList);
|
||||||
|
|
||||||
|
EXPECT_EQ(2u, semaphoreBeforeWalkerFound);
|
||||||
|
EXPECT_EQ(2u, semaphoreAfterWalkerFound);
|
||||||
|
EXPECT_EQ(2u, pipeControlBeforeWalkerFound);
|
||||||
|
EXPECT_EQ(2u, pipeControlAfterWalkerFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
HWTEST_F(PauseOnGpuTests, givenPauseModeSetToBeforeOnlyWhenDispatchingThenInsertPauseOnlyBeforeEnqueue) {
|
||||||
|
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
||||||
|
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
|
||||||
|
|
||||||
|
DebugManager.flags.PauseOnEnqueue.set(0);
|
||||||
|
DebugManager.flags.PauseOnGpuMode.set(PauseOnGpuProperties::PauseMode::BeforeWorkload);
|
||||||
|
|
||||||
|
MockKernelWithInternals mockKernel(*pClDevice);
|
||||||
|
|
||||||
|
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
|
||||||
|
|
||||||
|
HardwareParse hwParser;
|
||||||
|
hwParser.parseCommands<FamilyType>(*pCmdQ);
|
||||||
|
|
||||||
|
findSemaphores<MI_SEMAPHORE_WAIT>(hwParser.cmdList);
|
||||||
|
|
||||||
|
findPipeControls<PIPE_CONTROL>(hwParser.cmdList);
|
||||||
|
|
||||||
|
EXPECT_EQ(1u, semaphoreBeforeWalkerFound);
|
||||||
|
EXPECT_EQ(0u, semaphoreAfterWalkerFound);
|
||||||
|
EXPECT_EQ(1u, pipeControlBeforeWalkerFound);
|
||||||
|
EXPECT_EQ(0u, pipeControlAfterWalkerFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
HWTEST_F(PauseOnGpuTests, givenPauseModeSetToAfterOnlyWhenDispatchingThenInsertPauseOnlyAfterEnqueue) {
|
||||||
|
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
||||||
|
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
|
||||||
|
|
||||||
|
DebugManager.flags.PauseOnEnqueue.set(0);
|
||||||
|
DebugManager.flags.PauseOnGpuMode.set(PauseOnGpuProperties::PauseMode::AfterWorkload);
|
||||||
|
|
||||||
|
MockKernelWithInternals mockKernel(*pClDevice);
|
||||||
|
|
||||||
|
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
|
||||||
|
|
||||||
|
HardwareParse hwParser;
|
||||||
|
hwParser.parseCommands<FamilyType>(*pCmdQ);
|
||||||
|
|
||||||
|
findSemaphores<MI_SEMAPHORE_WAIT>(hwParser.cmdList);
|
||||||
|
|
||||||
|
findPipeControls<PIPE_CONTROL>(hwParser.cmdList);
|
||||||
|
|
||||||
|
EXPECT_EQ(0u, semaphoreBeforeWalkerFound);
|
||||||
|
EXPECT_EQ(1u, semaphoreAfterWalkerFound);
|
||||||
|
EXPECT_EQ(0u, pipeControlBeforeWalkerFound);
|
||||||
|
EXPECT_EQ(1u, pipeControlAfterWalkerFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
HWTEST_F(PauseOnGpuTests, givenPauseModeSetToBeforeAndAfterWhenDispatchingThenInsertPauseAroundEnqueue) {
|
||||||
|
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
||||||
|
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
|
||||||
|
|
||||||
|
DebugManager.flags.PauseOnEnqueue.set(0);
|
||||||
|
DebugManager.flags.PauseOnGpuMode.set(PauseOnGpuProperties::PauseMode::BeforeAndAfterWorkload);
|
||||||
|
|
||||||
|
MockKernelWithInternals mockKernel(*pClDevice);
|
||||||
|
|
||||||
|
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
|
||||||
|
|
||||||
|
HardwareParse hwParser;
|
||||||
|
hwParser.parseCommands<FamilyType>(*pCmdQ);
|
||||||
|
|
||||||
|
findSemaphores<MI_SEMAPHORE_WAIT>(hwParser.cmdList);
|
||||||
|
|
||||||
|
findPipeControls<PIPE_CONTROL>(hwParser.cmdList);
|
||||||
|
|
||||||
|
EXPECT_EQ(1u, semaphoreBeforeWalkerFound);
|
||||||
|
EXPECT_EQ(1u, semaphoreAfterWalkerFound);
|
||||||
|
EXPECT_EQ(1u, pipeControlBeforeWalkerFound);
|
||||||
|
EXPECT_EQ(1u, pipeControlAfterWalkerFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
HWTEST_F(PauseOnGpuTests, givenPauseOnEnqueueFlagSetWhenDispatchWalkersThenDontInsertPauseCommandsWhenUsingSpecialQueue) {
|
||||||
|
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
|
||||||
|
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
|
||||||
|
|
||||||
|
DebugManager.flags.PauseOnEnqueue.set(0);
|
||||||
|
|
||||||
pCmdQ->setIsSpecialCommandQueue(true);
|
pCmdQ->setIsSpecialCommandQueue(true);
|
||||||
|
|
||||||
MockKernelWithInternals mockKernel(*pClDevice);
|
MockKernelWithInternals mockKernel(*pClDevice);
|
||||||
|
|
||||||
size_t off[3] = {0, 0, 0};
|
|
||||||
size_t gws[3] = {1, 1, 1};
|
|
||||||
|
|
||||||
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
|
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
|
||||||
|
|
||||||
HardwareParse hwParser;
|
HardwareParse hwParser;
|
||||||
hwParser.parseCommands<FamilyType>(*pCmdQ);
|
hwParser.parseCommands<FamilyType>(*pCmdQ);
|
||||||
auto &cmdList = hwParser.cmdList;
|
|
||||||
|
|
||||||
auto semaphore = find<MI_SEMAPHORE_WAIT *>(cmdList.begin(), cmdList.end());
|
findSemaphores<MI_SEMAPHORE_WAIT>(hwParser.cmdList);
|
||||||
bool semaphoreBeforeWalkerFound = false;
|
|
||||||
bool semaphoreAfterWalkerFound = false;
|
|
||||||
while (semaphore != cmdList.end()) {
|
|
||||||
auto semaphoreCmd = genCmdCast<MI_SEMAPHORE_WAIT *>(*semaphore);
|
|
||||||
if (static_cast<uint32_t>(DebugPauseState::hasUserStartConfirmation) == semaphoreCmd->getSemaphoreDataDword() &&
|
|
||||||
debugPauseStateAddress == semaphoreCmd->getSemaphoreGraphicsAddress()) {
|
|
||||||
semaphoreBeforeWalkerFound = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (static_cast<uint32_t>(DebugPauseState::hasUserEndConfirmation) == semaphoreCmd->getSemaphoreDataDword() &&
|
findPipeControls<PIPE_CONTROL>(hwParser.cmdList);
|
||||||
debugPauseStateAddress == semaphoreCmd->getSemaphoreGraphicsAddress()) {
|
|
||||||
semaphoreAfterWalkerFound = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
semaphore = find<MI_SEMAPHORE_WAIT *>(++semaphore, cmdList.end());
|
EXPECT_EQ(0u, semaphoreBeforeWalkerFound);
|
||||||
}
|
EXPECT_EQ(0u, semaphoreAfterWalkerFound);
|
||||||
|
EXPECT_EQ(0u, pipeControlBeforeWalkerFound);
|
||||||
EXPECT_FALSE(semaphoreBeforeWalkerFound);
|
EXPECT_EQ(0u, pipeControlAfterWalkerFound);
|
||||||
EXPECT_FALSE(semaphoreAfterWalkerFound);
|
|
||||||
|
|
||||||
auto pipeControl = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
|
|
||||||
bool pipeControlBeforeWalkerFound = false;
|
|
||||||
bool pipeControlAfterWalkerFound = false;
|
|
||||||
while (pipeControl != cmdList.end()) {
|
|
||||||
auto pipeControlCmd = genCmdCast<PIPE_CONTROL *>(*pipeControl);
|
|
||||||
if (static_cast<uint32_t>(DebugPauseState::waitingForUserStartConfirmation) == pipeControlCmd->getImmediateData()) {
|
|
||||||
pipeControlBeforeWalkerFound = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (static_cast<uint32_t>(DebugPauseState::waitingForUserEndConfirmation) == pipeControlCmd->getImmediateData()) {
|
|
||||||
pipeControlAfterWalkerFound = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pipeControl = find<PIPE_CONTROL *>(++pipeControl, cmdList.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_FALSE(pipeControlBeforeWalkerFound);
|
|
||||||
EXPECT_FALSE(pipeControlAfterWalkerFound);
|
|
||||||
|
|
||||||
pCmdQ->setIsSpecialCommandQueue(false);
|
pCmdQ->setIsSpecialCommandQueue(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -194,4 +194,5 @@ EnableUsmCompression = -1
|
|||||||
PerformImplicitFlushEveryEnqueueCount = -1
|
PerformImplicitFlushEveryEnqueueCount = -1
|
||||||
PerformImplicitFlushForNewResource = -1
|
PerformImplicitFlushForNewResource = -1
|
||||||
PerformImplicitFlushForIdleGpu = -1
|
PerformImplicitFlushForIdleGpu = -1
|
||||||
ProvideVerboseImplicitFlush = false
|
ProvideVerboseImplicitFlush = false
|
||||||
|
PauseOnGpuMode = -1
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "shared/source/helpers/flat_batch_buffer_helper_hw.h"
|
#include "shared/source/helpers/flat_batch_buffer_helper_hw.h"
|
||||||
#include "shared/source/helpers/flush_stamp.h"
|
#include "shared/source/helpers/flush_stamp.h"
|
||||||
#include "shared/source/helpers/hw_helper.h"
|
#include "shared/source/helpers/hw_helper.h"
|
||||||
|
#include "shared/source/helpers/pause_on_gpu_properties.h"
|
||||||
#include "shared/source/helpers/preamble.h"
|
#include "shared/source/helpers/preamble.h"
|
||||||
#include "shared/source/helpers/ptr_math.h"
|
#include "shared/source/helpers/ptr_math.h"
|
||||||
#include "shared/source/helpers/state_base_address.h"
|
#include "shared/source/helpers/state_base_address.h"
|
||||||
@@ -930,15 +931,13 @@ uint32_t CommandStreamReceiverHw<GfxFamily>::blitBuffer(const BlitPropertiesCont
|
|||||||
|
|
||||||
auto lock = obtainUniqueOwnership();
|
auto lock = obtainUniqueOwnership();
|
||||||
|
|
||||||
bool pauseOnBlitCopyAllowed = (DebugManager.flags.PauseOnBlitCopy.get() == static_cast<int32_t>(taskCount));
|
auto &commandStream = getCS(BlitCommandsHelper<GfxFamily>::estimateBlitCommandsSize(blitPropertiesContainer, profilingEnabled, PauseOnGpuProperties::featureEnabled(DebugManager.flags.PauseOnBlitCopy.get()),
|
||||||
|
|
||||||
auto &commandStream = getCS(BlitCommandsHelper<GfxFamily>::estimateBlitCommandsSize(blitPropertiesContainer, profilingEnabled, pauseOnBlitCopyAllowed,
|
|
||||||
*this->executionEnvironment.rootDeviceEnvironments[this->rootDeviceIndex]));
|
*this->executionEnvironment.rootDeviceEnvironments[this->rootDeviceIndex]));
|
||||||
auto commandStreamStart = commandStream.getUsed();
|
auto commandStreamStart = commandStream.getUsed();
|
||||||
auto newTaskCount = taskCount + 1;
|
auto newTaskCount = taskCount + 1;
|
||||||
latestSentTaskCount = newTaskCount;
|
latestSentTaskCount = newTaskCount;
|
||||||
|
|
||||||
if (pauseOnBlitCopyAllowed) {
|
if (PauseOnGpuProperties::pauseModeAllowed(DebugManager.flags.PauseOnBlitCopy.get(), taskCount, PauseOnGpuProperties::PauseMode::BeforeWorkload)) {
|
||||||
BlitCommandsHelper<GfxFamily>::dispatchDebugPauseCommands(commandStream, getDebugPauseStateGPUAddress(), DebugPauseState::waitingForUserStartConfirmation, DebugPauseState::hasUserStartConfirmation);
|
BlitCommandsHelper<GfxFamily>::dispatchDebugPauseCommands(commandStream, getDebugPauseStateGPUAddress(), DebugPauseState::waitingForUserStartConfirmation, DebugPauseState::hasUserStartConfirmation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -983,7 +982,7 @@ uint32_t CommandStreamReceiverHw<GfxFamily>::blitBuffer(const BlitPropertiesCont
|
|||||||
|
|
||||||
MemorySynchronizationCommands<GfxFamily>::addAdditionalSynchronization(commandStream, tagAllocation->getGpuAddress(), peekHwInfo());
|
MemorySynchronizationCommands<GfxFamily>::addAdditionalSynchronization(commandStream, tagAllocation->getGpuAddress(), peekHwInfo());
|
||||||
|
|
||||||
if (pauseOnBlitCopyAllowed) {
|
if (PauseOnGpuProperties::pauseModeAllowed(DebugManager.flags.PauseOnBlitCopy.get(), taskCount, PauseOnGpuProperties::PauseMode::AfterWorkload)) {
|
||||||
BlitCommandsHelper<GfxFamily>::dispatchDebugPauseCommands(commandStream, getDebugPauseStateGPUAddress(), DebugPauseState::waitingForUserEndConfirmation, DebugPauseState::hasUserEndConfirmation);
|
BlitCommandsHelper<GfxFamily>::dispatchDebugPauseCommands(commandStream, getDebugPauseStateGPUAddress(), DebugPauseState::waitingForUserEndConfirmation, DebugPauseState::hasUserEndConfirmation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,8 +65,9 @@ DECLARE_DEBUG_VARIABLE(int32_t, OverrideGpuAddressSpace, -1, "-1: Default, !=-1:
|
|||||||
DECLARE_DEBUG_VARIABLE(int32_t, OverrideMaxWorkgroupSize, -1, "-1: Default, !=-1: Overrides max worgkroup size to this value")
|
DECLARE_DEBUG_VARIABLE(int32_t, OverrideMaxWorkgroupSize, -1, "-1: Default, !=-1: Overrides max worgkroup size to this value")
|
||||||
DECLARE_DEBUG_VARIABLE(int32_t, DoCpuCopyOnReadBuffer, -1, "-1: default 0: do not use CPU copy, 1: triggers CPU copy path for Read Buffer calls, only supported for some basic use cases (no blocked user events in dependencies tree)")
|
DECLARE_DEBUG_VARIABLE(int32_t, DoCpuCopyOnReadBuffer, -1, "-1: default 0: do not use CPU copy, 1: triggers CPU copy path for Read Buffer calls, only supported for some basic use cases (no blocked user events in dependencies tree)")
|
||||||
DECLARE_DEBUG_VARIABLE(int32_t, DoCpuCopyOnWriteBuffer, -1, "-1: default 0: do not use CPU copy, 1: triggers CPU copy path for Write Buffer calls, only supported for some basic use cases (no blocked user events in dependencies tree)")
|
DECLARE_DEBUG_VARIABLE(int32_t, DoCpuCopyOnWriteBuffer, -1, "-1: default 0: do not use CPU copy, 1: triggers CPU copy path for Write Buffer calls, only supported for some basic use cases (no blocked user events in dependencies tree)")
|
||||||
DECLARE_DEBUG_VARIABLE(int32_t, PauseOnEnqueue, -1, "-1: default, x: pause on enqueue number x and ask for user confirmation before and after execution, counted from 0")
|
DECLARE_DEBUG_VARIABLE(int32_t, PauseOnEnqueue, -1, "-1: default, -2: always, x: pause on enqueue number x and ask for user confirmation before and after execution, counted from 0")
|
||||||
DECLARE_DEBUG_VARIABLE(int32_t, PauseOnBlitCopy, -1, "-1: default, x: pause on blit enqueue number x and ask for user confirmation before and after execution, counted from 0. Note that single blit enqueue may have multiple copy instructions")
|
DECLARE_DEBUG_VARIABLE(int32_t, PauseOnBlitCopy, -1, "-1: default, -2: always, x: pause on blit enqueue number x and ask for user confirmation before and after execution, counted from 0. Note that single blit enqueue may have multiple copy instructions")
|
||||||
|
DECLARE_DEBUG_VARIABLE(int32_t, PauseOnGpuMode, -1, "-1: default (before and after), 0: before only, 1: after only")
|
||||||
DECLARE_DEBUG_VARIABLE(int32_t, EnableMultiStorageResources, -1, "-1: default, 0: Disable, 1: Enable")
|
DECLARE_DEBUG_VARIABLE(int32_t, EnableMultiStorageResources, -1, "-1: default, 0: Disable, 1: Enable")
|
||||||
DECLARE_DEBUG_VARIABLE(int32_t, LimitBlitterMaxWidth, -1, "-1: default, >=0: Max width")
|
DECLARE_DEBUG_VARIABLE(int32_t, LimitBlitterMaxWidth, -1, "-1: default, >=0: Max width")
|
||||||
DECLARE_DEBUG_VARIABLE(int32_t, LimitBlitterMaxHeight, -1, "-1: default, >=0: Max height")
|
DECLARE_DEBUG_VARIABLE(int32_t, LimitBlitterMaxHeight, -1, "-1: default, >=0: Max height")
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ set(NEO_CORE_HELPERS
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/kmd_notify_properties.h
|
${CMAKE_CURRENT_SOURCE_DIR}/kmd_notify_properties.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/non_copyable_or_moveable.h
|
${CMAKE_CURRENT_SOURCE_DIR}/non_copyable_or_moveable.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/options.h
|
${CMAKE_CURRENT_SOURCE_DIR}/options.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/pause_on_gpu_properties.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/pipeline_select_args.h
|
${CMAKE_CURRENT_SOURCE_DIR}/pipeline_select_args.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/pipeline_select_helper.h
|
${CMAKE_CURRENT_SOURCE_DIR}/pipeline_select_helper.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/preamble.h
|
${CMAKE_CURRENT_SOURCE_DIR}/preamble.h
|
||||||
|
|||||||
50
shared/source/helpers/pause_on_gpu_properties.h
Normal file
50
shared/source/helpers/pause_on_gpu_properties.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017-2020 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "shared/source/debug_settings/debug_settings_manager.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace NEO {
|
||||||
|
namespace PauseOnGpuProperties {
|
||||||
|
enum PauseMode : int32_t {
|
||||||
|
BeforeAndAfterWorkload = -1,
|
||||||
|
BeforeWorkload = 0,
|
||||||
|
AfterWorkload = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DebugFlagValues : int32_t {
|
||||||
|
OnEachEnqueue = -2,
|
||||||
|
Disabled = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool featureEnabled(int32_t debugFlagValue) {
|
||||||
|
return (debugFlagValue != DebugFlagValues::Disabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool pauseModeAllowed(int32_t debugFlagValue, uint32_t taskCount, PauseMode pauseMode) {
|
||||||
|
if (!featureEnabled(debugFlagValue)) {
|
||||||
|
// feature disabled
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((DebugManager.flags.PauseOnGpuMode.get() != PauseMode::BeforeAndAfterWorkload) && (DebugManager.flags.PauseOnGpuMode.get() != pauseMode)) {
|
||||||
|
// mode not allowed
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debugFlagValue == DebugFlagValues::OnEachEnqueue) {
|
||||||
|
// pause on each enqueue
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (debugFlagValue == static_cast<int32_t>(taskCount));
|
||||||
|
}
|
||||||
|
} // namespace PauseOnGpuProperties
|
||||||
|
} // namespace NEO
|
||||||
Reference in New Issue
Block a user