Skip to content

Commit

Permalink
Avoid unnecessary loading of D3D9.dll
Browse files Browse the repository at this point in the history
D3D9.dll is being loaded by ANGLE when using D3D11. This change
removes the D3D9 dependency.

- Delayload D3D9.dll using ldflags in BUILD.gn

- Replace Renderer11 usage of DebugAnnotator9 with DebugAnnotator11.
Using debug annotations with Visual Studio PIX tools now requires Windows 10.

- Refactor DebugAnnotator11 to QI ID3DUserDefinedAnnotation from the
renderer's ID3D11DeviceContext instead of making a 'null' device.

Bug: angleproject:3234
Change-Id: I10a2b537e07cda2094b08abf02b7876bbe5009f8
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1508643
Commit-Queue: Rafael Cintron <rafael.cintron@microsoft.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
  • Loading branch information
RafaelCintron authored and Commit Bot committed Mar 8, 2019
1 parent 1412650 commit b6a2f6b
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 98 deletions.
2 changes: 2 additions & 0 deletions BUILD.gn
Expand Up @@ -455,8 +455,10 @@ config("libANGLE_config") {
cflags = []
defines = []
libs = []
ldflags = []
if (angle_enable_d3d9) {
defines += [ "ANGLE_ENABLE_D3D9" ]
ldflags += [ "/DELAYLOAD:d3d9.dll" ]
}
if (angle_enable_d3d11) {
defines += [ "ANGLE_ENABLE_D3D11" ]
Expand Down
82 changes: 19 additions & 63 deletions src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
Expand Up @@ -8,35 +8,19 @@

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

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

#include <VersionHelpers.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)
{
SafeRelease(mUserDefinedAnnotation);
DebugAnnotator11::DebugAnnotator11() {}

#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
FreeLibrary(mD3d11Module);
#endif // !ANGLE_ENABLE_WINDOWS_STORE
}
}
DebugAnnotator11::~DebugAnnotator11() {}

void DebugAnnotator11::beginEvent(const char *eventName, const char *eventMessage)
{
initializeDevice();

angle::LoggingAnnotator::beginEvent(eventName, eventMessage);
if (mUserDefinedAnnotation != nullptr)
{
Expand All @@ -48,8 +32,6 @@ void DebugAnnotator11::beginEvent(const char *eventName, const char *eventMessag

void DebugAnnotator11::endEvent(const char *eventName)
{
initializeDevice();

angle::LoggingAnnotator::endEvent(eventName);
if (mUserDefinedAnnotation != nullptr)
{
Expand All @@ -59,8 +41,6 @@ void DebugAnnotator11::endEvent(const char *eventName)

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

angle::LoggingAnnotator::setMarker(markerName);
if (mUserDefinedAnnotation != nullptr)
{
Expand All @@ -72,55 +52,31 @@ void DebugAnnotator11::setMarker(const char *markerName)

bool DebugAnnotator11::getStatus()
{
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
static_assert(NTDDI_VERSION >= NTDDI_WIN10, "GetStatus only works on Win10 and above");
initializeDevice();

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

return true; // Default if initializeDevice() failed
#else
// We can't detect GetStatus() on desktop ANGLE builds so always return true.
return true;
#endif // ANGLE_ENABLE_WINDOWS_STORE
return false;
}

void DebugAnnotator11::initializeDevice()
void DebugAnnotator11::initialize(ID3D11DeviceContext *context)
{
if (!mInitialized)
// ID3DUserDefinedAnnotation.GetStatus only works on Windows10 or greater.
// Returning true unconditionally from DebugAnnotator11::getStatus() means
// writing out all compiled shaders to temporary files even if debugging
// tools are not attached. See rx::ShaderD3D::prepareSourceAndReturnOptions.
// If you want debug annotations, you must use Windows 10.
if (IsWindows10OrGreater())
{
#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(nullptr, D3D_DRIVER_TYPE_NULL, nullptr, 0, nullptr, 0,
D3D11_SDK_VERSION, &device, nullptr, &context);
ASSERT(SUCCEEDED(hr));
if (SUCCEEDED(hr))
{
mUserDefinedAnnotation =
d3d11::DynamicCastComObject<ID3DUserDefinedAnnotation>(context);
ASSERT(mUserDefinedAnnotation != nullptr);
mInitialized = true;
}

SafeRelease(device);
SafeRelease(context);
mUserDefinedAnnotation.Attach(
d3d11::DynamicCastComObject<ID3DUserDefinedAnnotation>(context));
}
}

void DebugAnnotator11::release()
{
mUserDefinedAnnotation.Reset();
}

} // namespace rx
8 changes: 3 additions & 5 deletions src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h
Expand Up @@ -19,17 +19,15 @@ class DebugAnnotator11 : public angle::LoggingAnnotator
public:
DebugAnnotator11();
~DebugAnnotator11() override;
void initialize(ID3D11DeviceContext *context);
void release();
void beginEvent(const char *eventName, const char *eventMessage) override;
void endEvent(const char *eventName) override;
void setMarker(const char *markerName) override;
bool getStatus() override;

private:
void initializeDevice();

bool mInitialized;
HMODULE mD3d11Module;
ID3DUserDefinedAnnotation *mUserDefinedAnnotation;
angle::ComPtr<ID3DUserDefinedAnnotation> mUserDefinedAnnotation;
static constexpr size_t kMaxMessageLength = 256;
wchar_t mWCharMessage[kMaxMessageLength];
};
Expand Down
35 changes: 7 additions & 28 deletions src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
Expand Up @@ -68,13 +68,6 @@
# include "libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h"
#endif

// Include the D3D9 debug annotator header for use by the desktop D3D11 renderer
// because the D3D11 interface method ID3DUserDefinedAnnotation::GetStatus
// doesn't work with the Graphics Diagnostics tools in Visual Studio 2013.
#ifdef ANGLE_ENABLE_D3D9
# include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h"
#endif

// Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process
// HWNDs or the Windows 7 Platform Update (KB2670838) is expected to be installed.
#ifndef ANGLE_SKIP_DXGI_1_2_CHECK
Expand Down Expand Up @@ -420,8 +413,7 @@ Renderer11::Renderer11(egl::Display *display)
mLastHistogramUpdateTime(
ANGLEPlatformCurrent()->monotonicallyIncreasingTime(ANGLEPlatformCurrent())),
mDebug(nullptr),
mScratchMemoryBuffer(ScratchMemoryBufferLifetime),
mAnnotator(nullptr)
mScratchMemoryBuffer(ScratchMemoryBufferLifetime)
{
mLineLoopIB = nullptr;
mTriangleFanIB = nullptr;
Expand Down Expand Up @@ -536,19 +528,6 @@ Renderer11::Renderer11(egl::Display *display)
const EGLenum presentPath = static_cast<EGLenum>(attributes.get(
EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE, EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE));
mPresentPathFastEnabled = (presentPath == EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE);

// The D3D11 renderer must choose the D3D9 debug annotator because the D3D11 interface
// method ID3DUserDefinedAnnotation::GetStatus on desktop builds doesn't work with the Graphics
// Diagnostics tools in Visual Studio 2013.
// The D3D9 annotator works properly for both D3D11 and D3D9.
// Incorrect status reporting can cause ANGLE to log unnecessary debug events.
#ifdef ANGLE_ENABLE_D3D9
mAnnotator = new DebugAnnotator9();
#else
mAnnotator = new DebugAnnotator11();
#endif
ASSERT(mAnnotator);
gl::InitializeDebugAnnotations(mAnnotator);
}

Renderer11::~Renderer11()
Expand Down Expand Up @@ -835,6 +814,9 @@ egl::Error Renderer11::initializeD3DDevice()

d3d11::SetDebugName(mDeviceContext, "DeviceContext");

mAnnotator.initialize(mDeviceContext);
gl::InitializeDebugAnnotations(&mAnnotator);

return egl::NoError();
}

Expand Down Expand Up @@ -1930,11 +1912,8 @@ void Renderer11::release()
{
mScratchMemoryBuffer.clear();

if (mAnnotator != nullptr)
{
gl::UninitializeDebugAnnotations();
SafeDelete(mAnnotator);
}
mAnnotator.release();
gl::UninitializeDebugAnnotations();

releaseDeviceResources();

Expand Down Expand Up @@ -3747,7 +3726,7 @@ gl::Version Renderer11::getMaxSupportedESVersion() const

gl::DebugAnnotator *Renderer11::getAnnotator()
{
return mAnnotator;
return &mAnnotator;
}

angle::Result Renderer11::dispatchCompute(const gl::Context *context,
Expand Down
2 changes: 1 addition & 1 deletion src/libANGLE/renderer/d3d/d3d11/Renderer11.h
Expand Up @@ -605,7 +605,7 @@ class Renderer11 : public RendererD3D

angle::ScratchBuffer mScratchMemoryBuffer;

gl::DebugAnnotator *mAnnotator;
DebugAnnotator11 mAnnotator;

mutable Optional<bool> mSupportsShareHandles;
ResourceManager11 mResourceManager11;
Expand Down
2 changes: 1 addition & 1 deletion src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
Expand Up @@ -189,7 +189,7 @@ void Renderer9::release()
egl::Error Renderer9::initialize()
{
TRACE_EVENT0("gpu.angle", "GetModuleHandle_d3d9");
mD3d9Module = GetModuleHandle(TEXT("d3d9.dll"));
mD3d9Module = ::LoadLibrary(TEXT("d3d9.dll"));

if (mD3d9Module == nullptr)
{
Expand Down

0 comments on commit b6a2f6b

Please sign in to comment.