You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/CryEngine/RenderDll/XRenderD3D9/D3DDebug.cpp

222 lines
6.5 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Control D3D debug runtime output
#include "RenderDll_precompiled.h"
#include "D3DDebug.h"
#if defined(SUPPORT_D3D_DEBUG_RUNTIME)
CD3DDebug::CD3DDebug()
{
m_pd3dDebugQueue = NULL;
m_nNumCurrBreakOnIDs = 0;
}
CD3DDebug::~CD3DDebug()
{
Release();
}
bool CD3DDebug::Init(ID3D11Device* pD3DDevice)
{
Release();
if (!pD3DDevice)
{
return false;
}
if (FAILED(pD3DDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&m_pd3dDebugQueue)))
{
return false;
}
m_pd3dDebugQueue->PushEmptyStorageFilter();
m_pd3dDebugQueue->AddApplicationMessage(D3D11_MESSAGE_SEVERITY_INFO, "Application D3D Debug Layer initialized");
return true;
}
void CD3DDebug::Release()
{
if (m_pd3dDebugQueue)
{
m_pd3dDebugQueue->AddApplicationMessage(D3D11_MESSAGE_SEVERITY_INFO, "Application D3D Debug Layer deinitialized");
m_pd3dDebugQueue->PopStorageFilter();
}
SAFE_RELEASE(m_pd3dDebugQueue);
}
void CD3DDebug::Update(ESeverityCombination muteSeverity, const char* strMuteMsgList, const char* strBreakOnMsgList)
{
if (!m_pd3dDebugQueue)
{
return;
}
m_pd3dDebugQueue->ClearStorageFilter();
/////////////////////////
// Severity based mute //
/////////////////////////
D3D11_MESSAGE_SEVERITY severityList[4] = { D3D11_MESSAGE_SEVERITY_INFO };
UINT nNumSeverities = 0;
switch (muteSeverity)
{
case ESeverity_Info:
severityList[0] = D3D11_MESSAGE_SEVERITY_INFO;
nNumSeverities = 1;
break;
case ESeverity_InfoWarning:
severityList[0] = D3D11_MESSAGE_SEVERITY_INFO;
severityList[1] = D3D11_MESSAGE_SEVERITY_WARNING;
nNumSeverities = 2;
break;
case ESeverity_InfoWarningError:
severityList[0] = D3D11_MESSAGE_SEVERITY_INFO;
severityList[1] = D3D11_MESSAGE_SEVERITY_WARNING;
severityList[2] = D3D11_MESSAGE_SEVERITY_ERROR;
nNumSeverities = 3;
break;
case ESeverity_All:
severityList[0] = D3D11_MESSAGE_SEVERITY_INFO;
severityList[1] = D3D11_MESSAGE_SEVERITY_WARNING;
severityList[2] = D3D11_MESSAGE_SEVERITY_ERROR;
severityList[3] = D3D11_MESSAGE_SEVERITY_CORRUPTION;
nNumSeverities = 4;
break;
}
///////////////////
// ID based mute //
///////////////////
D3D11_MESSAGE_ID msgIDsList[MAX_NUM_DEBUG_MSG_IDS] = { D3D11_MESSAGE_ID_UNKNOWN };
UINT nNumIDs = ParseIDs(strMuteMsgList, msgIDsList);
D3D11_INFO_QUEUE_FILTER filterQueue;
ZeroStruct(filterQueue);
filterQueue.DenyList.pSeverityList = severityList;
filterQueue.DenyList.NumSeverities = nNumSeverities;
filterQueue.DenyList.pIDList = msgIDsList;
filterQueue.DenyList.NumIDs = nNumIDs;
m_pd3dDebugQueue->AddStorageFilterEntries(&filterQueue);
////////////////////////////
// Break on functionality //
////////////////////////////
// First disable break for old entries
for (UINT i = 0; i < m_nNumCurrBreakOnIDs; ++i)
{
m_pd3dDebugQueue->SetBreakOnID(m_arrBreakOnIDsList[i], FALSE);
}
m_nNumCurrBreakOnIDs = 0;
const int nVal = atoi(strBreakOnMsgList);
if (nVal == -1)
{
// Break on all errors
m_pd3dDebugQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, TRUE);
m_pd3dDebugQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, TRUE);
}
else
{
// Break on specified messages
m_pd3dDebugQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, FALSE);
m_pd3dDebugQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, FALSE);
m_nNumCurrBreakOnIDs = ParseIDs(strBreakOnMsgList, m_arrBreakOnIDsList);
for (UINT i = 0; i < m_nNumCurrBreakOnIDs; ++i)
{
m_pd3dDebugQueue->SetBreakOnID(m_arrBreakOnIDsList[i], TRUE);
}
}
}
UINT CD3DDebug::ParseIDs(const char* strMsgIDList, D3D11_MESSAGE_ID arrMsgList[MAX_NUM_DEBUG_MSG_IDS]) const
{
const size_t nLen = strlen(strMsgIDList);
UINT nIDs = 0;
const char* pStart = strMsgIDList;
char* pEnd;
UINT nValID = 1;
while (nValID != 0 && nIDs < MAX_NUM_DEBUG_MSG_IDS)
{
nValID = UINT(strtol(pStart, &pEnd, 10));
if (nValID)
{
arrMsgList[nIDs] = D3D11_MESSAGE_ID(nValID);
pStart = pEnd;
nIDs++;
}
}
return nIDs;
}
string CD3DDebug::GetLastMessage()
{
string res;
ID3D11InfoQueue* pQueue = GetDebugInfoQueue();
if (pQueue)
{
const UINT64 numMsg = pQueue->GetNumStoredMessages();
if (numMsg)
{
const UINT64 lastMsg = numMsg - 1;
SIZE_T msgLen = 0;
if (SUCCEEDED(pQueue->GetMessage(lastMsg, 0, &msgLen)))
{
D3D11_MESSAGE* pMsg = (D3D11_MESSAGE*) CryModuleMalloc(msgLen);
if (SUCCEEDED(pQueue->GetMessage(lastMsg, pMsg, &msgLen)))
{
const char* pFmt = 0;
switch (pMsg->Severity)
{
case D3D11_MESSAGE_SEVERITY_CORRUPTION:
pFmt = "D3D11 Corruption #%d: ";
break;
case D3D11_MESSAGE_SEVERITY_ERROR:
pFmt = "D3D11 Error #%d: ";
break;
case D3D11_MESSAGE_SEVERITY_WARNING:
pFmt = "D3D11 Warning #%d: ";
break;
case D3D11_MESSAGE_SEVERITY_INFO:
pFmt = "D3D11 Info #%d: ";
break;
}
char buf[32];
sprintf_s(buf, pFmt, pMsg->ID);
res += buf;
res += pMsg->pDescription;
}
CryModuleFree(pMsg);
}
}
}
if (res.empty())
{
res = string("No message queued. Debug runtime might be inactive or not installed.");
}
return res;
}
#endif