Add IsDebugToolAttached to GPUDevice for detecting gpu debugger tools attached and auto-enable GPU profiler in that case

This commit is contained in:
Wojtek Figat
2024-06-03 09:24:27 +02:00
parent bd819b1f5f
commit 1cbcddf410
7 changed files with 90 additions and 27 deletions

View File

@@ -321,10 +321,11 @@ GPUDevice::GPUDevice(RendererType type, ShaderProfile profile)
, _res(New<PrivateData>())
, _resources(1024)
, TotalGraphicsMemory(0)
, IsDebugToolAttached(false)
, QuadShader(nullptr)
, CurrentTask(nullptr)
{
ASSERT(_rendererType != RendererType::Unknown);
ASSERT_LOW_LAYER(_rendererType != RendererType::Unknown);
}
GPUDevice::~GPUDevice()

View File

@@ -121,6 +121,11 @@ public:
/// </summary>
API_FIELD(ReadOnly) uint64 TotalGraphicsMemory;
/// <summary>
/// Indicates that debug tool is profiling device (eg. RenderDoc).
/// </summary>
API_FIELD(ReadOnly) bool IsDebugToolAttached;
/// <summary>
/// The GPU limits.
/// </summary>

View File

@@ -8,6 +8,7 @@
#include "Engine/Core/Config/GraphicsSettings.h"
#include "Engine/Engine/CommandLine.h"
#include "Engine/Engine/EngineService.h"
#include "Engine/Profiler/ProfilerGPU.h"
#include "Engine/Render2D/Font.h"
bool Graphics::UseVSync = false;
@@ -186,6 +187,13 @@ bool GraphicsService::Init()
);
// Initialize
if (device->IsDebugToolAttached)
{
#if COMPILE_WITH_PROFILER
// Auto-enable GPU profiler
ProfilerGPU::Enabled = true;
#endif
}
if (device->LoadContent())
{
return true;

View File

@@ -286,22 +286,6 @@ bool GPUDeviceDX11::Init()
}
UpdateOutputs(adapter);
ComPtr<IDXGIFactory5> factory5;
_factoryDXGI->QueryInterface(IID_PPV_ARGS(&factory5));
if (factory5)
{
BOOL allowTearing;
if (SUCCEEDED(factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing)))
&& allowTearing
#if PLATFORM_WINDOWS
&& GetModuleHandleA("renderdoc.dll") == nullptr // Disable tearing with RenderDoc (prevents crashing)
#endif
)
{
_allowTearing = true;
}
}
// Get flags and device type base on current configuration
uint32 flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#if GPU_ENABLE_DIAGNOSTICS
@@ -313,13 +297,44 @@ bool GPUDeviceDX11::Init()
D3D_FEATURE_LEVEL createdFeatureLevel = static_cast<D3D_FEATURE_LEVEL>(0);
auto targetFeatureLevel = GetD3DFeatureLevel();
VALIDATE_DIRECTX_CALL(D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, flags, &targetFeatureLevel, 1, D3D11_SDK_VERSION, &_device, &createdFeatureLevel, &_imContext));
// Validate result
ASSERT(_device);
ASSERT(_imContext);
ASSERT(createdFeatureLevel == targetFeatureLevel);
_state = DeviceState::Created;
#if PLATFORM_WINDOWS
// Detect RenderDoc usage (UUID {A7AA6116-9C8D-4BBA-9083-B4D816B71B78})
IUnknown* unknown = nullptr;
const GUID uuidRenderDoc = { 0xa7aa6116, 0x9c8d, 0x4bba, {0x90, 0x83, 0xb4, 0xd8, 0x16, 0xb7, 0x1b, 0x78}};
HRESULT hr = _device->QueryInterface(uuidRenderDoc, (void**)&unknown);
if(SUCCEEDED(hr) && unknown)
{
IsDebugToolAttached = true;
unknown->Release();
}
if (!IsDebugToolAttached && GetModuleHandleA("renderdoc.dll") != nullptr)
{
IsDebugToolAttached = true;
}
#endif
// Check if can use screen tearing on a swapchain
ComPtr<IDXGIFactory5> factory5;
_factoryDXGI->QueryInterface(IID_PPV_ARGS(&factory5));
if (factory5)
{
BOOL allowTearing;
if (SUCCEEDED(factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing)))
&& allowTearing
#if PLATFORM_WINDOWS
&& !IsDebugToolAttached // Disable tearing with RenderDoc (prevents crashing)
#endif
)
{
_allowTearing = true;
}
}
// Init device limits
{
auto& limits = Limits;

View File

@@ -304,6 +304,26 @@ bool GPUDeviceDX12::Init()
}
UpdateOutputs(adapter);
// Create DirectX device
VALIDATE_DIRECTX_CALL(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&_device)));
#if PLATFORM_WINDOWS
// Detect RenderDoc usage (UUID {A7AA6116-9C8D-4BBA-9083-B4D816B71B78})
IUnknown* unknown = nullptr;
const GUID uuidRenderDoc = { 0xa7aa6116, 0x9c8d, 0x4bba, { 0x90, 0x83, 0xb4, 0xd8, 0x16, 0xb7, 0x1b, 0x78 } };
HRESULT hr = _device->QueryInterface(uuidRenderDoc, (void**)&unknown);
if (SUCCEEDED(hr) && unknown)
{
IsDebugToolAttached = true;
unknown->Release();
}
if (!IsDebugToolAttached && GetModuleHandleA("renderdoc.dll") != nullptr)
{
IsDebugToolAttached = true;
}
#endif
// Check if can use screen tearing on a swapchain
ComPtr<IDXGIFactory5> factory5;
_factoryDXGI->QueryInterface(IID_PPV_ARGS(&factory5));
if (factory5)
@@ -312,15 +332,12 @@ bool GPUDeviceDX12::Init()
if (SUCCEEDED(factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing)))
&& allowTearing
#if PLATFORM_WINDOWS
&& GetModuleHandleA("renderdoc.dll") == nullptr // Disable tearing with RenderDoc (prevents crashing)
&& !IsDebugToolAttached // Disable tearing with RenderDoc (prevents crashing)
#endif
)
AllowTearing = true;
}
// Create DirectX device
VALIDATE_DIRECTX_CALL(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&_device)));
// Debug Layer
#if GPU_ENABLE_DIAGNOSTICS
ComPtr<ID3D12InfoQueue> infoQueue;

