diff --git a/docs/DebugMarkers.md b/docs/DebugMarkers.md index da11dfaa96..e33d5b8350 100644 --- a/docs/DebugMarkers.md +++ b/docs/DebugMarkers.md @@ -27,7 +27,9 @@ To enable marker functionality, you must: You may now call the debug marker APIs mentioned above and see them from your GPU debugging tool. When using your tool, it is supported to both launch your application with the debugger attached, or attach the debugger while your application is running. -D3D12 debug markers have been tested with [Microsoft PIX](https://blogs.msdn.microsoft.com/pix/download/) and [Intel Graphics Frame Analyzer](https://software.intel.com/en-us/gpa/graphics-frame-analyzer). +D3D12 debug markers have been tested with [Microsoft PIX](https://devblogs.microsoft.com/pix/) and [Intel Graphics Frame Analyzer](https://software.intel.com/en-us/gpa/graphics-frame-analyzer). + +Unfortunately, PIX's UI does does not lend itself to capturing single frame applications like tests. You must enable capture from within your application. To do this in Dawn tests, pass the --begin-capture-on-startup flag to dawn_end2end_tests.exe. ## Vulkan diff --git a/src/dawn_native/DawnNative.cpp b/src/dawn_native/DawnNative.cpp index 90a332f643..08c9587f0a 100644 --- a/src/dawn_native/DawnNative.cpp +++ b/src/dawn_native/DawnNative.cpp @@ -103,7 +103,16 @@ namespace dawn_native { mImpl->EnableBackendValidation(enableBackendValidation); } - bool Instance::IsBackendValidationEnabled() { + bool Instance::IsBackendValidationEnabled() const { return mImpl->IsBackendValidationEnabled(); } + + void Instance::EnableBeginCaptureOnStartup(bool beginCaptureOnStartup) { + mImpl->EnableBeginCaptureOnStartup(beginCaptureOnStartup); + } + + bool Instance::IsBeginCaptureOnStartupEnabled() const { + return mImpl->IsBeginCaptureOnStartupEnabled(); + } + } // namespace dawn_native diff --git a/src/dawn_native/Instance.cpp b/src/dawn_native/Instance.cpp index b5e2f896d7..f686a069be 100644 --- a/src/dawn_native/Instance.cpp +++ b/src/dawn_native/Instance.cpp @@ -247,8 +247,16 @@ namespace dawn_native { mEnableBackendValidation = enableBackendValidation; } - bool InstanceBase::IsBackendValidationEnabled() { + bool InstanceBase::IsBackendValidationEnabled() const { return mEnableBackendValidation; } + void InstanceBase::EnableBeginCaptureOnStartup(bool beginCaptureOnStartup) { + mBeginCaptureOnStartup = beginCaptureOnStartup; + } + + bool InstanceBase::IsBeginCaptureOnStartupEnabled() const { + return mBeginCaptureOnStartup; + } + } // namespace dawn_native diff --git a/src/dawn_native/Instance.h b/src/dawn_native/Instance.h index fba7e01c71..3743dd81f9 100644 --- a/src/dawn_native/Instance.h +++ b/src/dawn_native/Instance.h @@ -52,7 +52,10 @@ namespace dawn_native { const char* ToggleEnumToName(Toggle toggle); void EnableBackendValidation(bool enableBackendValidation); - bool IsBackendValidationEnabled(); + bool IsBackendValidationEnabled() const; + + void EnableBeginCaptureOnStartup(bool beginCaptureOnStartup); + bool IsBeginCaptureOnStartupEnabled() const; private: // Lazily creates connections to all backends that have been compiled. @@ -70,6 +73,7 @@ namespace dawn_native { bool mToggleNameToEnumMapInitialized = false; bool mEnableBackendValidation = false; + bool mBeginCaptureOnStartup = false; std::vector> mBackends; std::vector> mAdapters; diff --git a/src/dawn_native/d3d12/BackendD3D12.cpp b/src/dawn_native/d3d12/BackendD3D12.cpp index b702fe49d0..473eedbb6a 100644 --- a/src/dawn_native/d3d12/BackendD3D12.cpp +++ b/src/dawn_native/d3d12/BackendD3D12.cpp @@ -24,7 +24,8 @@ namespace dawn_native { namespace d3d12 { namespace { ResultOrError> CreateFactory(const PlatformFunctions* functions, - bool enableBackendValidation) { + bool enableBackendValidation, + bool beginCaptureOnStartup) { ComPtr factory; uint32_t dxgiFactoryFlags = 0; @@ -49,6 +50,14 @@ namespace dawn_native { namespace d3d12 { DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_ALL)); } } + + if (beginCaptureOnStartup) { + ComPtr graphicsAnalysis; + if (SUCCEEDED(functions->dxgiGetDebugInterface1( + 0, IID_PPV_ARGS(&graphicsAnalysis)))) { + graphicsAnalysis->BeginCapture(); + } + } } if (FAILED(functions->createDxgiFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&factory)))) { @@ -68,8 +77,11 @@ namespace dawn_native { namespace d3d12 { mFunctions = std::make_unique(); DAWN_TRY(mFunctions->LoadFunctions()); - DAWN_TRY_ASSIGN( - mFactory, CreateFactory(mFunctions.get(), GetInstance()->IsBackendValidationEnabled())); + const auto instance = GetInstance(); + + DAWN_TRY_ASSIGN(mFactory, + CreateFactory(mFunctions.get(), instance->IsBackendValidationEnabled(), + instance->IsBeginCaptureOnStartupEnabled())); return {}; } diff --git a/src/dawn_native/d3d12/d3d12_platform.h b/src/dawn_native/d3d12/d3d12_platform.h index 854f9519f1..6dfa2fdd86 100644 --- a/src/dawn_native/d3d12/d3d12_platform.h +++ b/src/dawn_native/d3d12/d3d12_platform.h @@ -19,6 +19,9 @@ #include #include +// DXProgrammableCapture.h takes a dependency on other platform header +// files, so it must be defined after them. +#include #include using Microsoft::WRL::ComPtr; diff --git a/src/include/dawn_native/DawnNative.h b/src/include/dawn_native/DawnNative.h index 76c1159a9c..356d3a0ff1 100644 --- a/src/include/dawn_native/DawnNative.h +++ b/src/include/dawn_native/DawnNative.h @@ -127,7 +127,11 @@ namespace dawn_native { // Enable backend's validation layers if it has. void EnableBackendValidation(bool enableBackendValidation); - bool IsBackendValidationEnabled(); + bool IsBackendValidationEnabled() const; + + // Enable debug capture on Dawn startup + void EnableBeginCaptureOnStartup(bool beginCaptureOnStartup); + bool IsBeginCaptureOnStartupEnabled() const; private: InstanceBase* mImpl = nullptr; diff --git a/src/tests/DawnTest.cpp b/src/tests/DawnTest.cpp index c501cf0e2a..c567d494e2 100644 --- a/src/tests/DawnTest.cpp +++ b/src/tests/DawnTest.cpp @@ -109,13 +109,20 @@ DawnTestEnvironment::DawnTestEnvironment(int argc, char** argv) { continue; } + if (strcmp("-c", argv[i]) == 0 || strcmp("--begin-capture-on-startup", argv[i]) == 0) { + mBeginCaptureOnStartup = true; + continue; + } + if (strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) { std::cout << "\n\nUsage: " << argv[0] - << " [GTEST_FLAGS...] [-w] [--enable-validation-layers]\n"; - std::cout << " -w, --use-wire: Run the tests through the wire (defaults to no wire)\n"; - std::cout << " -d, --enable-backend-validation: Enable backend validation (defaults" - << " to disabled)\n"; - std::cout << std::endl; + << " [GTEST_FLAGS...] [-w] [--enable-validation-layers]\n" + " -w, --use-wire: Run the tests through the wire (defaults to no wire)\n" + " -d, --enable-backend-validation: Enable backend validation (defaults" + " to disabled)\n" + " -c, --begin-capture-on-startup: Begin debug capture on startup " + "(defaults to no capture)" + << std::endl; continue; } } @@ -126,6 +133,7 @@ void DawnTestEnvironment::SetUp() { mInstance = std::make_unique(); mInstance->EnableBackendValidation(mEnableBackendValidation); + mInstance->EnableBeginCaptureOnStartup(mBeginCaptureOnStartup); static constexpr dawn_native::BackendType kAllBackends[] = { dawn_native::BackendType::D3D12, @@ -142,12 +150,18 @@ void DawnTestEnvironment::SetUp() { } } - std::cout << "Testing configuration\n"; - std::cout << "---------------------\n"; - std::cout << "UseWire: " << (mUseWire ? "true" : "false") << "\n"; - std::cout << "EnableBackendValidation: " << (mEnableBackendValidation ? "true" : "false") - << "\n"; - std::cout << "\n"; + std::cout << "Testing configuration\n" + "---------------------\n" + "UseWire: " + << (mUseWire ? "true" : "false") + << "\n" + "EnableBackendValidation: " + << (mEnableBackendValidation ? "true" : "false") + << "\n" + "BeginCaptureOnStartup: " + << (mBeginCaptureOnStartup ? "true" : "false") + << "\n" + "\n"; // Preparing for outputting hex numbers std::cout << std::showbase << std::hex << std::setfill('0') << std::setw(4); diff --git a/src/tests/DawnTest.h b/src/tests/DawnTest.h index f2b8c1740f..2370d3da72 100644 --- a/src/tests/DawnTest.h +++ b/src/tests/DawnTest.h @@ -117,6 +117,7 @@ class DawnTestEnvironment : public testing::Environment { bool mUseWire = false; bool mEnableBackendValidation = false; + bool mBeginCaptureOnStartup = false; std::unique_ptr mInstance; // Windows don't usually like to be bound to one API than the other, for example switching