From a0eadf47f5e61e436195af37483afe383816b944 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 4 Sep 2020 17:43:32 +0100 Subject: [PATCH] Push GCN ISA support checks onto separate thread * The executables can take a little while to run, so we can do that in parallel while loading the capture. --- renderdoc/driver/ihv/amd/amd_isa.cpp | 61 +++++++++++++++++++++++--- renderdoc/driver/ihv/amd/amd_isa.h | 1 + renderdoc/replay/replay_controller.cpp | 11 ++--- 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/renderdoc/driver/ihv/amd/amd_isa.cpp b/renderdoc/driver/ihv/amd/amd_isa.cpp index cbd677b84..33c936ca7 100644 --- a/renderdoc/driver/ihv/amd/amd_isa.cpp +++ b/renderdoc/driver/ihv/amd/amd_isa.cpp @@ -45,7 +45,7 @@ rdcstr pluginPath = "amd/isa"; // in amd_isa_.cpp rdcstr DisassembleDXBC(const bytebuf &shaderBytes, const rdcstr &target); -static bool IsSupported(ShaderEncoding encoding) +static bool CheckForSupport(ShaderEncoding encoding) { if(encoding == ShaderEncoding::GLSL) { @@ -87,12 +87,8 @@ static bool IsSupported(ShaderEncoding encoding) return false; } -void GetTargets(GraphicsAPI api, rdcarray &targets) +static void GetEncodings(GraphicsAPI api, ShaderEncoding &primary, ShaderEncoding &secondary) { - targets.reserve(asicCount + 1); - - ShaderEncoding primary = ShaderEncoding::SPIRV, secondary = ShaderEncoding::SPIRV; - if(IsD3D(api)) { primary = ShaderEncoding::DXBC; @@ -108,6 +104,59 @@ void GetTargets(GraphicsAPI api, rdcarray &targets) primary = ShaderEncoding::SPIRV; secondary = ShaderEncoding::SPIRV; } +} + +bool encodingCached[arraydim()] = {}; +bool encodingSupported[arraydim()] = {}; + +Threading::ThreadHandle supportCheckThread = 0; + +static void CacheSupport(ShaderEncoding primary, ShaderEncoding secondary = ShaderEncoding::Unknown) +{ + // if there's a thread running, sync it now. + if(supportCheckThread) + { + Threading::JoinThread(supportCheckThread); + Threading::CloseThread(supportCheckThread); + supportCheckThread = 0; + } + + // if we have these encodings cached now, return + if(encodingCached[(size_t)primary] && + (secondary == ShaderEncoding::Unknown || encodingCached[(size_t)secondary])) + return; + + // kick off a thread to cache these encodings' support + Threading::CreateThread([primary, secondary]() { + encodingSupported[(size_t)primary] = CheckForSupport(primary); + encodingSupported[(size_t)secondary] = CheckForSupport(secondary); + + encodingCached[(size_t)primary] = true; + encodingCached[(size_t)secondary] = true; + }); +} + +static bool IsSupported(ShaderEncoding encoding) +{ + CacheSupport(encoding); + + return encodingSupported[(size_t)encoding]; +} + +void CacheSupport(GraphicsAPI api) +{ + ShaderEncoding primary = ShaderEncoding::SPIRV, secondary = ShaderEncoding::SPIRV; + GetEncodings(api, primary, secondary); + + CacheSupport(primary, secondary); +} + +void GetTargets(GraphicsAPI api, rdcarray &targets) +{ + targets.reserve(asicCount + 1); + + ShaderEncoding primary = ShaderEncoding::SPIRV, secondary = ShaderEncoding::SPIRV; + GetEncodings(api, primary, secondary); if(IsSupported(primary) || IsSupported(secondary)) { diff --git a/renderdoc/driver/ihv/amd/amd_isa.h b/renderdoc/driver/ihv/amd/amd_isa.h index b36a2972f..43bb6ba01 100644 --- a/renderdoc/driver/ihv/amd/amd_isa.h +++ b/renderdoc/driver/ihv/amd/amd_isa.h @@ -30,6 +30,7 @@ namespace GCNISA { +void CacheSupport(GraphicsAPI api); void GetTargets(GraphicsAPI api, rdcarray &targets); rdcstr Disassemble(ShaderEncoding api, ShaderStage stage, const bytebuf &shaderBytes, diff --git a/renderdoc/replay/replay_controller.cpp b/renderdoc/replay/replay_controller.cpp index 50f6fa67d..0acd81dd5 100644 --- a/renderdoc/replay/replay_controller.cpp +++ b/renderdoc/replay/replay_controller.cpp @@ -2009,16 +2009,17 @@ ReplayStatus ReplayController::PostCreateInit(IReplayDriver *device, RDCFile *rd m_pDevice = device; + m_APIProps = m_pDevice->GetAPIProperties(); + + GCNISA::CacheSupport(m_APIProps.pipelineType); + ReplayStatus status = m_pDevice->ReadLogInitialisation(rdc, false); + GCNISA::GetTargets(m_APIProps.pipelineType, m_GCNTargets); + if(status != ReplayStatus::Succeeded) return status; - m_APIProps = m_pDevice->GetAPIProperties(); - - // fetch GCN ISA targets - GCNISA::GetTargets(m_APIProps.pipelineType, m_GCNTargets); - m_Buffers = m_pDevice->GetBuffers(); m_Textures = m_pDevice->GetTextures(); m_Resources = m_pDevice->GetResources();