View File

@@ -200,6 +200,16 @@ static bool ListContains(const Array<const char*>& list, const char* name)
return false;
}
static bool ListContains(const Array<StringAnsi>& list, const char* name)
{
for (const StringAnsi& element : list)
{
if (element == name)
return true;
}
return false;
}
void GPUDeviceVulkan::GetInstanceLayersAndExtensions(Array<const char*>& outInstanceExtensions, Array<const char*>& outInstanceLayers, bool& outDebugUtils)
{
VkResult result;
@@ -473,6 +483,10 @@ void GPUDeviceVulkan::GetDeviceExtensionsAndLayers(VkPhysicalDevice gpu, Array<c
}
// Add device layers for debugging
if (ListContains(foundUniqueExtensions, "VK_EXT_tooling_info"))
{
IsDebugToolAttached = true;
}
#if VULKAN_USE_DEBUG_LAYER
bool hasKhronosStandardValidationLayer = false, hasLunargStandardValidationLayer = false;
#if VULKAN_USE_KHRONOS_STANDARD_VALIDATION

View File

@@ -187,8 +187,10 @@ struct RenderTargetLayoutVulkan
uint32 WriteStencil : 1;
uint32 BlendEnable : 1;
};
uint32 Flags;
};
MSAALevel MSAA;
PixelFormat DepthFormat;
PixelFormat RTVsFormats[GPU_MAX_RT_BINDED];
@@ -405,12 +407,13 @@ public:
#endif
};
static void GetInstanceLayersAndExtensions(Array<const char*>& outInstanceExtensions, Array<const char*>& outInstanceLayers, bool& outDebugUtils);
static void GetDeviceExtensionsAndLayers(VkPhysicalDevice gpu, Array<const char*>& outDeviceExtensions, Array<const char*>& outDeviceLayers);
void ParseOptionalDeviceExtensions(const Array<const char*>& deviceExtensions);
static OptionalVulkanDeviceExtensions OptionalDeviceExtensions;
private:
static void GetInstanceLayersAndExtensions(Array<const char*>& outInstanceExtensions, Array<const char*>& outInstanceLayers, bool& outDebugUtils);
void GetDeviceExtensionsAndLayers(VkPhysicalDevice gpu, Array<const char*>& outDeviceExtensions, Array<const char*>& outDeviceLayers);
static void ParseOptionalDeviceExtensions(const Array<const char*>& deviceExtensions);
public:
/// <summary>
/// The Vulkan instance.