Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DirectX 11 Debug Layer Capture Error Strings

I have the DirectX Debug Layer working and it outputs errors and warnings to the output window in visual studio. Like this for example (not the actual issue I'm facing):

D3D11 WARNING: ID3D11DeviceContext::OMSetRenderTargets: Resource being set to OM RenderTarget slot 0 is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD]

I have a custom logging system that saves to files and prints in other windows. I'd like to capture the debug message strings, and display them in my own way. Is this supported? If so how do I do it?

like image 513
DavidColson Avatar asked Oct 20 '25 02:10

DavidColson


2 Answers

Since I had this problem myself and found the previous answer a bit lackluster, I want to give a more detailed solution, now that I've got this working:

All API calls I will reference can be found here

One can get messages out of DirectX11 by reading them from an internal message queue, that can be accessed by calling ID3D11InfoQueue::GetMessage, which takes the index of the message to get and fills a provided buffer with a D3D11_MESSAGE struct, that contains all the wanted information (Severity, Category, ID and Text).

However, I discovered that this buffer was empty (by calling 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, which pushes a filter that doesn't filter out any messages:

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

This filtering is the part that is actually discussed in the blog post that is linked in Chuck Walbourn's answer (allthough the link only directs me to the main page, the actual blog post is here). It doesn't contain any info on how to redirect the messages though.

Once the messages are generated, you can iterate over them like so:

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 is the ID3D11InfoQueue interface and can be obtained like so:

ID3D11InfoQueue* debug_info_queue;
device->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&debug_info_queue);
like image 149
pulp_user Avatar answered Oct 22 '25 18:10

pulp_user


You use the ID3D11InfoQueue interface to implement your own debug message output.

using Microsoft::WRL::ComPtr;

ComPtr<ID3D11Debug> d3dDebug;
if (SUCCEEDED(device.As(&d3dDebug)))
{
    ComPtr<ID3D11InfoQueue> d3dInfoQueue;
    if (SUCCEEDED(d3dDebug.As(&d3dInfoQueue)))
    {

See this blog post

like image 37
Chuck Walbourn Avatar answered Oct 22 '25 16:10

Chuck Walbourn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!