From 99b3137b4144282cc4d3340a404f279b3af50e5b Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Fri, 26 Sep 2025 08:20:29 +0100 Subject: [PATCH] Add asserts for DXIL ThreadState APIs to be called on the device thread --- renderdoc/driver/shaders/dxil/dxil_debug.cpp | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/renderdoc/driver/shaders/dxil/dxil_debug.cpp b/renderdoc/driver/shaders/dxil/dxil_debug.cpp index 1d6b0d195..2d6cd827e 100644 --- a/renderdoc/driver/shaders/dxil/dxil_debug.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_debug.cpp @@ -42,6 +42,16 @@ RDOC_CONFIG(bool, D3D12_DXILShaderDebugger_Logging, false, RDCASSERTMSG("Debugger function called from non-device thread!", IsDeviceThread()); #endif // #if defined(RELEASE) +#if defined(RELEASE) +#define THREADSTATE_CHECK_DEBUGGER_THREAD() \ + do \ + { \ + } while((void)0, 0) +#else +#define THREADSTATE_CHECK_DEBUGGER_THREAD() \ + RDCASSERTMSG("Function called from non-debugger thread!", m_Debugger.IsDeviceThread()); +#endif // #if defined(RELEASE) + using namespace rdcshaders; // TODO: Extend support for Compound Constants: arithmetic, logical ops @@ -1790,6 +1800,7 @@ void MemoryTracking::ConvertGlobalAllocToLocal(Id allocId) } } +// Must be called from the replay manager thread (the debugger thread) ThreadState::ThreadState(Debugger &debugger, const GlobalState &globalState, uint32_t maxSSAId, uint32_t laneIndex) : m_Debugger(debugger), @@ -1798,14 +1809,17 @@ ThreadState::ThreadState(Debugger &debugger, const GlobalState &globalState, uin m_MaxSSAId(maxSSAId), m_WorkgroupIndex(laneIndex) { + THREADSTATE_CHECK_DEBUGGER_THREAD(); m_ShaderType = m_Program.GetShaderType(); m_Assigned.resize(maxSSAId); m_Live.resize(maxSSAId); m_Variables.resize(maxSSAId); } +// Must be called from the replay manager thread (the debugger thread) ThreadState::~ThreadState() { + THREADSTATE_CHECK_DEBUGGER_THREAD(); for(auto it : m_Memory.m_Allocations) { if(it.second.localMemory) @@ -1823,8 +1837,10 @@ bool ThreadState::InUniformBlock() const return m_FunctionInfo->uniformBlocks.contains(m_Block); } +// Must be called from the replay manager thread (the debugger thread) void ThreadState::ProcessScopeChange(const rdcarray &oldLive, const rdcarray &newLive) { + THREADSTATE_CHECK_DEBUGGER_THREAD(); // nothing to do if we aren't tracking into a state if(!m_State) return; @@ -1851,8 +1867,10 @@ void ThreadState::ProcessScopeChange(const rdcarray &oldLive, const rdcarr } } +// Must be called from the replay manager thread (the debugger thread) void ThreadState::EnterFunction(const Function *function, const rdcarray &args) { + THREADSTATE_CHECK_DEBUGGER_THREAD(); StackFrame *frame = new StackFrame(function); m_FunctionInstructionIdx = 0; m_FunctionInfo = m_Debugger.GetFunctionInfo(function); @@ -1881,8 +1899,10 @@ void ThreadState::EnterFunction(const Function *function, const rdcarraycallstacks.size() == 1) { state.callstack = m_FunctionInfo->callstacks.begin()->second;