/*
 * Copyright 2015 Steve Lhomme
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

import "oaidl.idl";

const UINT DXGI_DEBUG_BINARY_VERSION = 1;

typedef GUID DXGI_DEBUG_ID;

cpp_quote("DEFINE_GUID(DXGI_DEBUG_ALL,   0xe48ae283, 0xda80, 0x490b,0x87, 0xe6, 0x43, 0xe9, 0xa9, 0xcf, 0xda, 0x08);")
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,   0x06cd6e01, 0x4219, 0x4ebd,0x87, 0x90, 0x27, 0xed, 0x23, 0x36, 0x0c, 0x62);")

typedef enum DXGI_DEBUG_RLO_FLAGS {
    DXGI_DEBUG_RLO_SUMMARY         = 0x0001,
    DXGI_DEBUG_RLO_DETAIL          = 0x0002,
    DXGI_DEBUG_RLO_IGNORE_INTERNAL = 0x0004,
    DXGI_DEBUG_RLO_ALL             = 0x0007
} DXGI_DEBUG_RLO_FLAGS;

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;
    const char *pDescription;
    SIZE_T DescriptionByteLength;
} DXGI_INFO_QUEUE_MESSAGE;

typedef struct DXGI_INFO_QUEUE_FILTER_DESC {
    UINT NumCategories;
    DXGI_INFO_QUEUE_MESSAGE_CATEGORY *pCategoryList;
    UINT NumSeverities;
    DXGI_INFO_QUEUE_MESSAGE_SEVERITY *pSeverityList;
    UINT NumIDs;
    DXGI_INFO_QUEUE_MESSAGE_ID *pIDList;
} DXGI_INFO_QUEUE_FILTER_DESC;

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);")

[
    uuid(d67441c7-672a-476f-9e82-cd55b44949ce),
    object,
    local,
    pointer_default(unique)
]
interface IDXGIInfoQueue : IUnknown
{
    HRESULT SetMessageCountLimit(
        [in] DXGI_DEBUG_ID producer,
        [in] UINT64 limit);

    void ClearStoredMessages(
        [in] DXGI_DEBUG_ID producer);

    HRESULT GetMessage(
        [in] DXGI_DEBUG_ID producer,
        [in] UINT64 index,
        [out] DXGI_INFO_QUEUE_MESSAGE *message,
        [in, out] SIZE_T *length);

    UINT64 GetNumStoredMessagesAllowedByRetrievalFilters(
        [in] DXGI_DEBUG_ID producer);

    UINT64 GetNumStoredMessages(
        [in] DXGI_DEBUG_ID producer);

    UINT64 GetNumMessagesDiscardedByMessageCountLimit(
        [in] DXGI_DEBUG_ID producer);

    UINT64 GetMessageCountLimit(
        [in] DXGI_DEBUG_ID producer);

    UINT64 GetNumMessagesAllowedByStorageFilter(
        [in] DXGI_DEBUG_ID producer);

    UINT64 GetNumMessagesDeniedByStorageFilter(
        [in] DXGI_DEBUG_ID producer);

    HRESULT AddStorageFilterEntries(
        [in] DXGI_DEBUG_ID producer,
        [in] DXGI_INFO_QUEUE_FILTER *filter);

    HRESULT GetStorageFilter(
        [in] DXGI_DEBUG_ID producer,
        [out] DXGI_INFO_QUEUE_FILTER *filter,
        [in, out] SIZE_T *length);

    void ClearStorageFilter(
        [in] DXGI_DEBUG_ID producer);

    HRESULT PushEmptyStorageFilter(
        [in] DXGI_DEBUG_ID producer);

    HRESULT PushDenyAllStorageFilter(
        [in] DXGI_DEBUG_ID producer);

    HRESULT PushCopyOfStorageFilter(
        [in] DXGI_DEBUG_ID producer);

    HRESULT PushStorageFilter(
        [in] DXGI_DEBUG_ID producer,
        [in] DXGI_INFO_QUEUE_FILTER *filter);

    void PopStorageFilter(
        [in] DXGI_DEBUG_ID producer);

    UINT GetStorageFilterStackSize(
        [in] DXGI_DEBUG_ID producer);

    HRESULT AddRetrievalFilterEntries(
        [in] DXGI_DEBUG_ID producer,
        [in] DXGI_INFO_QUEUE_FILTER *filter);

    HRESULT GetRetrievalFilter(
        [in] DXGI_DEBUG_ID producer,
        [out] DXGI_INFO_QUEUE_FILTER *filter,
        [in, out] SIZE_T *length);

    void ClearRetrievalFilter(
        [in] DXGI_DEBUG_ID producer);

    HRESULT PushEmptyRetrievalFilter(
        [in] DXGI_DEBUG_ID producer);

    HRESULT PushDenyAllRetrievalFilter(
        [in] DXGI_DEBUG_ID producer);

    HRESULT PushCopyOfRetrievalFilter(
        [in] DXGI_DEBUG_ID producer);

    HRESULT PushRetrievalFilter(
        [in] DXGI_DEBUG_ID producer,
        [in] DXGI_INFO_QUEUE_FILTER *filter);

    void PopRetrievalFilter(
        [in] DXGI_DEBUG_ID producer);

    UINT GetRetrievalFilterStackSize(
        [in] DXGI_DEBUG_ID producer);

    HRESULT AddMessage(
        [in] DXGI_DEBUG_ID producer,
        [in] DXGI_INFO_QUEUE_MESSAGE_CATEGORY category,
        [in] DXGI_INFO_QUEUE_MESSAGE_SEVERITY severity,
        [in] DXGI_INFO_QUEUE_MESSAGE_ID id,
        [in] LPCSTR description);

    HRESULT AddApplicationMessage(
        [in] DXGI_INFO_QUEUE_MESSAGE_SEVERITY severity,
        [in] LPCSTR description);

    HRESULT SetBreakOnCategory(
        [in] DXGI_DEBUG_ID producer,
        [in] DXGI_INFO_QUEUE_MESSAGE_CATEGORY category,
        [in] BOOL enable);

    HRESULT SetBreakOnSeverity(
        [in] DXGI_DEBUG_ID producer,
        [in] DXGI_INFO_QUEUE_MESSAGE_SEVERITY severity,
        [in] BOOL enable);

    HRESULT SetBreakOnID(
        [in] DXGI_DEBUG_ID producer,
        [in] DXGI_INFO_QUEUE_MESSAGE_ID id,
        [in] BOOL enable);

    BOOL GetBreakOnCategory(
        [in] DXGI_DEBUG_ID producer,
        [in] DXGI_INFO_QUEUE_MESSAGE_CATEGORY category);

    BOOL GetBreakOnSeverity(
        [in] DXGI_DEBUG_ID producer,
        [in] DXGI_INFO_QUEUE_MESSAGE_SEVERITY severity);

    BOOL GetBreakOnID(
        [in] DXGI_DEBUG_ID producer,
        [in] DXGI_INFO_QUEUE_MESSAGE_ID id);

    void SetMuteDebugOutput(
        [in] DXGI_DEBUG_ID producer,
        [in] BOOL mute);

    BOOL GetMuteDebugOutput(
        [in] DXGI_DEBUG_ID producer);
}

[
    object,
    local,
    uuid(119e7452-de9e-40fe-8806-88f90c12b441)
]
interface IDXGIDebug : IUnknown
{
    HRESULT ReportLiveObjects(
        [in] GUID apiid,
        [in] 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();
}