DirectX 11 调试层捕获错误字符串
DirectX 11 Debug Layer Capture Error Strings
我的 DirectX 调试层在工作,它向 visual studio 中的输出 window 输出错误和警告。例如这样(不是我面临的实际问题):
D3D11 WARNING: ID3D11DeviceContext::OMSetRenderTargets: Resource being set to OM RenderTarget slot 0 is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD]
我有一个自定义日志记录系统,可以保存到文件并在其他 windows 中打印。我想捕获调试消息字符串,并以我自己的方式显示它们。这受支持吗?如果可以,我该怎么做?
您使用ID3D11InfoQueue接口来实现您自己的调试消息输出。
using Microsoft::WRL::ComPtr;
ComPtr<ID3D11Debug> d3dDebug;
if (SUCCEEDED(device.As(&d3dDebug)))
{
ComPtr<ID3D11InfoQueue> d3dInfoQueue;
if (SUCCEEDED(d3dDebug.As(&d3dInfoQueue)))
{
由于我自己也遇到了这个问题,觉得之前的回答有点乏味,所以我想给出更详细的解决方案,现在我已经解决了:
我将参考的所有 API 个调用都可以找到 here
可以通过从内部消息队列中读取消息来从 DirectX11 中获取消息,可以通过调用 ID3D11InfoQueue::GetMessage, which takes the index of the message to get and fills a provided buffer with a D3D11_MESSAGE 结构访问该队列,该结构包含所有需要的信息(严重性、类别、ID 和文本)。
但是,我发现这个缓冲区是空的(通过调用 ID3D11InfoQueue::GetNumStoredMessages) when I tried to iterate over it. That seemed to be due to some filtering going on. In order for the runtime to actually fill this buffer, I first had to call ID3D11InfoQueue::PushEmptyStorageFilter,它推送一个不过滤掉任何消息的过滤器:
//HANDLE_HRESULT is just a macro of mine to check for S_OK return value
HANDLE_HRESULT(debug_info_queue->PushEmptyStorageFilter());
此过滤是博客 post 中实际讨论的部分,在 Chuck Walbourn 的回答中 link 编辑(尽管 link 仅将我定向到主页,实际博客 post 是 here)。不过,它不包含有关如何重定向消息的任何信息。
生成消息后,您可以像这样迭代它们:
UINT64 message_count = debug_info_queue->GetNumStoredMessages();
for(UINT64 i = 0; i < message_count; i++){
SIZE_T message_size = 0;
debug_info_queue->GetMessage(i, nullptr, &message_size); //get the size of the message
D3D11_MESSAGE* message = (D3D11_MESSAGE*) malloc(message_size); //allocate enough space
HANDLE_HRESULT(debug_info_queue->GetMessage(i, message, &message_size)); //get the actual message
//do whatever you want to do with it
printf("Directx11: %.*s", message->DescriptionByteLength, message->pDescription);
free(message);
}
debug_info_queue->ClearStoredMessages();
debug_info_queue是ID3D11InfoQueue接口,可以这样获取:
ID3D11InfoQueue* debug_info_queue;
HANDLE_HRESULT(device->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&debug_info_queue));
我的 DirectX 调试层在工作,它向 visual studio 中的输出 window 输出错误和警告。例如这样(不是我面临的实际问题):
D3D11 WARNING: ID3D11DeviceContext::OMSetRenderTargets: Resource being set to OM RenderTarget slot 0 is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD]
我有一个自定义日志记录系统,可以保存到文件并在其他 windows 中打印。我想捕获调试消息字符串,并以我自己的方式显示它们。这受支持吗?如果可以,我该怎么做?
您使用ID3D11InfoQueue接口来实现您自己的调试消息输出。
using Microsoft::WRL::ComPtr;
ComPtr<ID3D11Debug> d3dDebug;
if (SUCCEEDED(device.As(&d3dDebug)))
{
ComPtr<ID3D11InfoQueue> d3dInfoQueue;
if (SUCCEEDED(d3dDebug.As(&d3dInfoQueue)))
{
由于我自己也遇到了这个问题,觉得之前的回答有点乏味,所以我想给出更详细的解决方案,现在我已经解决了:
我将参考的所有 API 个调用都可以找到 here
可以通过从内部消息队列中读取消息来从 DirectX11 中获取消息,可以通过调用 ID3D11InfoQueue::GetMessage, which takes the index of the message to get and fills a provided buffer with a D3D11_MESSAGE 结构访问该队列,该结构包含所有需要的信息(严重性、类别、ID 和文本)。
但是,我发现这个缓冲区是空的(通过调用 ID3D11InfoQueue::GetNumStoredMessages) when I tried to iterate over it. That seemed to be due to some filtering going on. In order for the runtime to actually fill this buffer, I first had to call ID3D11InfoQueue::PushEmptyStorageFilter,它推送一个不过滤掉任何消息的过滤器:
//HANDLE_HRESULT is just a macro of mine to check for S_OK return value
HANDLE_HRESULT(debug_info_queue->PushEmptyStorageFilter());
此过滤是博客 post 中实际讨论的部分,在 Chuck Walbourn 的回答中 link 编辑(尽管 link 仅将我定向到主页,实际博客 post 是 here)。不过,它不包含有关如何重定向消息的任何信息。
生成消息后,您可以像这样迭代它们:
UINT64 message_count = debug_info_queue->GetNumStoredMessages();
for(UINT64 i = 0; i < message_count; i++){
SIZE_T message_size = 0;
debug_info_queue->GetMessage(i, nullptr, &message_size); //get the size of the message
D3D11_MESSAGE* message = (D3D11_MESSAGE*) malloc(message_size); //allocate enough space
HANDLE_HRESULT(debug_info_queue->GetMessage(i, message, &message_size)); //get the actual message
//do whatever you want to do with it
printf("Directx11: %.*s", message->DescriptionByteLength, message->pDescription);
free(message);
}
debug_info_queue->ClearStoredMessages();
debug_info_queue是ID3D11InfoQueue接口,可以这样获取:
ID3D11InfoQueue* debug_info_queue;
HANDLE_HRESULT(device->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&debug_info_queue));