diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp index c884155de..37a9e1f10 100644 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ b/qrenderdoc/Windows/ShaderViewer.cpp @@ -838,35 +838,52 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR if(!me) return; - rdcarray states = r->ContinueDebug(m_Trace->debugger); + rdcarray *states = new rdcarray(); + + states->append(std::move(r->ContinueDebug(m_Trace->debugger))); + + rdcarray nextStates; bool finished = false; do { if(!me) + { + delete states; return; + } - rdcarray nextStates = r->ContinueDebug(m_Trace->debugger); + nextStates = r->ContinueDebug(m_Trace->debugger); if(!me) + { + delete states; return; + } - states.append(nextStates); finished = nextStates.empty(); + states->append(std::move(nextStates)); } while(!finished && m_BackgroundRunning.available() == 1); if(!me) + { + delete states; return; + } m_BackgroundRunning.tryAcquire(1); r->SetFrameEvent(m_Ctx.CurEvent(), true); if(!me) + { + delete states; return; + } GUIInvoke::call(this, [this, states]() { - m_States = states; + m_States.swap(*states); + delete states; if(!m_States.empty()) { diff --git a/renderdoc/api/replay/rdcarray.h b/renderdoc/api/replay/rdcarray.h index b9b66ab22..b9a41ca8b 100644 --- a/renderdoc/api/replay/rdcarray.h +++ b/renderdoc/api/replay/rdcarray.h @@ -333,7 +333,7 @@ public: { const size_t lastIdx = size(); reserve(size() + 1); - new(elems + lastIdx) T(std::forward(args...)); + new(elems + lastIdx) T(std::forward(args)...); setUsedCount(usedCount + 1); } @@ -569,6 +569,18 @@ public: // helpful shortcut for 'append at end', basically a multi-element push_back inline void append(const T *el, size_t count) { insert(size(), el, count); } inline void append(const rdcarray &in) { insert(size(), in.data(), in.size()); } + // overload for 'append from move' to move all the elements individually even though we can't move + // the allocation obviously. + inline void append(rdcarray &&in) + { + reserve(size() + in.size()); + for(size_t i = 0; i < in.size(); i++) + push_back(std::move(in[i])); + // don't have to clear here, since moved object can be left in any indeterminate but valid state + // (an all the members are in that state, while the array is fully valid), but this gives fewer + // surprises. + in.clear(); + } void erase(size_t offs, size_t count = 1) { if(count == 0) diff --git a/renderdoc/api/replay/shader_types.h b/renderdoc/api/replay/shader_types.h index 68bd0ce22..1c3c96d09 100644 --- a/renderdoc/api/replay/shader_types.h +++ b/renderdoc/api/replay/shader_types.h @@ -229,6 +229,10 @@ struct ShaderVariable } ShaderVariable(const ShaderVariable &) = default; ShaderVariable &operator=(const ShaderVariable &) = default; +#if !defined(SWIG) + ShaderVariable(ShaderVariable &&) = default; + ShaderVariable &operator=(ShaderVariable &&) = default; +#endif ShaderVariable(const rdcstr &n, float x, float y, float z, float w) { name = n; @@ -428,6 +432,10 @@ struct DebugVariableReference : name(name), type(type), component(component) { } +#if !defined(SWIG) + DebugVariableReference(DebugVariableReference &&) = default; + DebugVariableReference &operator=(DebugVariableReference &&) = default; +#endif bool operator==(const DebugVariableReference &o) const { return name == o.name && type == o.type && component == o.component; @@ -474,6 +482,10 @@ struct SourceVariableMapping SourceVariableMapping() = default; SourceVariableMapping(const SourceVariableMapping &) = default; SourceVariableMapping &operator=(const SourceVariableMapping &) = default; +#if !defined(SWIG) + SourceVariableMapping(SourceVariableMapping &&) = default; + SourceVariableMapping &operator=(SourceVariableMapping &&) = default; +#endif bool operator==(const SourceVariableMapping &o) const { @@ -613,6 +625,10 @@ struct ShaderVariableChange ShaderVariableChange() = default; ShaderVariableChange(const ShaderVariableChange &) = default; ShaderVariableChange &operator=(const ShaderVariableChange &) = default; +#if !defined(SWIG) + ShaderVariableChange(ShaderVariableChange &&) = default; + ShaderVariableChange &operator=(ShaderVariableChange &&) = default; +#endif bool operator==(const ShaderVariableChange &o) const { @@ -652,6 +668,10 @@ struct ShaderDebugState ShaderDebugState() = default; ShaderDebugState(const ShaderDebugState &) = default; ShaderDebugState &operator=(const ShaderDebugState &) = default; +#if !defined(SWIG) + ShaderDebugState(ShaderDebugState &&) = default; + ShaderDebugState &operator=(ShaderDebugState &&) = default; +#endif bool operator==(const ShaderDebugState &o) const { diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp index bcee58702..af2d5a43a 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp @@ -5629,7 +5629,7 @@ rdcarray InterpretDebugger::ContinueDebug(DXBCDebug::DebugAPIW initial.changes.push_back({ShaderVariable(), v}); dxbc->FillStateInstructionInfo(initial); - ret.push_back(initial); + ret.push_back(std::move(initial)); steps++; } @@ -5666,7 +5666,7 @@ rdcarray InterpretDebugger::ContinueDebug(DXBCDebug::DebugAPIW state.stepIndex = steps; state.nextInstruction = workgroup[i].nextInstruction; dxbc->FillStateInstructionInfo(state); - ret.push_back(state); + ret.push_back(std::move(state)); steps++; } diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp index 6d4972682..fbbb5d632 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp @@ -1561,7 +1561,7 @@ rdcarray Debugger::ContinueDebug() initial.changes.push_back({ShaderVariable(), GetPointerValue(active.ids[v])}); } - ret.push_back(initial); + ret.push_back(std::move(initial)); steps++; } @@ -1594,7 +1594,7 @@ rdcarray Debugger::ContinueDebug() if(thread.nextInstruction >= instructionOffsets.size()) { if(lane == activeLaneIndex) - ret.push_back(ShaderDebugState()); + ret.emplace_back(); continue; } @@ -1697,7 +1697,7 @@ rdcarray Debugger::ContinueDebug() }); } - ret.push_back(state); + ret.push_back(std::move(state)); steps++; }