DirectX 11 调试层捕获错误字符串

Dav*_*son 4 c++ directx directx-11 visual-studio

我的 DirectX 调试层正在运行,它会将错误和警告输出到 Visual Studio 中的输出窗口。例如这样(不是我面临的实际问题):

D3D11 WARNING: ID3D11DeviceContext::OMSetRenderTargets: Resource being set to OM RenderTarget slot 0 is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD]
Run Code Online (Sandbox Code Playgroud)

我有一个自定义日志记录系统,可以保存到文件并在其他窗口中打印。我想捕获调试消息字符串,并以我自己的方式显示它们。支持吗?如果是这样我该怎么做?

pul*_*ser 9

由于我自己也遇到了这个问题,并且发现之前的答案有点乏善可陈,所以我想给出一个更详细的解决方案,现在我已经完成了这个工作:

我将参考的所有 API 调用都可以在这里找到

可以通过从内部消息队列读取消息来从 DirectX11 中获取消息,可以通过调用ID3D11InfoQueue::GetMessage来访问该消息,该消息获取要获取的消息的索引,并使用D3D11_MESSAGE结构填充提供的缓冲区,该结构包含所有消息想要的信息(严重性、类别、ID 和文本)。

但是,当我尝试迭代该缓冲区时,我发现该缓冲区是空的(通过调用ID3D11InfoQueue::GetNumStoredMessages )。这似乎是由于正在进行一些过滤。为了让运行时实际填充此缓冲区,我首先必须调用ID3D11InfoQueue::PushEmptyStorageFilter,它会推送一个不过滤任何消息的过滤器:

//HANDLE_HRESULT is just a macro of mine to check for S_OK return value
HANDLE_HRESULT(debug_info_queue->PushEmptyStorageFilter());
Run Code Online (Sandbox Code Playgroud)

这种过滤是 Chuck Walbourn 的答案中链接的博客文章中实际讨论的部分(尽管该链接仅将我定向到主页,但实际的博客文章在这里)。但它不包含任何有关如何重定向消息的信息。

生成消息后,您可以像这样迭代它们:

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();
Run Code Online (Sandbox Code Playgroud)

debug_info_queue 是ID3D11InfoQueue接口,可以像这样获取:

ID3D11InfoQueue* debug_info_queue;
device->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&debug_info_queue);
Run Code Online (Sandbox Code Playgroud)


Chu*_*urn 5

您可以使用ID3D11InfoQueue接口来实现您自己的调试消息输出。

using Microsoft::WRL::ComPtr;

ComPtr<ID3D11Debug> d3dDebug;
if (SUCCEEDED(device.As(&d3dDebug)))
{
    ComPtr<ID3D11InfoQueue> d3dInfoQueue;
    if (SUCCEEDED(d3dDebug.As(&d3dInfoQueue)))
    {
Run Code Online (Sandbox Code Playgroud)

请参阅这篇博文