summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
blob: 1c35ab45cc6b3f471103fb2c6ee6bbf7b06493c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DebugAnnotator11.cpp: D3D11 helpers for adding trace annotations.
//

#include "libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h"

#include "common/debug.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"

namespace rx
{

DebugAnnotator11::DebugAnnotator11()
    : mInitialized(false),
      mD3d11Module(nullptr),
      mUserDefinedAnnotation(nullptr)
{
    // D3D11 devices can't be created during DllMain.
    // We defer device creation until the object is actually used.
}

DebugAnnotator11::~DebugAnnotator11()
{
    if (mInitialized)
    {
#if defined(ANGLE_ENABLE_D3D11_1)
        SafeRelease(mUserDefinedAnnotation);
#endif

#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
        FreeLibrary(mD3d11Module);
#endif // !ANGLE_ENABLE_WINDOWS_STORE
    }
}

void DebugAnnotator11::beginEvent(const wchar_t *eventName)
{
    initializeDevice();

    if (mUserDefinedAnnotation != nullptr)
    {
#if defined(ANGLE_ENABLE_D3D11_1)
        mUserDefinedAnnotation->BeginEvent(eventName);
#endif
    }
}

void DebugAnnotator11::endEvent()
{
    initializeDevice();

    if (mUserDefinedAnnotation != nullptr)
    {
#if defined(ANGLE_ENABLE_D3D11_1)
        mUserDefinedAnnotation->EndEvent();
#endif
    }
}

void DebugAnnotator11::setMarker(const wchar_t *markerName)
{
    initializeDevice();

    if (mUserDefinedAnnotation != nullptr)
    {
#if defined(ANGLE_ENABLE_D3D11_1)
        mUserDefinedAnnotation->SetMarker(markerName);
#endif
    }
}

bool DebugAnnotator11::getStatus()
{
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
#if (NTDDI_VERSION == NTDDI_WIN10)
    initializeDevice();

    if (mUserDefinedAnnotation != nullptr)
    {
        return !!(mUserDefinedAnnotation->GetStatus());
    }

    return true;  // Default if initializeDevice() failed
#elif defined(_DEBUG) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
    static bool underCapture = true;

    // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in
    // Windows 8.1/Visual Studio 2013. We can use IDXGraphicsAnalysis, though.
    // The call to GetDebugInterface1 only succeeds if the app is under capture.
    // This should only be called in DEBUG mode.
    // If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows
    // Store ingestion checks.

    // Cache the result to reduce the number of calls to DXGIGetDebugInterface1
    static bool triedIDXGraphicsAnalysis = false;

    if (!triedIDXGraphicsAnalysis)
    {
        IDXGraphicsAnalysis *graphicsAnalysis = nullptr;

        HRESULT result = DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis));
        if (SUCCEEDED(result))
        {
            underCapture = (graphicsAnalysis != nullptr);
        }

        SafeRelease(graphicsAnalysis);
        triedIDXGraphicsAnalysis = true;
    }

    return underCapture;
#else
    // We can't detect GetStatus() on release WinRT 8.1 builds, so always return true.
    return true;
#endif  // (NTDDI_VERSION == NTDDI_WIN10) or _DEBUG
#else
    // We can't detect GetStatus() on desktop ANGLE builds so always return true.
    return true;
#endif  // ANGLE_ENABLE_WINDOWS_STORE
}

void DebugAnnotator11::initializeDevice()
{
    if (!mInitialized)
    {
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
        mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
        ASSERT(mD3d11Module);

        PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
        ASSERT(D3D11CreateDevice != nullptr);
#endif // !ANGLE_ENABLE_WINDOWS_STORE

        ID3D11Device *device = nullptr;
        ID3D11DeviceContext *context = nullptr;

        HRESULT hr = E_FAIL;

        // Create a D3D_DRIVER_TYPE_NULL device, which is much cheaper than other types of device.
        hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &device, nullptr, &context);
        ASSERT(SUCCEEDED(hr));
        if (SUCCEEDED(hr))
        {
#if defined(ANGLE_ENABLE_D3D11_1)
            mUserDefinedAnnotation = d3d11::DynamicCastComObject<ID3DUserDefinedAnnotation>(context);
            ASSERT(mUserDefinedAnnotation != nullptr);
#endif
            mInitialized = true;
        }

        SafeRelease(device);
        SafeRelease(context);
    }
}

}