From 6208e3992dcec163068800c43d6bebb2af7e2a6c Mon Sep 17 00:00:00 2001 From: baldurk Date: Sun, 1 Feb 2015 19:57:09 +0000 Subject: [PATCH] Fall back to WARP if D3D11 hardware isn't present. Closes #121 * If hardware support for feature level 11 isn't present, fall back to the WARP software rasterizer. This will support everything needed, but it certainly won't run well. * There are loud warnings - I added a debug message to the debug errors& warnings window so the status bar will indicate that, and it's in the title. * At most once every 3 weeks there will also be a message box pop up when loading a log, to remind the user so that it isn't forgotten, as for obvious reasons this is not the intended use-case (hopefully once per 3 weeks isn't too often to be annoying). --- renderdoc/api/replay/data_types.h | 1 + renderdoc/core/image_viewer.cpp | 1 + renderdoc/core/replay_proxy.cpp | 3 ++- renderdoc/driver/d3d11/d3d11_replay.cpp | 17 ++++++++++++++--- renderdoc/driver/d3d11/d3d11_replay.h | 3 ++- renderdoc/driver/gl/gl_replay.cpp | 1 + renderdocui/Code/Core.cs | 14 ++++++++++++++ renderdocui/Code/PersistantConfig.cs | 2 ++ renderdocui/Interop/FetchInfo.cs | 1 + renderdocui/Windows/MainWindow.cs | 2 ++ 10 files changed, 40 insertions(+), 5 deletions(-) diff --git a/renderdoc/api/replay/data_types.h b/renderdoc/api/replay/data_types.h index 5ec1cc0a0..98759fcb6 100644 --- a/renderdoc/api/replay/data_types.h +++ b/renderdoc/api/replay/data_types.h @@ -210,6 +210,7 @@ struct FetchDrawcall struct APIProperties { APIPipelineStateType pipelineType; + bool32 degraded; }; struct CounterDescription diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index 6a62357a6..cd7b69b10 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -39,6 +39,7 @@ class ImageViewer : public IReplayDriver if(m_Proxy == NULL) RDCERR("Unexpectedly NULL proxy at creation of ImageViewer"); m_Props.pipelineType = ePipelineState_D3D11; + m_Props.degraded = false; FetchFrameRecord record; record.frameInfo.fileOffset = 0; diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index 821146769..c45ac7436 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -719,8 +719,9 @@ template<> void Serialiser::Serialise(const char *name, APIProperties &el) { Serialise("", el.pipelineType); + Serialise("", el.degraded); - SIZE_CHECK(APIProperties, 4); + SIZE_CHECK(APIProperties, 8); } template<> diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index 5439328af..16bee1f3e 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -40,6 +40,7 @@ D3D11Replay::D3D11Replay() { m_pDevice = NULL; m_Proxy = false; + m_WARP = false; } void D3D11Replay::Shutdown() @@ -340,6 +341,7 @@ APIProperties D3D11Replay::GetAPIProperties() APIProperties ret; ret.pipelineType = ePipelineState_D3D11; + ret.degraded = m_WARP; return ret; } @@ -1810,10 +1812,13 @@ ReplayCreateStatus D3D11_CreateReplayDevice(const char *logfile, IReplayDriver * // check for feature level 11 support - passing NULL feature level array implicitly checks for 11_0 before others hr = createDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, NULL, NULL, NULL, &maxFeatureLevel, NULL); + bool warpFallback = false; + if(SUCCEEDED(hr) && maxFeatureLevel < D3D_FEATURE_LEVEL_11_0) { - RDCERR("Couldn't create FEATURE_LEVEL_11_0 device - RenderDoc requires FEATURE_LEVEL_11_0 availability"); - return eReplayCreate_APIHardwareUnsupported; + RDCWARN("Couldn't create FEATURE_LEVEL_11_0 device - RenderDoc requires FEATURE_LEVEL_11_0 availability - falling back to WARP rasterizer"); + driverTypes[0] = driverType = D3D_DRIVER_TYPE_WARP; + warpFallback = true; } D3D11DebugManager::PreDeviceInitCounters(); @@ -1835,7 +1840,13 @@ ReplayCreateStatus D3D11_CreateReplayDevice(const char *logfile, IReplayDriver * RDCLOG("Created device."); D3D11Replay *replay = wrappedDev->GetReplay(); - replay->SetProxy(logfile == NULL); + replay->SetProxy(logfile == NULL, warpFallback); + if(warpFallback) + { + wrappedDev->AddDebugMessage(eDbgCategory_Initialization, eDbgSeverity_High, eDbgSource_RuntimeWarning, + "Couldn't create FEATURE_LEVEL_11_0 device - RenderDoc requires FEATURE_LEVEL_11_0 availability - falling back to WARP rasterizer.\n" \ + "Performance and usability will be significantly degraded."); + } *driver = (IReplayDriver *)replay; return eReplayCreate_Success; diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index 72699dd4f..f329b3725 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -36,7 +36,7 @@ class D3D11Replay : public IReplayDriver public: D3D11Replay(); - void SetProxy(bool p) { m_Proxy = p; } + void SetProxy(bool p, bool warp) { m_Proxy = p; m_WARP = warp; } bool IsRemoteProxy() { return m_Proxy; } void Shutdown(); @@ -135,6 +135,7 @@ class D3D11Replay : public IReplayDriver private: D3D11PipelineState MakePipelineState(); + bool m_WARP; bool m_Proxy; WrappedID3D11Device *m_pDevice; diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index f68709ced..3997da13a 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -86,6 +86,7 @@ APIProperties GLReplay::GetAPIProperties() APIProperties ret; ret.pipelineType = ePipelineState_OpenGL; + ret.degraded = false; return ret; } diff --git a/renderdocui/Code/Core.cs b/renderdocui/Code/Core.cs index 31c8ad034..d746bb785 100644 --- a/renderdocui/Code/Core.cs +++ b/renderdocui/Code/Core.cs @@ -512,6 +512,20 @@ namespace renderdocui.Code Thread.Sleep(20); + DateTime today = DateTime.Now; + DateTime compare = today.AddDays(-21); + + if (compare.CompareTo(Config.DegradedLog_LastUpdate) >= 0 && m_APIProperties.degraded) + { + Config.DegradedLog_LastUpdate = today; + + MessageBox.Show(String.Format("{0}\nThis log opened with degraded support - " + + "this could mean missing hardware support caused a fallback to software rendering.\n\n" + + "This warning will not appear every time this happens, " + + "check debug errors/warnings window for more details.", logFile), + "Degraded support of log", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + m_LogLoaded = true; progressThread = false; diff --git a/renderdocui/Code/PersistantConfig.cs b/renderdocui/Code/PersistantConfig.cs index 1539f148b..7e19fccfb 100644 --- a/renderdocui/Code/PersistantConfig.cs +++ b/renderdocui/Code/PersistantConfig.cs @@ -95,6 +95,8 @@ namespace renderdocui.Code public bool CheckUpdate_UpdateAvailable = false; public DateTime CheckUpdate_LastUpdate = new DateTime(2012, 06, 27); + public DateTime DegradedLog_LastUpdate = new DateTime(2015, 01, 01); + public bool AllowGlobalHook = false; public void SetupFormatter() diff --git a/renderdocui/Interop/FetchInfo.cs b/renderdocui/Interop/FetchInfo.cs index b36e79476..44708f08c 100644 --- a/renderdocui/Interop/FetchInfo.cs +++ b/renderdocui/Interop/FetchInfo.cs @@ -487,6 +487,7 @@ namespace renderdoc public class APIProperties { public APIPipelineStateType pipelineType; + public bool degraded; }; [StructLayout(LayoutKind.Sequential)] diff --git a/renderdocui/Windows/MainWindow.cs b/renderdocui/Windows/MainWindow.cs index 6c49df04c..1739f35c6 100644 --- a/renderdocui/Windows/MainWindow.cs +++ b/renderdocui/Windows/MainWindow.cs @@ -594,6 +594,8 @@ namespace renderdocui.Windows if (m_Core != null && m_Core.LogLoaded) { prefix = Path.GetFileName(m_Core.LogFileName); + if (m_Core.APIProps.degraded) + prefix += " !DEGRADED PERFORMANCE!"; if (m_RemoteReplay.Length > 0) prefix += String.Format(" (Remote replay on {0})", m_RemoteReplay); prefix += " - ";