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

时间:2018-12-02 10:13:21

标签: c++ visual-studio directx directx-11

我有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]

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

2 个答案:

答案 0 :(得分:2)

您使用ID3D11InfoQueue界面实现自己的调试消息输出。

git-svn version 2.19.2 (svn 1.9.7)

请参见this blog post

答案 1 :(得分:1)

由于我自己遇到了这个问题,并且发现前面的答案有点平淡,因此我想给出一个更详细的解决方案,因为我已经开始工作了:

我将引用的所有API调用都可以找到here

一个人可以通过从内部消息队列中读取消息来从DirectX11中获取消息,可以通过调用ID3D11InfoQueue::GetMessage来访问它,该方法将获取消息的索引以获取并用{{3填充所提供的缓冲区。 }}结构,其中包含所有所需的信息(严重性,类别,ID和文本)。

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

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

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

生成消息后,您可以像这样遍历它们:

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是here接口,可以这样获得:

ID3D11InfoQueue* debug_info_queue;
HANDLE_HRESULT(device->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&debug_info_queue));