Debug Layer in Direct3D 11.1 Metro Style Applications

DirectX developers might (should) be familiar with the Debug Layer. This is a piece of code that you can inject into Direct3D for debugging instrumentation. When you create a D3D device, by default – Direct3D is a very thin layer that allows you to achieve maximum performance from your API calls through the drivers to the hardware. In fact it is so thin, that when an error occurs – you only get one of few error codes. This might make you wonder why that API call you are making is failing. Did you forget to pad that constant buffer struct to a multiple of 16 bytes size? Or perhaps you passed an invalid combination of flags to that other method. Well, for years now – you could get all that information by enabling the Debug Layer, but how do you do that in the WinRT world?

In Direct3D 10 you might have used the D3D10_CREATE_DEVICE_DEBUG flag with a D3D10CreateDeviceAndSwapChain or D3D10CreateDevice call. In a D3D 11.1-based Metro style app you get an analogous D3D11_CREATE_DEVICE_DEBUG flag to pass to D3D11CreateDevice and in fact the Direct3D App project template does that for you in the Debug Solution Configuration.

#if defined(_DEBUG)
    // If the project is in a debug build, enable debugging via SDK Layers with this flag.
    creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

I believe the difference is that you used to need to something like this to trace the errors:

#include <dxerr.h> // link to dxerr.lib

HRESULT hr = CreateDevice( ... );
if( FAILED(hr) )
{
     DXTrace( __FILE__, __LINE__, hr, DXGetErrorDescription(hr), FALSE );
}

DxErr is not available in Windows 8 though. I spent some time looking for it and trying to add some tracing in DirectXHelper.h/DX::ThrowIfFailed() until I decided to check the Output Window (Ctrl+W,O) and lo and behold – there are all the helpful messages like:

D3D11 ERROR: ID3D11Device::CreateBuffer: The Dimensions are invalid. For ConstantBuffers, marked with the D3D11_BIND_CONSTANT_BUFFER BindFlag, the ByteWidth (value = 4) must be a multiple of 16.  ByteWidth must also be less than or equal to 65536 on the current driver. [ STATE_CREATION ERROR #66: CREATEBUFFER_INVALIDDIMENSIONS]

You can also tag your resources using SetPrivateData calls to get names of allocated objects when looking at memory leaks. Then there are new shader tracing APIs that you can explore. Lots of helpful tools that make developing in Direct3D a bit more sane. The gist of it though is that if you get exceptions in your Direct3D code you should look at your Output Window before doing anything else.

Advertisements
Tagged , , , , ,

2 thoughts on “Debug Layer in Direct3D 11.1 Metro Style Applications

  1. xyzzer says:

    Note – for general purpose tracing from your C++ code – you can call OutputDebugString(L”Trace”). If you build a trace line from a Platform::String – you just need to pass its ->Data.

  2. xyzzer says:

    Also – this article mentions how you would open a console window in a WinRT app:
    http://seaplusplus.com/2012/06/25/printf-debugging-in-metro-style-apps/

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: