mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-10 12:53:42 +08:00
Debugger L0 Win - register allocations metadata in debugger
Related-To: NEO-6764 Signed-off-by: Igor Venevtsev <igor.venevtsev@intel.com>
This commit is contained in:

committed by
Compute-Runtime-Automation

parent
2f46a7da63
commit
cb6db5672b
@ -44,13 +44,18 @@ ze_result_t DebugSessionWindows::initialize() {
|
||||
escapeInfo.KmEuDbgL0EscapeInfo.AttachDebuggerParams.ProcessId = processId;
|
||||
|
||||
auto status = runEscape(escapeInfo);
|
||||
if (STATUS_SUCCESS != status || DBGUMD_RETURN_ESCAPE_SUCCESS != escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_ATTACH_DEBUGGER: Failed - ProcessId: %d Status: %d EscapeReturnStatus: %d\n", processId, status, escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||
if (STATUS_SUCCESS != status) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_ATTACH_DEBUGGER: Failed - ProcessId: %d Status: 0x%llX EscapeReturnStatus: %d\n", processId, status, escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||
return DebugSessionWindows::translateNtStatusToZeResult(status);
|
||||
}
|
||||
|
||||
if (DBGUMD_RETURN_ESCAPE_SUCCESS != escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_ATTACH_DEBUGGER: Failed - ProcessId: %d Status: 0x%llX EscapeReturnStatus: %d\n", processId, status, escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||
return DebugSessionWindows::translateEscapeReturnStatusToZeResult(escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||
}
|
||||
|
||||
debugHandle = escapeInfo.KmEuDbgL0EscapeInfo.AttachDebuggerParams.hDebugHandle;
|
||||
PRINT_DEBUGGER_INFO_LOG("DBGUMD_ACTION_ATTACH_DEBUGGER: SUCCESS - ProcessId: %d DebugHandle: 0x%ullx\n", processId, debugHandle);
|
||||
PRINT_DEBUGGER_INFO_LOG("DBGUMD_ACTION_ATTACH_DEBUGGER: SUCCESS - ProcessId: %d DebugHandle: 0x%llx\n", processId, debugHandle);
|
||||
|
||||
auto result = ZE_RESULT_SUCCESS;
|
||||
do {
|
||||
@ -77,7 +82,7 @@ bool DebugSessionWindows::closeConnection() {
|
||||
|
||||
auto status = runEscape(escapeInfo);
|
||||
if (STATUS_SUCCESS != status) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_DETACH_DEBUGGER: Failed - ProcessId: %d Status: %d\n", processId, status);
|
||||
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_DETACH_DEBUGGER: Failed - ProcessId: %d Status: 0x%llX\n", processId, status);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -111,6 +116,7 @@ NTSTATUS DebugSessionWindows::runEscape(KM_ESCAPE_INFO &escapeInfo) {
|
||||
D3DKMT_ESCAPE escapeCommand = {0};
|
||||
|
||||
escapeInfo.Header.EscapeCode = GFX_ESCAPE_KMD;
|
||||
escapeInfo.Header.Size = sizeof(escapeInfo) - sizeof(escapeInfo.Header);
|
||||
escapeInfo.EscapeOperation = KM_ESCAPE_EUDBG_L0_DBGUMD_HANDLER;
|
||||
escapeInfo.KmEuDbgL0EscapeInfo.hDebugHandle = debugHandle;
|
||||
|
||||
@ -140,18 +146,24 @@ ze_result_t DebugSessionWindows::readAndHandleEvent(uint64_t timeoutMs) {
|
||||
escapeInfo.KmEuDbgL0EscapeInfo.ReadEventParams.EventParamBufferPtr = reinterpret_cast<uint64_t>(&eventParamsBuffer);
|
||||
|
||||
auto status = runEscape(escapeInfo);
|
||||
if (STATUS_SUCCESS != status || DBGUMD_RETURN_ESCAPE_SUCCESS != escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_READ_EVENT: Failed - Status: %d EscapeReturnStatus: %d\n", status, escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||
if (STATUS_SUCCESS != status) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_READ_EVENT: Failed - Status: 0x%llX EscapeReturnStatus: %d\n", status, escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||
return DebugSessionWindows::translateNtStatusToZeResult(status);
|
||||
}
|
||||
|
||||
if (DBGUMD_RETURN_ESCAPE_SUCCESS != escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_READ_EVENT: Failed - Status: 0x%llX EscapeReturnStatus: %d\n", status, escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||
return DebugSessionWindows::translateEscapeReturnStatusToZeResult(escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||
}
|
||||
|
||||
auto seqNo = escapeInfo.KmEuDbgL0EscapeInfo.ReadEventParams.EventSeqNo;
|
||||
switch (escapeInfo.KmEuDbgL0EscapeInfo.ReadEventParams.ReadEventType) {
|
||||
case DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION:
|
||||
return handleModuleCreateEvent(eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams);
|
||||
case DBGUMD_READ_EVENT_EU_ATTN_BIT_SET:
|
||||
return handleEuAttentionBitsEvent(eventParamsBuffer.eventParamsBuffer.EuBitSetEventParams);
|
||||
case DBGUMD_READ_EVENT_ALLOCATION_DATA_INFO:
|
||||
return handleAllocationDataEvent(eventParamsBuffer.eventParamsBuffer.ReadAdditionalAllocDataParams);
|
||||
return handleAllocationDataEvent(seqNo, eventParamsBuffer.eventParamsBuffer.ReadAdditionalAllocDataParams);
|
||||
case DBGUMD_READ_EVENT_CONTEXT_CREATE_DESTROY:
|
||||
return handleContextCreateDestroyEvent(eventParamsBuffer.eventParamsBuffer.ContextCreateDestroyEventParams);
|
||||
case DBGUMD_READ_EVENT_DEVICE_CREATE_DESTROY:
|
||||
@ -174,14 +186,25 @@ ze_result_t DebugSessionWindows::handleEuAttentionBitsEvent(DBGUMD_READ_EVENT_EU
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
ze_result_t DebugSessionWindows::handleAllocationDataEvent(DBGUMD_READ_EVENT_READ_ALLOCATION_DATA_PARAMS &allocationDataParams) {
|
||||
auto allocationDebugData = reinterpret_cast<GFX_ALLOCATION_DEBUG_DATA_INFO *>(allocationDataParams.DebugDataBufferPtr);
|
||||
ze_result_t DebugSessionWindows::handleAllocationDataEvent(uint32_t seqNo, DBGUMD_READ_EVENT_READ_ALLOCATION_DATA_PARAMS &allocationDataParams) {
|
||||
auto allocationDebugData = reinterpret_cast<GFX_ALLOCATION_DEBUG_DATA_INFO *>(&allocationDataParams.DebugDataBufferPtr);
|
||||
UNRECOVERABLE_IF(nullptr == allocationDebugData);
|
||||
|
||||
if (allocationDebugData->DataType == MODULE_HEAP_DEBUG_AREA) {
|
||||
moduleDebugAreaCaptured = true;
|
||||
}
|
||||
for (uint32_t i = 0; i < allocationDataParams.NumOfDebugData; ++i) {
|
||||
auto dataType = allocationDebugData[i].DataType;
|
||||
PRINT_DEBUGGER_INFO_LOG("DBGUMD_ACTION_READ_ALLOCATION_DATA: DataType=%d DataSize=%d DataPointer=%p\n", dataType, allocationDebugData[i].DataSize, allocationDebugData[i].DataPointer);
|
||||
NEO::WddmAllocation::RegistrationData registrationData = {0};
|
||||
auto result = readAllocationDebugData(seqNo, allocationDebugData[i].DataPointer, ®istrationData, sizeof(registrationData));
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_READ_ALLOCATION_DATA - Fail!\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
if (allocationDebugData->DataType == MODULE_HEAP_DEBUG_AREA) {
|
||||
moduleDebugAreaCaptured = true;
|
||||
}
|
||||
PRINT_DEBUGGER_INFO_LOG("DBGUMD_ACTION_READ_ALLOCATION_DATA - Success - gpuVA=0x%llX Size=0x%X\n", registrationData.gpuVirtualAddress, registrationData.size);
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -202,7 +225,33 @@ ze_result_t DebugSessionWindows::handleContextCreateDestroyEvent(DBGUMD_READ_EVE
|
||||
}
|
||||
|
||||
ze_result_t DebugSessionWindows::handleDeviceCreateDestroyEvent(DBGUMD_READ_EVENT_DEVICE_CREATE_DESTROY_EVENT_PARAMS &deviceCreateDestroyParams) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
PRINT_DEBUGGER_INFO_LOG("DEVICE_CREATE_DESTROY_EVENT: hDeviceContext=0x%llx IsCreated=%d ProcessId=%d\n",
|
||||
deviceCreateDestroyParams.hDeviceContext, deviceCreateDestroyParams.IsCreated, deviceCreateDestroyParams.ProcessID);
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t DebugSessionWindows::readAllocationDebugData(uint32_t seqNo, uint64_t umdDataBufferPtr, void *outBuf, size_t outBufSize) {
|
||||
KM_ESCAPE_INFO escapeInfo = {0};
|
||||
|
||||
escapeInfo.KmEuDbgL0EscapeInfo.EscapeActionType = DBGUMD_ACTION_READ_ALLOCATION_DATA;
|
||||
escapeInfo.KmEuDbgL0EscapeInfo.ReadAdditionalAllocDataParams.EventSeqNo = seqNo;
|
||||
escapeInfo.KmEuDbgL0EscapeInfo.ReadAdditionalAllocDataParams.DebugDataAddr = umdDataBufferPtr;
|
||||
escapeInfo.KmEuDbgL0EscapeInfo.ReadAdditionalAllocDataParams.OutputBufferSize = static_cast<uint32_t>(outBufSize);
|
||||
escapeInfo.KmEuDbgL0EscapeInfo.ReadAdditionalAllocDataParams.OutputBufferPtr = reinterpret_cast<uint64_t>(outBuf);
|
||||
|
||||
auto status = runEscape(escapeInfo);
|
||||
if (STATUS_SUCCESS != status) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_READ_ALLOCATION_DATA: Failed - Status: 0x%llX EscapeReturnStatus: %d\n", status, escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||
return DebugSessionWindows::translateNtStatusToZeResult(status);
|
||||
}
|
||||
|
||||
if (DBGUMD_RETURN_ESCAPE_SUCCESS != escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_READ_ALLOCATION_DATA: Failed - Status: 0x%llX EscapeReturnStatus: %d\n", status, escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||
return DebugSessionWindows::translateEscapeReturnStatusToZeResult(escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||
}
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t DebugSessionWindows::handleCreateDebugDataEvent(DBGUMD_READ_EVENT_CREATE_DEBUG_DATA_PARAMS &createDebugDataParams) {
|
||||
@ -218,6 +267,19 @@ ze_result_t DebugSessionWindows::handleCreateDebugDataEvent(DBGUMD_READ_EVENT_CR
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t DebugSessionWindows::translateNtStatusToZeResult(NTSTATUS status) {
|
||||
switch (status) {
|
||||
case STATUS_SUCCESS:
|
||||
return ZE_RESULT_SUCCESS;
|
||||
case STATUS_INVALID_PARAMETER:
|
||||
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||||
case STATUS_UNSUCCESSFUL:
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
default:
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t DebugSessionWindows::translateEscapeReturnStatusToZeResult(uint32_t escapeReturnStatus) {
|
||||
switch (escapeReturnStatus) {
|
||||
case DBGUMD_RETURN_ESCAPE_SUCCESS:
|
||||
|
@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "shared/source/os_interface/windows/wddm/wddm.h"
|
||||
#include "shared/source/os_interface/windows/wddm_allocation.h"
|
||||
|
||||
#include "level_zero/core/source/device/device.h"
|
||||
#include "level_zero/tools/source/debug/debug_session.h"
|
||||
@ -31,6 +32,7 @@ struct DebugSessionWindows : DebugSessionImp {
|
||||
ze_result_t writeMemory(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc, size_t size, const void *buffer) override;
|
||||
ze_result_t acknowledgeEvent(const zet_debug_event_t *event) override;
|
||||
|
||||
static ze_result_t translateNtStatusToZeResult(NTSTATUS status);
|
||||
static ze_result_t translateEscapeReturnStatusToZeResult(uint32_t escapeErrorStatus);
|
||||
|
||||
protected:
|
||||
@ -45,10 +47,11 @@ struct DebugSessionWindows : DebugSessionImp {
|
||||
MOCKABLE_VIRTUAL ze_result_t readAndHandleEvent(uint64_t timeoutMs);
|
||||
ze_result_t handleModuleCreateEvent(DBGUMD_READ_EVENT_MODULE_CREATE_EVENT_PARAMS &moduleCreateParams);
|
||||
ze_result_t handleEuAttentionBitsEvent(DBGUMD_READ_EVENT_EU_ATTN_BIT_SET_PARAMS &euAttentionBitsParams);
|
||||
ze_result_t handleAllocationDataEvent(DBGUMD_READ_EVENT_READ_ALLOCATION_DATA_PARAMS &allocationDataParams);
|
||||
ze_result_t handleAllocationDataEvent(uint32_t seqNo, DBGUMD_READ_EVENT_READ_ALLOCATION_DATA_PARAMS &allocationDataParams);
|
||||
ze_result_t handleContextCreateDestroyEvent(DBGUMD_READ_EVENT_CONTEXT_CREATE_DESTROY_EVENT_PARAMS &contextCreateDestroyParams);
|
||||
ze_result_t handleDeviceCreateDestroyEvent(DBGUMD_READ_EVENT_DEVICE_CREATE_DESTROY_EVENT_PARAMS &deviceCreateDestroyParams);
|
||||
ze_result_t handleCreateDebugDataEvent(DBGUMD_READ_EVENT_CREATE_DEBUG_DATA_PARAMS &createDebugDataParams);
|
||||
ze_result_t readAllocationDebugData(uint32_t seqNo, uint64_t umdDataBufferPtr, void *outBuf, size_t outBufSize);
|
||||
|
||||
void enqueueApiEvent(zet_debug_event_t &debugEvent) override;
|
||||
bool readSystemRoutineIdent(EuThread *thread, uint64_t vmHandle, SIP::sr_ident &srMagic) override;
|
||||
|
@ -5,6 +5,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/os_interface/windows/wddm_allocation.h"
|
||||
#include "shared/test/common/mocks/windows/mock_wddm_eudebug.h"
|
||||
#include "shared/test/common/test_macros/test.h"
|
||||
|
||||
@ -23,6 +24,7 @@ struct MockDebugSessionWindows : DebugSessionWindows {
|
||||
using DebugSessionWindows::initialize;
|
||||
using DebugSessionWindows::moduleDebugAreaCaptured;
|
||||
using DebugSessionWindows::processId;
|
||||
using DebugSessionWindows::readAllocationDebugData;
|
||||
using DebugSessionWindows::readAndHandleEvent;
|
||||
using DebugSessionWindows::startAsyncThread;
|
||||
using DebugSessionWindows::wddm;
|
||||
@ -110,12 +112,40 @@ TEST_F(DebugApiWindowsTest, givenDebugAttachAvailableAndInitializationFailedWhen
|
||||
EXPECT_EQ(nullptr, debugSession);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenDebugSessionInitializeCalledAndModuleDebugAreaNotCapturedThenAttachDebuggerAndReadEventEscapesAreInvokedAndErrorNotAvailableReturned) {
|
||||
TEST_F(DebugApiWindowsTest, givenDebugSessionInitializeCalledAndDebugAttachNtStatusIsFailedThenErrorUnknownReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
mockWddm->ntStatus = STATUS_UNSUCCESSFUL;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
auto result = session->initialize();
|
||||
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, result);
|
||||
EXPECT_FALSE(session->moduleDebugAreaCaptured);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ATTACH_DEBUGGER]);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenDebugSessionInitializeCalledAndDebugAttachEscapeReturnStatusIsFailedThenErrorUnsupportedFetaureReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
mockWddm->escapeReturnStatus = DBGUMD_RETURN_EU_DEBUG_NOT_SUPPORTED;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
auto result = session->initialize();
|
||||
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
|
||||
EXPECT_FALSE(session->moduleDebugAreaCaptured);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ATTACH_DEBUGGER]);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenDebugSessionInitializeCalledAndEventQueueIsEmptyThenAttachDebuggerAndReadEventEscapesAreInvokedAndErrorNotAvailableReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
// KMD event queue is empty
|
||||
mockWddm->readEventOutParams.escapeReturnStatus = DBGUMD_RETURN_READ_EVENT_TIMEOUT_EXPIRED;
|
||||
mockWddm->numEvents = 0;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
auto result = session->initialize();
|
||||
@ -126,15 +156,88 @@ TEST_F(DebugApiWindowsTest, givenDebugSessionInitializeCalledAndModuleDebugAreaN
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_EVENT]);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenDebugSessionInitializeCalledAndModuleDebugAreaCapturedThenAttachDebuggerAndReadEventEscapesAreInvokedAndResultSuccessReturned) {
|
||||
TEST_F(DebugApiWindowsTest, givenDebugSessionInitializeCalledAndEventQueueIsNotAmptyAndModuleDebugAreaIsNotCapturedThenAttachDebuggerAndReadEventEscapesAreInvokedAndErrorNotAvailableReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
GFX_ALLOCATION_DEBUG_DATA_INFO allocDebugDataInfo = {0};
|
||||
allocDebugDataInfo.DataType = MODULE_HEAP_DEBUG_AREA;
|
||||
mockWddm->readEventOutParams.readEventType = DBGUMD_READ_EVENT_ALLOCATION_DATA_INFO;
|
||||
mockWddm->readEventOutParams.eventParamsBuffer.ReadAdditionalAllocDataParams.NumOfDebugData = 1;
|
||||
mockWddm->readEventOutParams.eventParamsBuffer.ReadAdditionalAllocDataParams.DebugDataBufferPtr = reinterpret_cast<uint64_t>(&allocDebugDataInfo);
|
||||
mockWddm->numEvents = 1;
|
||||
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_CONTEXT_CREATE_DESTROY;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
auto result = session->initialize();
|
||||
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result);
|
||||
EXPECT_FALSE(session->moduleDebugAreaCaptured);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ATTACH_DEBUGGER]);
|
||||
EXPECT_EQ(2, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_EVENT]);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenDebugSessionInitializeCalledAndEventQueueIsNotAmptyAndReadAllocationDataFailedThenAttachDebuggerAndReadEventAndReadAllocationDataEscapesAreInvokedAndResultUnknownIsReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
mockWddm->numEvents = 1;
|
||||
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_ALLOCATION_DATA_INFO;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadAdditionalAllocDataParams.NumOfDebugData = 1;
|
||||
GFX_ALLOCATION_DEBUG_DATA_INFO *allocDebugDataInfo = reinterpret_cast<GFX_ALLOCATION_DEBUG_DATA_INFO *>(&mockWddm->eventQueue[2].eventParamsBuffer.eventParamsBuffer.ReadAdditionalAllocDataParams.DebugDataBufferPtr);
|
||||
allocDebugDataInfo->DataType = MODULE_HEAP_DEBUG_AREA;
|
||||
|
||||
WddmAllocation::RegistrationData registrationData = {0x12345678, 0x1000};
|
||||
mockWddm->readAllocationDataOutParams.escapeReturnStatus = DBGUMD_RETURN_EU_DEBUG_NOT_SUPPORTED;
|
||||
mockWddm->readAllocationDataOutParams.outData = ®istrationData;
|
||||
mockWddm->readAllocationDataOutParams.outDataSize = sizeof(registrationData);
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
auto result = session->initialize();
|
||||
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
|
||||
EXPECT_FALSE(session->moduleDebugAreaCaptured);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ATTACH_DEBUGGER]);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_EVENT]);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_ALLOCATION_DATA]);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenDebugSessionInitializeCalledAndEventQueueIsNotAmptyAndReadAllocationDataSucceedAndModuleDebugAreaNotCapturedThenAttachDebuggerAndReadEventAndReadAllocationDataEscapesAreInvokedAndResultUnavailableIsReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
mockWddm->numEvents = 1;
|
||||
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_ALLOCATION_DATA_INFO;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadAdditionalAllocDataParams.NumOfDebugData = 1;
|
||||
GFX_ALLOCATION_DEBUG_DATA_INFO *allocDebugDataInfo = reinterpret_cast<GFX_ALLOCATION_DEBUG_DATA_INFO *>(&mockWddm->eventQueue[2].eventParamsBuffer.eventParamsBuffer.ReadAdditionalAllocDataParams.DebugDataBufferPtr);
|
||||
allocDebugDataInfo->DataType = ISA;
|
||||
|
||||
WddmAllocation::RegistrationData registrationData = {0x12345678, 0x1000};
|
||||
mockWddm->readAllocationDataOutParams.outData = ®istrationData;
|
||||
mockWddm->readAllocationDataOutParams.outDataSize = sizeof(registrationData);
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
auto result = session->initialize();
|
||||
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result);
|
||||
EXPECT_FALSE(session->moduleDebugAreaCaptured);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ATTACH_DEBUGGER]);
|
||||
EXPECT_EQ(2, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_EVENT]);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_ALLOCATION_DATA]);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenDebugSessionInitializeCalledAndEventQueueIsNotAmptyAndModuleDebugAreaIsCapturedThenAttachDebuggerAndReadEventEscapesAreInvokedAndResultSuccessReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
mockWddm->numEvents = 3;
|
||||
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_CONTEXT_CREATE_DESTROY;
|
||||
|
||||
mockWddm->eventQueue[1].readEventType = DBGUMD_READ_EVENT_DEVICE_CREATE_DESTROY;
|
||||
|
||||
mockWddm->eventQueue[2].readEventType = DBGUMD_READ_EVENT_ALLOCATION_DATA_INFO;
|
||||
mockWddm->eventQueue[2].eventParamsBuffer.eventParamsBuffer.ReadAdditionalAllocDataParams.NumOfDebugData = 1;
|
||||
GFX_ALLOCATION_DEBUG_DATA_INFO *allocDebugDataInfo = reinterpret_cast<GFX_ALLOCATION_DEBUG_DATA_INFO *>(&mockWddm->eventQueue[2].eventParamsBuffer.eventParamsBuffer.ReadAdditionalAllocDataParams.DebugDataBufferPtr);
|
||||
allocDebugDataInfo->DataType = MODULE_HEAP_DEBUG_AREA;
|
||||
|
||||
WddmAllocation::RegistrationData registrationData = {0x12345678, 0x1000};
|
||||
mockWddm->readAllocationDataOutParams.outData = ®istrationData;
|
||||
mockWddm->readAllocationDataOutParams.outDataSize = sizeof(registrationData);
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
auto result = session->initialize();
|
||||
@ -142,7 +245,8 @@ TEST_F(DebugApiWindowsTest, givenDebugSessionInitializeCalledAndModuleDebugAreaC
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_TRUE(session->moduleDebugAreaCaptured);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ATTACH_DEBUGGER]);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_EVENT]);
|
||||
EXPECT_EQ(3, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_EVENT]);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_ALLOCATION_DATA]);
|
||||
EXPECT_EQ(session->processId, config.pid);
|
||||
EXPECT_EQ(session->debugHandle, mockWddm->debugHandle);
|
||||
}
|
||||
@ -159,11 +263,15 @@ TEST_F(DebugApiWindowsTest, givenDebugSessionInitializedAndCloseConnectionCalled
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
GFX_ALLOCATION_DEBUG_DATA_INFO allocDebugDataInfo = {0};
|
||||
allocDebugDataInfo.DataType = MODULE_HEAP_DEBUG_AREA;
|
||||
mockWddm->readEventOutParams.readEventType = DBGUMD_READ_EVENT_ALLOCATION_DATA_INFO;
|
||||
mockWddm->readEventOutParams.eventParamsBuffer.ReadAdditionalAllocDataParams.NumOfDebugData = 1;
|
||||
mockWddm->readEventOutParams.eventParamsBuffer.ReadAdditionalAllocDataParams.DebugDataBufferPtr = reinterpret_cast<uint64_t>(&allocDebugDataInfo);
|
||||
mockWddm->numEvents = 1;
|
||||
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_ALLOCATION_DATA_INFO;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadAdditionalAllocDataParams.NumOfDebugData = 1;
|
||||
GFX_ALLOCATION_DEBUG_DATA_INFO *allocDebugDataInfo = reinterpret_cast<GFX_ALLOCATION_DEBUG_DATA_INFO *>(&mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadAdditionalAllocDataParams.DebugDataBufferPtr);
|
||||
allocDebugDataInfo->DataType = MODULE_HEAP_DEBUG_AREA;
|
||||
|
||||
WddmAllocation::RegistrationData registrationData = {0x12345678, 0x1000};
|
||||
mockWddm->readAllocationDataOutParams.outData = ®istrationData;
|
||||
mockWddm->readAllocationDataOutParams.outDataSize = sizeof(registrationData);
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
auto result = session->initialize();
|
||||
@ -171,6 +279,7 @@ TEST_F(DebugApiWindowsTest, givenDebugSessionInitializedAndCloseConnectionCalled
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ATTACH_DEBUGGER]);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_EVENT]);
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_ALLOCATION_DATA]);
|
||||
EXPECT_EQ(session->processId, config.pid);
|
||||
EXPECT_EQ(session->debugHandle, mockWddm->debugHandle);
|
||||
|
||||
@ -178,6 +287,29 @@ TEST_F(DebugApiWindowsTest, givenDebugSessionInitializedAndCloseConnectionCalled
|
||||
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_DETACH_DEBUGGER]);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenNtStatusFailedWhenReadAndHandleEventCalledThenResultUnknownIsReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
session->wddm = mockWddm;
|
||||
|
||||
mockWddm->ntStatus = STATUS_UNSUCCESSFUL;
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, session->readAndHandleEvent(100));
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenEscapeReturnStatusFailedWhenReadAndHandleEventCalledThenResultUnsupportedFeatureIsReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
session->wddm = mockWddm;
|
||||
|
||||
mockWddm->numEvents = 1;
|
||||
mockWddm->eventQueue[0].escapeReturnStatus = DBGUMD_RETURN_EU_DEBUG_NOT_SUPPORTED;
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, session->readAndHandleEvent(100));
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenUnsupportedEventTypeWhenReadAndHandleEventCalledThenResultUnsupportedFeatureIsReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
@ -185,10 +317,10 @@ TEST_F(DebugApiWindowsTest, givenUnsupportedEventTypeWhenReadAndHandleEventCalle
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
session->wddm = mockWddm;
|
||||
|
||||
for (auto unsupportedEventType : {DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION,
|
||||
DBGUMD_READ_EVENT_EU_ATTN_BIT_SET,
|
||||
DBGUMD_READ_EVENT_DEVICE_CREATE_DESTROY}) {
|
||||
mockWddm->readEventOutParams.readEventType = unsupportedEventType;
|
||||
mockWddm->numEvents = 1;
|
||||
for (auto unsupportedEventType : {DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION, DBGUMD_READ_EVENT_EU_ATTN_BIT_SET}) {
|
||||
mockWddm->curEvent = 0;
|
||||
mockWddm->eventQueue[0].readEventType = unsupportedEventType;
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, session->readAndHandleEvent(100));
|
||||
}
|
||||
}
|
||||
@ -199,10 +331,34 @@ TEST_F(DebugApiWindowsTest, givenUnknownEventTypeWhenReadAndHandleEventCalledThe
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
session->wddm = mockWddm;
|
||||
mockWddm->readEventOutParams.readEventType = DBGUMD_READ_EVENT_MAX;
|
||||
|
||||
mockWddm->numEvents = 1;
|
||||
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_MAX;
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, session->readAndHandleEvent(100));
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenNtStatusFailedWhenReadAllocationDebugDataCalledThenResultUnknownIsReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
session->wddm = mockWddm;
|
||||
|
||||
mockWddm->ntStatus = STATUS_UNSUCCESSFUL;
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, session->readAllocationDebugData(1, 0x1234, nullptr, 0));
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenEscapeReturnStatusFailedWhenReadAllocationDebugDataCalledThenResultUnsupportedFeatureIsReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
session->wddm = mockWddm;
|
||||
|
||||
mockWddm->readAllocationDataOutParams.escapeReturnStatus = DBGUMD_RETURN_EU_DEBUG_NOT_SUPPORTED;
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, session->readAllocationDebugData(1, 0x1234, nullptr, 0));
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenDebugDataEventTypeWhenReadAndHandleEventCalledThenResultDebugDataIsSaved) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
@ -210,10 +366,11 @@ TEST_F(DebugApiWindowsTest, givenDebugDataEventTypeWhenReadAndHandleEventCalledT
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
session->wddm = mockWddm;
|
||||
|
||||
mockWddm->readEventOutParams.readEventType = DBGUMD_READ_EVENT_CREATE_DEBUG_DATA;
|
||||
mockWddm->readEventOutParams.eventParamsBuffer.ReadCreateDebugDataParams.DebugDataType = ELF_BINARY;
|
||||
mockWddm->readEventOutParams.eventParamsBuffer.ReadCreateDebugDataParams.DataBufferPtr = 0xa000;
|
||||
mockWddm->readEventOutParams.eventParamsBuffer.ReadCreateDebugDataParams.DataSize = 8;
|
||||
mockWddm->numEvents = 1;
|
||||
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_CREATE_DEBUG_DATA;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadCreateDebugDataParams.DebugDataType = ELF_BINARY;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadCreateDebugDataParams.DataBufferPtr = 0xa000;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadCreateDebugDataParams.DataSize = 8;
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, session->readAndHandleEvent(100));
|
||||
EXPECT_EQ(1, session->allElfs.size());
|
||||
auto elf = session->allElfs[0];
|
||||
@ -228,23 +385,33 @@ TEST_F(DebugApiWindowsTest, givenContextCreateEventTypeWhenReadAndHandleEventCal
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
session->wddm = mockWddm;
|
||||
|
||||
mockWddm->readEventOutParams.readEventType = DBGUMD_READ_EVENT_CONTEXT_CREATE_DESTROY;
|
||||
mockWddm->readEventOutParams.eventParamsBuffer.ContextCreateDestroyEventParams.hContextHandle = 0xa000;
|
||||
mockWddm->readEventOutParams.eventParamsBuffer.ContextCreateDestroyEventParams.IsCreated = 1;
|
||||
mockWddm->readEventOutParams.eventParamsBuffer.ContextCreateDestroyEventParams.IsSIPInstalled = 0;
|
||||
mockWddm->numEvents = 1;
|
||||
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_CONTEXT_CREATE_DESTROY;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ContextCreateDestroyEventParams.hContextHandle = 0xa000;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ContextCreateDestroyEventParams.IsCreated = 1;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ContextCreateDestroyEventParams.IsSIPInstalled = 0;
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, session->readAndHandleEvent(100));
|
||||
EXPECT_EQ(0, session->allContexts.size());
|
||||
|
||||
mockWddm->readEventOutParams.eventParamsBuffer.ContextCreateDestroyEventParams.IsSIPInstalled = 1;
|
||||
mockWddm->curEvent = 0;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ContextCreateDestroyEventParams.IsSIPInstalled = 1;
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, session->readAndHandleEvent(100));
|
||||
EXPECT_EQ(1, session->allContexts.size());
|
||||
EXPECT_EQ(1, session->allContexts.count(0xa000));
|
||||
|
||||
mockWddm->readEventOutParams.eventParamsBuffer.ContextCreateDestroyEventParams.IsCreated = 0;
|
||||
mockWddm->curEvent = 0;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ContextCreateDestroyEventParams.IsCreated = 0;
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, session->readAndHandleEvent(100));
|
||||
EXPECT_EQ(0, session->allContexts.size());
|
||||
}
|
||||
|
||||
TEST(DebugSessionWindowsTest, whenTranslateNtStatusCalledThenCorrectZeResultReturned) {
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, DebugSessionWindows::translateNtStatusToZeResult(STATUS_SUCCESS));
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, DebugSessionWindows::translateNtStatusToZeResult(STATUS_INVALID_PARAMETER));
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, DebugSessionWindows::translateNtStatusToZeResult(STATUS_UNSUCCESSFUL));
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, DebugSessionWindows::translateNtStatusToZeResult(NTSTATUS(~0)));
|
||||
}
|
||||
|
||||
TEST(DebugSessionWindowsTest, whenTranslateEscapeErrorStatusCalledThenCorrectZeResultReturned) {
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, DebugSessionWindows::translateEscapeReturnStatusToZeResult(DBGUMD_RETURN_ESCAPE_SUCCESS));
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, DebugSessionWindows::translateEscapeReturnStatusToZeResult(DBGUMD_RETURN_DEBUGGER_ATTACH_DEVICE_BUSY));
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "shared/test/common/mocks/mock_memory_manager.h"
|
||||
#include "shared/test/common/mocks/mock_os_context.h"
|
||||
#include "shared/test/common/mocks/ult_device_factory.h"
|
||||
#include "shared/test/common/mocks/windows/mock_wddm_eudebug.h"
|
||||
#include "shared/test/unit_test/utilities/base_object_utils.h"
|
||||
|
||||
#include "opencl/source/helpers/cl_memory_properties_helpers.h"
|
||||
@ -2243,6 +2244,33 @@ TEST_F(MockWddmMemoryManagerTest, givenCompressedFlagSetWhenInternalIsSetThenUpd
|
||||
EXPECT_EQ(expectedCallCount, mockMngr->updateAuxTableCalled);
|
||||
}
|
||||
|
||||
TEST_F(MockWddmMemoryManagerWithEuDebugInterfaceTest, givenAllocateGraphicsMemoryWhenAllocationRegistrationIsRequiredThenAllocationIsRegistered) {
|
||||
WddmMemoryManager memoryManager(*executionEnvironment);
|
||||
|
||||
uint32_t registerAllocationTypeCalled = 0;
|
||||
for (auto allocationType : {AllocationType::DEBUG_CONTEXT_SAVE_AREA,
|
||||
AllocationType::DEBUG_SBA_TRACKING_BUFFER,
|
||||
AllocationType::DEBUG_MODULE_AREA}) {
|
||||
auto wddmAlloc = static_cast<WddmAllocation *>(memoryManager.allocateGraphicsMemoryWithProperties(MockAllocationProperties{rootDeviceIndex, MemoryConstants::pageSize, allocationType}));
|
||||
EXPECT_EQ(++registerAllocationTypeCalled, wddm->registerAllocationTypeCalled);
|
||||
|
||||
WddmAllocation::RegistrationData registrationData = {0};
|
||||
registrationData.gpuVirtualAddress = wddmAlloc->getGpuAddress();
|
||||
registrationData.size = wddmAlloc->getUnderlyingBufferSize();
|
||||
|
||||
EXPECT_EQ(0, memcmp(wddm->registerAllocationTypePassedParams.allocData, ®istrationData, sizeof(registrationData)));
|
||||
memoryManager.freeGraphicsMemory(wddmAlloc);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(MockWddmMemoryManagerWithEuDebugInterfaceTest, givenAllocateGraphicsMemoryWhenAllocationRegistrationIsNotRequiredThenAllocationIsNotRegistered) {
|
||||
WddmMemoryManager memoryManager(*executionEnvironment);
|
||||
|
||||
auto wddmAlloc = static_cast<WddmAllocation *>(memoryManager.allocateGraphicsMemoryWithProperties(MockAllocationProperties{rootDeviceIndex, MemoryConstants::pageSize, AllocationType::BUFFER}));
|
||||
EXPECT_EQ(0, wddm->registerAllocationTypeCalled);
|
||||
memoryManager.freeGraphicsMemory(wddmAlloc);
|
||||
}
|
||||
|
||||
TEST_F(WddmMemoryManagerTest2, givenReadOnlyMemoryWhenCreateAllocationFailsThenPopulateOsHandlesReturnsInvalidPointer) {
|
||||
OsHandleStorage handleStorage;
|
||||
handleStorage.fragmentCount = 1;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "shared/test/common/mocks/mock_gmm_page_table_mngr.h"
|
||||
#include "shared/test/common/mocks/mock_wddm_residency_allocations_container.h"
|
||||
#include "shared/test/common/mocks/windows/mock_gdi_interface.h"
|
||||
#include "shared/test/common/mocks/windows/mock_wddm_eudebug.h"
|
||||
#include "shared/test/common/os_interface/windows/mock_wddm_memory_manager.h"
|
||||
#include "shared/test/common/os_interface/windows/wddm_fixture.h"
|
||||
#include "shared/test/common/test_macros/test.h"
|
||||
@ -188,4 +189,26 @@ class MockWddmMemoryManagerTest : public ::testing::Test {
|
||||
const uint32_t rootDeviceIndex = 0u;
|
||||
};
|
||||
|
||||
class MockWddmMemoryManagerWithEuDebugInterfaceTest : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
executionEnvironment = getExecutionEnvironmentImpl(hwInfo, 2);
|
||||
executionEnvironment->incRefInternal();
|
||||
wddm = new WddmEuDebugInterfaceMock(*executionEnvironment->rootDeviceEnvironments[1].get());
|
||||
wddm->callBaseDestroyAllocations = false;
|
||||
wddm->callBaseMapGpuVa = false;
|
||||
executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(wddm));
|
||||
executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->memoryOperationsInterface = std::make_unique<WddmMemoryOperationsHandler>(wddm);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
executionEnvironment->decRefInternal();
|
||||
}
|
||||
|
||||
HardwareInfo *hwInfo = nullptr;
|
||||
WddmEuDebugInterfaceMock *wddm = nullptr;
|
||||
ExecutionEnvironment *executionEnvironment = nullptr;
|
||||
const uint32_t rootDeviceIndex = 0u;
|
||||
};
|
||||
|
||||
using OsAgnosticMemoryManagerUsingWddmTest = MockWddmMemoryManagerTest;
|
||||
|
@ -121,6 +121,11 @@ if(NOT WIN32 AND NOT DISABLE_WDDM_LINUX)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_create_dxcore.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/trim_callback_stub.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sys_calls_wrapper_drm_or_wddm.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_memory_manager_register_allocation.cpp
|
||||
)
|
||||
else()
|
||||
list(APPEND NEO_CORE_OS_INTERFACE_WDDM
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_memory_manager_register_allocation_win.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@ -24,6 +24,11 @@ constexpr size_t trimListUnusedPosition = std::numeric_limits<size_t>::max();
|
||||
|
||||
class WddmAllocation : public GraphicsAllocation {
|
||||
public:
|
||||
struct RegistrationData {
|
||||
uint64_t gpuVirtualAddress = 0;
|
||||
uint64_t size = 0;
|
||||
};
|
||||
|
||||
WddmAllocation(uint32_t rootDeviceIndex, AllocationType allocationType, void *cpuPtrIn, uint64_t canonizedAddress, size_t sizeIn, void *reservedAddr, MemoryPool pool, uint32_t shareable, size_t maxOsContextCount)
|
||||
: WddmAllocation(rootDeviceIndex, 1, allocationType, cpuPtrIn, canonizedAddress, sizeIn, reservedAddr, pool, shareable, maxOsContextCount) {}
|
||||
|
||||
|
@ -79,6 +79,7 @@ class WddmMemoryManager : public MemoryManager {
|
||||
bool isNTHandle(osHandle handle, uint32_t rootDeviceIndex) override;
|
||||
void releaseDeviceSpecificMemResources(uint32_t rootDeviceIndex) override{};
|
||||
void createDeviceSpecificMemResources(uint32_t rootDeviceIndex) override{};
|
||||
void registerAllocationInOs(GraphicsAllocation *allocation) override;
|
||||
|
||||
protected:
|
||||
GraphicsAllocation *createGraphicsAllocation(OsHandleStorage &handleStorage, const AllocationData &allocationData) override;
|
||||
|
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/os_interface/windows/wddm_memory_manager.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
void WddmMemoryManager::registerAllocationInOs(GraphicsAllocation *allocation) {}
|
||||
|
||||
} // namespace NEO
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/os_interface/windows/wddm/wddm.h"
|
||||
#include "shared/source/os_interface/windows/wddm_memory_manager.h"
|
||||
|
||||
#include "KmEscape.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
void WddmMemoryManager::registerAllocationInOs(GraphicsAllocation *allocation) {
|
||||
auto dataType = MAX_GFX_ALLOCATION_TYPE;
|
||||
auto wddmAllocation = static_cast<WddmAllocation *>(allocation);
|
||||
switch (wddmAllocation->getAllocationType()) {
|
||||
case AllocationType::DEBUG_CONTEXT_SAVE_AREA:
|
||||
dataType = SIP_CONTEXT_SAVE_AREA;
|
||||
break;
|
||||
case AllocationType::DEBUG_SBA_TRACKING_BUFFER:
|
||||
dataType = SBA_BUFFER_AREA;
|
||||
break;
|
||||
case AllocationType::DEBUG_MODULE_AREA:
|
||||
dataType = MODULE_HEAP_DEBUG_AREA;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (dataType == MAX_GFX_ALLOCATION_TYPE) {
|
||||
return;
|
||||
}
|
||||
|
||||
WddmAllocation::RegistrationData registrationData = {0};
|
||||
registrationData.gpuVirtualAddress = wddmAllocation->getGpuAddress();
|
||||
registrationData.size = wddmAllocation->getUnderlyingBufferSize();
|
||||
|
||||
PRINT_DEBUGGER_INFO_LOG("REGISTER_ALLOCATION_TYPE: gpuVA=0x%llX Size=%X DataType=%d DataSize=%d DataPointer=%p\n",
|
||||
registrationData.gpuVirtualAddress, registrationData.size, dataType, sizeof(registrationData), ®istrationData);
|
||||
|
||||
GFX_ALLOCATION_DEBUG_DATA_INFO allocationDebugDataInfo;
|
||||
allocationDebugDataInfo.DataType = dataType;
|
||||
allocationDebugDataInfo.DataSize = sizeof(registrationData);
|
||||
allocationDebugDataInfo.DataPointer = reinterpret_cast<uint64_t>(®istrationData);
|
||||
|
||||
KM_ESCAPE_INFO escapeInfo;
|
||||
memset(&escapeInfo, 0, sizeof(escapeInfo));
|
||||
escapeInfo.Header.EscapeCode = GFX_ESCAPE_KMD;
|
||||
escapeInfo.Header.Size = sizeof(escapeInfo) - sizeof(escapeInfo.Header);
|
||||
escapeInfo.EscapeOperation = KM_ESCAPE_EUDBG_UMD_REGISTER_ALLOCATION_TYPE;
|
||||
escapeInfo.KmEuDbgUmdRegisterAllocationData.hAllocation = wddmAllocation->getDefaultHandle();
|
||||
escapeInfo.KmEuDbgUmdRegisterAllocationData.hElfAddressPtr = uint64_t(-1);
|
||||
escapeInfo.KmEuDbgUmdRegisterAllocationData.NumOfDebugDataInfo = 1;
|
||||
escapeInfo.KmEuDbgUmdRegisterAllocationData.DebugDataBufferPtr = reinterpret_cast<uint64_t>(&allocationDebugDataInfo);
|
||||
|
||||
auto &wddm = getWddm(allocation->getRootDeviceIndex());
|
||||
|
||||
D3DKMT_ESCAPE escapeCommand = {0};
|
||||
escapeCommand.Flags.HardwareAccess = 0;
|
||||
escapeCommand.Flags.Reserved = 0;
|
||||
escapeCommand.hAdapter = wddm.getAdapter();
|
||||
escapeCommand.hContext = (D3DKMT_HANDLE)0;
|
||||
escapeCommand.hDevice = wddm.getDeviceHandle();
|
||||
escapeCommand.pPrivateDriverData = &escapeInfo;
|
||||
escapeCommand.PrivateDriverDataSize = sizeof(escapeInfo);
|
||||
escapeCommand.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
|
||||
|
||||
[[maybe_unused]] auto status = wddm.escape(escapeCommand);
|
||||
DEBUG_BREAK_IF(STATUS_SUCCESS != status);
|
||||
}
|
||||
|
||||
} // namespace NEO
|
@ -22,45 +22,83 @@ struct WddmEuDebugInterfaceMock : public WddmMock {
|
||||
|
||||
NTSTATUS escape(D3DKMT_ESCAPE &escapeCommand) override {
|
||||
auto pEscapeInfo = static_cast<KM_ESCAPE_INFO *>(escapeCommand.pPrivateDriverData);
|
||||
if (pEscapeInfo->EscapeOperation == KM_ESCAPE_EUDBG_UMD_REGISTER_ALLOCATION_TYPE) {
|
||||
++registerAllocationTypeCalled;
|
||||
GFX_ALLOCATION_DEBUG_DATA_INFO *allocDataInfo = reinterpret_cast<GFX_ALLOCATION_DEBUG_DATA_INFO *>(pEscapeInfo->KmEuDbgUmdRegisterAllocationData.DebugDataBufferPtr);
|
||||
registerAllocationTypePassedParams.allocDataSize = allocDataInfo->DataSize;
|
||||
memcpy_s(registerAllocationTypePassedParams.allocData, 100, reinterpret_cast<uint8_t *>(allocDataInfo->DataPointer), allocDataInfo->DataSize);
|
||||
return ntStatus;
|
||||
}
|
||||
|
||||
if (pEscapeInfo->EscapeOperation != KM_ESCAPE_EUDBG_L0_DBGUMD_HANDLER) {
|
||||
return escapeStatus;
|
||||
return ntStatus;
|
||||
}
|
||||
|
||||
++dbgUmdEscapeActionCalled[pEscapeInfo->KmEuDbgL0EscapeInfo.EscapeActionType];
|
||||
|
||||
pEscapeInfo->KmEuDbgL0EscapeInfo.EscapeReturnStatus = escapeReturnStatus;
|
||||
switch (pEscapeInfo->KmEuDbgL0EscapeInfo.EscapeActionType) {
|
||||
case DBGUMD_ACTION_ATTACH_DEBUGGER: {
|
||||
pEscapeInfo->KmEuDbgL0EscapeInfo.EscapeReturnStatus = DBGUMD_RETURN_ESCAPE_SUCCESS;
|
||||
pEscapeInfo->KmEuDbgL0EscapeInfo.AttachDebuggerParams.hDebugHandle = debugHandle;
|
||||
break;
|
||||
}
|
||||
case DBGUMD_ACTION_DETACH_DEBUGGER:
|
||||
break;
|
||||
case DBGUMD_ACTION_READ_EVENT: {
|
||||
pEscapeInfo->KmEuDbgL0EscapeInfo.EscapeReturnStatus = readEventOutParams.escapeReturnStatus;
|
||||
if (DBGUMD_RETURN_READ_EVENT_TIMEOUT_EXPIRED == pEscapeInfo->KmEuDbgL0EscapeInfo.EscapeReturnStatus) {
|
||||
if (curEvent >= numEvents) {
|
||||
// KMD event queue is empty
|
||||
pEscapeInfo->KmEuDbgL0EscapeInfo.EscapeReturnStatus = DBGUMD_RETURN_READ_EVENT_TIMEOUT_EXPIRED;
|
||||
break;
|
||||
}
|
||||
pEscapeInfo->KmEuDbgL0EscapeInfo.ReadEventParams.ReadEventType = readEventOutParams.readEventType;
|
||||
|
||||
pEscapeInfo->KmEuDbgL0EscapeInfo.EscapeReturnStatus = eventQueue[curEvent].escapeReturnStatus;
|
||||
pEscapeInfo->KmEuDbgL0EscapeInfo.ReadEventParams.ReadEventType = eventQueue[curEvent].readEventType;
|
||||
auto paramBuffer = reinterpret_cast<uint8_t *>(pEscapeInfo->KmEuDbgL0EscapeInfo.ReadEventParams.EventParamBufferPtr);
|
||||
memcpy_s(paramBuffer, pEscapeInfo->KmEuDbgL0EscapeInfo.ReadEventParams.EventParamsBufferSize, &readEventOutParams.eventParamsBuffer, sizeof(READ_EVENT_PARAMS_BUFFER));
|
||||
memcpy_s(paramBuffer, pEscapeInfo->KmEuDbgL0EscapeInfo.ReadEventParams.EventParamsBufferSize, &eventQueue[curEvent].eventParamsBuffer, sizeof(READ_EVENT_PARAMS_BUFFER));
|
||||
return eventQueue[curEvent++].ntStatus;
|
||||
}
|
||||
case DBGUMD_ACTION_READ_ALLOCATION_DATA: {
|
||||
pEscapeInfo->KmEuDbgL0EscapeInfo.EscapeReturnStatus = readAllocationDataOutParams.escapeReturnStatus;
|
||||
if (readAllocationDataOutParams.outData != nullptr) {
|
||||
auto outBuffer = reinterpret_cast<uint8_t *>(pEscapeInfo->KmEuDbgL0EscapeInfo.ReadAdditionalAllocDataParams.OutputBufferPtr);
|
||||
memcpy_s(outBuffer, pEscapeInfo->KmEuDbgL0EscapeInfo.ReadAdditionalAllocDataParams.OutputBufferSize, readAllocationDataOutParams.outData, readAllocationDataOutParams.outDataSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return escapeStatus;
|
||||
return ntStatus;
|
||||
};
|
||||
|
||||
uint32_t numEvents = 0;
|
||||
uint32_t curEvent = 0;
|
||||
struct {
|
||||
NTSTATUS ntStatus = STATUS_SUCCESS;
|
||||
EUDBG_L0DBGUMD_ESCAPE_RETURN_TYPE escapeReturnStatus = DBGUMD_RETURN_ESCAPE_SUCCESS;
|
||||
EUDBG_DBGUMD_READ_EVENT_TYPE readEventType = DBGUMD_READ_EVENT_MAX;
|
||||
union {
|
||||
READ_EVENT_PARAMS_BUFFER eventParamsBuffer;
|
||||
uint8_t rawBytes[READ_EVENT_PARAMS_BUFFER_MIN_SIZE_BYTES] = {0};
|
||||
} eventParamsBuffer;
|
||||
} eventQueue[10] = {0};
|
||||
|
||||
struct {
|
||||
EUDBG_L0DBGUMD_ESCAPE_RETURN_TYPE escapeReturnStatus = DBGUMD_RETURN_ESCAPE_SUCCESS;
|
||||
EUDBG_DBGUMD_READ_EVENT_TYPE readEventType = DBGUMD_READ_EVENT_MAX;
|
||||
READ_EVENT_PARAMS_BUFFER eventParamsBuffer = {0};
|
||||
} readEventOutParams;
|
||||
void *outData = nullptr;
|
||||
size_t outDataSize = 0;
|
||||
} readAllocationDataOutParams;
|
||||
|
||||
struct {
|
||||
uint32_t allocDataSize = 0;
|
||||
uint32_t allocData[100] = {0};
|
||||
} registerAllocationTypePassedParams;
|
||||
|
||||
bool debugAttachAvailable = true;
|
||||
NTSTATUS escapeStatus = STATUS_SUCCESS;
|
||||
NTSTATUS ntStatus = STATUS_SUCCESS;
|
||||
uint32_t escapeReturnStatus = DBGUMD_RETURN_ESCAPE_SUCCESS;
|
||||
|
||||
uint64_t debugHandle = 0x0DEB0DEB;
|
||||
uint32_t dbgUmdEscapeActionCalled[DBGUMD_ACTION_MAX] = {0};
|
||||
uint32_t registerAllocationTypeCalled = 0;
|
||||
};
|
||||
|
||||
} // namespace NEO
|
||||
|
Reference in New Issue
Block a user