////////////////////////////////////////////////////////////////////////////////////////////// // // // DXGIDebug.idl // // // // Contains interface definitions for the DXGI Debug Binary. // // // // Copyright (c) Microsoft Corporation. // // // ////////////////////////////////////////////////////////////////////////////////////////////// import "oaidl.idl"; import "ocidl.idl"; cpp_quote("#include ") #pragma region Application Family cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)") const UINT DXGI_DEBUG_BINARY_VERSION = 1; typedef enum DXGI_DEBUG_RLO_FLAGS { DXGI_DEBUG_RLO_SUMMARY = 0x1, DXGI_DEBUG_RLO_DETAIL = 0x2, DXGI_DEBUG_RLO_IGNORE_INTERNAL = 0x4, DXGI_DEBUG_RLO_ALL = 0x7, } DXGI_DEBUG_RLO_FLAGS; //================================================================================================================================== // // DXGI Debug Producer GUIDs // //================================================================================================================================== typedef GUID DXGI_DEBUG_ID; cpp_quote("DEFINE_GUID(DXGI_DEBUG_ALL, 0xe48ae283, 0xda80, 0x490b, 0x87, 0xe6, 0x43, 0xe9, 0xa9, 0xcf, 0xda, 0x8);") cpp_quote("DEFINE_GUID(DXGI_DEBUG_DX, 0x35cdd7fc, 0x13b2, 0x421d, 0xa5, 0xd7, 0x7e, 0x44, 0x51, 0x28, 0x7d, 0x64);") cpp_quote("DEFINE_GUID(DXGI_DEBUG_DXGI, 0x25cddaa4, 0xb1c6, 0x47e1, 0xac, 0x3e, 0x98, 0x87, 0x5b, 0x5a, 0x2e, 0x2a);") cpp_quote("DEFINE_GUID(DXGI_DEBUG_APP, 0x6cd6e01, 0x4219, 0x4ebd, 0x87, 0x9, 0x27, 0xed, 0x23, 0x36, 0xc, 0x62);") //================================================================================================================================== // // Info Queue // //================================================================================================================================== typedef enum DXGI_INFO_QUEUE_MESSAGE_CATEGORY { DXGI_INFO_QUEUE_MESSAGE_CATEGORY_UNKNOWN, DXGI_INFO_QUEUE_MESSAGE_CATEGORY_MISCELLANEOUS, DXGI_INFO_QUEUE_MESSAGE_CATEGORY_INITIALIZATION, DXGI_INFO_QUEUE_MESSAGE_CATEGORY_CLEANUP, DXGI_INFO_QUEUE_MESSAGE_CATEGORY_COMPILATION, DXGI_INFO_QUEUE_MESSAGE_CATEGORY_STATE_CREATION, DXGI_INFO_QUEUE_MESSAGE_CATEGORY_STATE_SETTING, DXGI_INFO_QUEUE_MESSAGE_CATEGORY_STATE_GETTING, DXGI_INFO_QUEUE_MESSAGE_CATEGORY_RESOURCE_MANIPULATION, DXGI_INFO_QUEUE_MESSAGE_CATEGORY_EXECUTION, DXGI_INFO_QUEUE_MESSAGE_CATEGORY_SHADER, } DXGI_INFO_QUEUE_MESSAGE_CATEGORY; typedef enum DXGI_INFO_QUEUE_MESSAGE_SEVERITY { DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_WARNING, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_INFO, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_MESSAGE } DXGI_INFO_QUEUE_MESSAGE_SEVERITY; typedef int DXGI_INFO_QUEUE_MESSAGE_ID; cpp_quote("#define DXGI_INFO_QUEUE_MESSAGE_ID_STRING_FROM_APPLICATION 0") typedef struct DXGI_INFO_QUEUE_MESSAGE { DXGI_DEBUG_ID Producer; DXGI_INFO_QUEUE_MESSAGE_CATEGORY Category; DXGI_INFO_QUEUE_MESSAGE_SEVERITY Severity; DXGI_INFO_QUEUE_MESSAGE_ID ID; [annotation("_Field_size_(DescriptionByteLength)")] const char* pDescription; SIZE_T DescriptionByteLength; } DXGI_INFO_QUEUE_MESSAGE; typedef struct DXGI_INFO_QUEUE_FILTER_DESC { UINT NumCategories; [annotation("_Field_size_(NumCategories)")] DXGI_INFO_QUEUE_MESSAGE_CATEGORY* pCategoryList; UINT NumSeverities; [annotation("_Field_size_(NumSeverities)")] DXGI_INFO_QUEUE_MESSAGE_SEVERITY* pSeverityList; UINT NumIDs; [annotation("_Field_size_(NumIDs)")] DXGI_INFO_QUEUE_MESSAGE_ID* pIDList; } DXGI_INFO_QUEUE_FILTER_DESC; // To use, memset to 0, then fill in what you need. typedef struct DXGI_INFO_QUEUE_FILTER { DXGI_INFO_QUEUE_FILTER_DESC AllowList; DXGI_INFO_QUEUE_FILTER_DESC DenyList; } DXGI_INFO_QUEUE_FILTER; cpp_quote("#define DXGI_INFO_QUEUE_DEFAULT_MESSAGE_COUNT_LIMIT 1024") cpp_quote( "HRESULT WINAPI DXGIGetDebugInterface(REFIID riid, void **ppDebug);" ) //============================================================================= // IDXGIInfoQueue // // Logs DX Messages. // This interface is a singleton per process. Debug DX devices will log messages // to this object which can be retrieved through its APIs. // // [ uuid( D67441C7-672A-476f-9E82-CD55B44949CE ), object, local, pointer_default( unique ) ] interface IDXGIInfoQueue : IUnknown { //========================================================================= // Methods for configuring how much data is stored in the queue. // SetMessageCountLimit() // This sets how many messages are stored for a given producer. When the queue // is full, new messages coming in push old messages out (for that producer). // Passing -1 to SetMessageCountLimit means the queue has // unlimited size (go until out of memory or ClearStoredMessages()). // The default message count size is DXGI_INFO_QUEUE_DEFAULT_MESSAGE_COUNT_LIMIT // Returns S_OK or E_INVALIDARG. HRESULT SetMessageCountLimit( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] UINT64 MessageCountLimit ); // ClearStoredMessages void ClearStoredMessages( [annotation("_In_")] DXGI_DEBUG_ID Producer); //========================================================================= // Methods for retrieving data or statistics from the queue. // GetMessage() // Retrieves messages, one at a time, from the queue which pass any // retrieval filter currently defined. // // Call GetMessage with (DXGI_INFO_QUEUE_PRODUCER_ALL) to get messages // from all producers. // // The MessageIndex parameter is a 0 based index into the results passing // the filter. The number of results is returned by // GetNumStoredMessagesAllowedByRetrievalFilter(). // // Note this does not remove the message from the queue. // // pMessageByteLength inputs the size of the buffer passed in via // pMessage, and outputs the size of the message. pMessage can be NULL // when the size of the required buffer is being queried (return S_FALSE). // // NOTE: The returned buffer pMessage is NOT just the size of DXGI_INFO_QUEUE_MESSAGE, // it includes extra memory after the DXGI_INFO_QUEUE_MESSAGE for storing the string // description, which is pointed to from within DXGI_INFO_QUEUE_MESSAGE. Therefore // applications should check the size needed for pMessage as described above. // // Watch out for thread safety when making consecutive calls first to // determine the buffer size required and then to pass in the buffer and // retrieve the message, and also between calling // GetNumStoredMessagesAllowedByRetrievalFilter() and enumerating through // the results via GetMessagE(). // // Returns: S_OK, S_FALSE, E_INVALIDARG or E_OUTOFMEMORY. HRESULT GetMessage( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] UINT64 MessageIndex, [annotation("_Out_writes_bytes_opt_(*pMessageByteLength)")] DXGI_INFO_QUEUE_MESSAGE* pMessage, [annotation("_Inout_")] SIZE_T* pMessageByteLength ); // GetNumStoredMessagesAllowedByRetrievalFilter() // Returns how many messages that are currently in the queue which // pass the retrieval filter. // The MessageIndex parameter to GetMessage() indexes // an array of this many results. UINT64 GetNumStoredMessagesAllowedByRetrievalFilters( [annotation("_In_")] DXGI_DEBUG_ID Producer); // GetNumStoredMessages() // Returns how many messages are currently stored in the queue for the specified producer. UINT64 GetNumStoredMessages( [annotation("_In_")] DXGI_DEBUG_ID Producer); // GetNumMessagesDiscardedByMessageCountLimit() for the specified producer. UINT64 GetNumMessagesDiscardedByMessageCountLimit( [annotation("_In_")] DXGI_DEBUG_ID Producer); // GetMessageCountLimit // This is how many messages can be stored in the queue for the specified producer. // When the queue is full, new messages coming in push old messages out. // -1 means there is no limit. UINT64 GetMessageCountLimit( [annotation("_In_")] DXGI_DEBUG_ID Producer); // GetNumMessagesAllowedByStorageFilter() // Returns how many messages sent to the queue passed // whatever storage filter was active upon receipt of // the message. // This can be a larger value than the message count limit, // returned by GetMessageCountLimit(), since old messages are discarded // when the queue is full to prevent overflow. UINT64 GetNumMessagesAllowedByStorageFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer); // GetNumMessagesDeniedByStorageFilter() UINT64 GetNumMessagesDeniedByStorageFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer); //========================================================================= // Methods for filtering what gets stored in the queue // AddStorageFilterEntries() // Adds to the existing entries at top of stack // Returns: S_OK, E_INVALIDARG or E_OUTOFMEMORY. HRESULT AddStorageFilterEntries( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] DXGI_INFO_QUEUE_FILTER* pFilter ); // GetStorageFilter() // Gets all entries at top of stack. // The application must allocate the output buffer. The size required can be // queried by passing null for pFilter and looking at the returned // pFilterByteLength (HRESULT is S_FALSE). Note that DXGI_INFO_QUEUE_FILTER contains // pointers - these will point to locations within the same // contiguous buffer - *pFilterByteLength is the total storage needed for all // data. So the application needs to only allocate/free the memory for pFilter. // Returns S_OK, S_FALSE, E_INVALIDARG or E_OUTOFMEMORY HRESULT GetStorageFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_Out_writes_bytes_opt_(*pFilterByteLength)")] DXGI_INFO_QUEUE_FILTER* pFilter, [annotation("_Inout_")] SIZE_T* pFilterByteLength ); // ClearStorageFilter() // Clears filter at the top of the stack (if there is one) void ClearStorageFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer); // PushEmptyStorageFilter() // Push an empty storage filter on the stack to allow local filtering changes. // For convenience, this is automatically called by SetStorageFilter() // if the stack is empty. Thus if the stack is not needed, filters can be // defined without ever bothering to push or pop. // Returns S_OK or E_OUTOFMEMORY HRESULT PushEmptyStorageFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer); // PushDenyAllStorageFilter() // Push a storage filter that denies all messages. This is for convience to // silence all messages from a given producer. Messages that are not stored // in the InfoQueue are not displayed to debug output. // A deny all will be a filter with all of the severities in the deny list. // Returns S_OK or E_OUTOFMEMORY HRESULT PushDenyAllStorageFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer); // PushCopyOfStorageFilter() // Push a copy of the current filter so that local modifications can be made // starting from what currently exists. // Returns S_OK or E_OUTOFMEMORY HRESULT PushCopyOfStorageFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer); // PushStorageFilter() // Push a filter passed as a parameter onto the stack. This is // just a helper for calling PushEmptyStorageFilter() followed // by AddStorageFilterEntries() // Returns S_OK, E_INVALIDARG or E_OUTOFMEMORY. HRESULT PushStorageFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] DXGI_INFO_QUEUE_FILTER* pFilter ); // PopStorageFilter() // Pop the current storage filter off the stack (if there is one) void PopStorageFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer); // GetStorageFilterStackSize() UINT GetStorageFilterStackSize( [annotation("_In_")] DXGI_DEBUG_ID Producer); //========================================================================= // Methods for filtering what gets read out of the queue by GetMessage(). // AddRetrievalFilterEntries() // Adds to the existing entries at top of stack // Returns: S_OK, E_INVALIDARG or E_OUTOFMEMORY. HRESULT AddRetrievalFilterEntries( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] DXGI_INFO_QUEUE_FILTER* pFilter ); // GetRetrievalFilter() // Gets all entries at top of stack. // The application must allocate the output buffer. The size required can be // queried by passing null for pFilter and looking at the returned // pFilterByteLength (HRESULT is S_FALSE). Note that DXGI_INFO_QUEUE_FILTER contains // pointers - these will point to locations within the same // contiguous buffer - *pFilterByteLength is the total storage needed for all // data. So the application needs to only allocate/free the memory for pFilter. // Returns S_OK, S_FALSE, E_INVALIDARG or E_OUTOFMEMORY HRESULT GetRetrievalFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_Out_writes_bytes_opt_(*pFilterByteLength)")] DXGI_INFO_QUEUE_FILTER* pFilter, [annotation("_Inout_")] SIZE_T* pFilterByteLength ); // ClearRetrievalFilter() // Clears filter at the top of the stack (if there is one) void ClearRetrievalFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer); // PushEmptyRetrievalFilter() // Push an empty retrieval filter on the stack to allow local filtering changes. // For convenience, this is automatically called by SetRetrievalFilter() // if the stack is empty. Thus if the stack is not needed, filters can be // defined without ever bothering to push or pop. // Returns S_OK or E_OUTOFMEMORY HRESULT PushEmptyRetrievalFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer); // PushDenyAllRetrievalFilter() // Push a retrieval filter that denies all messages. This is for convience to // ignore all messages from a given producer. // A deny all will be a filter with all of the severities in the deny list. // Returns S_OK or E_OUTOFMEMORY HRESULT PushDenyAllRetrievalFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer); // PushCopyOfRetrievalFilter() // Push a copy of the current filter so that local modifications can be made // starting from what currently exists. // Returns S_OK or E_OUTOFMEMORY HRESULT PushCopyOfRetrievalFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer); // PushRetrievalFilter() // Push a filter passed as a parameter onto the stack. This is // just a helper for calling PushEmptyRetrievalFilter() followed // by AddRetrievalFilterEntries() // Returns S_OK, E_INVALIDARG or E_OUTOFMEMORY. HRESULT PushRetrievalFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] DXGI_INFO_QUEUE_FILTER* pFilter ); // PopRetrievalFilter() // Pop the current storage filter off the stack (if there is one) void PopRetrievalFilter( [annotation("_In_")] DXGI_DEBUG_ID Producer); // GetRetrievalFilterStackSize() UINT GetRetrievalFilterStackSize( [annotation("_In_")] DXGI_DEBUG_ID Producer); //========================================================================= // Methods for adding entries to the queue. // AddMessage() // This is used by DX components to log messages. Nothing stops // applications from calling this, but it isn't particularly useful. // If an application wishes to insert custom strings into the queue, // AddApplicationMessage() below is suggested. See below. // // Returns S_OK, E_INVALIDARG or E_OUTOFMEMORY HRESULT AddMessage( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] DXGI_INFO_QUEUE_MESSAGE_CATEGORY Category, [annotation("_In_")] DXGI_INFO_QUEUE_MESSAGE_SEVERITY Severity, [annotation("_In_")] DXGI_INFO_QUEUE_MESSAGE_ID ID, [annotation("_In_")] LPCSTR pDescription); // AddApplicationMessage() // This is a convenience for applications that want // to insert strings of their own into the queue, perhaps to log issues // of its own, or to mark out points in time in the queue. This // has the same effect as calling AddMessage() above with the // following settings: // Category = DXGI_INFO_QUEUE_MESSAGE_CATEGORY_APPLICATION_DEFINED // Severity = // ID = DXGI_INFO_QUEUE_MESSAGE_ID_STRING_FROM_APPLICATION // pDescription = // // Returns S_OK, E_INVALIDARG or E_OUTOFMEMORY HRESULT AddApplicationMessage( [annotation("_In_")] DXGI_INFO_QUEUE_MESSAGE_SEVERITY Severity, [annotation("_In_")] LPCSTR pDescription); //========================================================================= // Methods for breaking on errors that pass the storage filter. HRESULT SetBreakOnCategory( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] DXGI_INFO_QUEUE_MESSAGE_CATEGORY Category, [annotation("_In_")] BOOL bEnable ); HRESULT SetBreakOnSeverity( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] DXGI_INFO_QUEUE_MESSAGE_SEVERITY Severity, [annotation("_In_")] BOOL bEnable ); HRESULT SetBreakOnID( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] DXGI_INFO_QUEUE_MESSAGE_ID ID, [annotation("_In_")] BOOL bEnable ); BOOL GetBreakOnCategory( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] DXGI_INFO_QUEUE_MESSAGE_CATEGORY Category ); BOOL GetBreakOnSeverity( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] DXGI_INFO_QUEUE_MESSAGE_SEVERITY Severity ); BOOL GetBreakOnID( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] DXGI_INFO_QUEUE_MESSAGE_ID ID ); //========================================================================= // Methods for muting debug spew from the InfoQueue void SetMuteDebugOutput( [annotation("_In_")] DXGI_DEBUG_ID Producer, [annotation("_In_")] BOOL bMute ); BOOL GetMuteDebugOutput( [annotation("_In_")] DXGI_DEBUG_ID Producer); }; [ uuid(119E7452-DE9E-40fe-8806-88F90C12B441), object, local, pointer_default( unique ) ] interface IDXGIDebug : IUnknown { HRESULT ReportLiveObjects(GUID apiid, DXGI_DEBUG_RLO_FLAGS flags); }; [ uuid(c5a05f0c-16f2-4adf-9f4d-a8c4d58ac550), object, local, pointer_default( unique ) ] interface IDXGIDebug1 : IDXGIDebug { void EnableLeakTrackingForThread(); void DisableLeakTrackingForThread(); BOOL IsLeakTrackingEnabledForThread(); }; cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */") #pragma endregion #pragma region Desktop Family cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)") cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */") #pragma endregion cpp_quote( "DEFINE_GUID(IID_IDXGIInfoQueue,0xD67441C7,0x672A,0x476f,0x9E,0x82,0xCD,0x55,0xB4,0x49,0x49,0xCE);" ) cpp_quote( "DEFINE_GUID(IID_IDXGIDebug,0x119E7452,0xDE9E,0x40fe,0x88,0x06,0x88,0xF9,0x0C,0x12,0xB4,0x41);" ) cpp_quote( "DEFINE_GUID(IID_IDXGIDebug1,0xc5a05f0c,0x16f2,0x4adf,0x9f,0x4d,0xa8,0xc4,0xd5,0x8a,0xc5,0x50);" )