From 7498c53a37323d806d1a2ccc4fd4249212ac962d Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 20 Dec 2018 10:49:13 +0000 Subject: [PATCH] Verify thread access to ReplayController to ReplayOutput --- renderdoc/replay/replay_controller.cpp | 114 +++++++++++++++++++++++++ renderdoc/replay/replay_controller.h | 6 ++ renderdoc/replay/replay_output.cpp | 48 +++++++++++ 3 files changed, 168 insertions(+) diff --git a/renderdoc/replay/replay_controller.cpp b/renderdoc/replay/replay_controller.cpp index a1a7a301d..826c8bcba 100644 --- a/renderdoc/replay/replay_controller.cpp +++ b/renderdoc/replay/replay_controller.cpp @@ -170,6 +170,8 @@ static void fileWriteFunc(void *context, void *data, int size) ReplayController::ReplayController() { + m_ThreadID = Threading::GetCurrentID(); + m_pDevice = NULL; m_EventID = 100000; @@ -185,6 +187,8 @@ ReplayController::ReplayController() ReplayController::~ReplayController() { + CHECK_REPLAY_THREAD(); + RDCLOG("Shutting down replay renderer"); for(size_t i = 0; i < m_Outputs.size(); i++) @@ -209,6 +213,8 @@ ReplayController::~ReplayController() void ReplayController::SetFrameEvent(uint32_t eventId, bool force) { + CHECK_REPLAY_THREAD(); + if(eventId != m_EventID || force) { m_EventID = eventId; @@ -226,31 +232,43 @@ void ReplayController::SetFrameEvent(uint32_t eventId, bool force) const D3D11Pipe::State *ReplayController::GetD3D11PipelineState() { + CHECK_REPLAY_THREAD(); + return m_D3D11PipelineState; } const D3D12Pipe::State *ReplayController::GetD3D12PipelineState() { + CHECK_REPLAY_THREAD(); + return m_D3D12PipelineState; } const GLPipe::State *ReplayController::GetGLPipelineState() { + CHECK_REPLAY_THREAD(); + return m_GLPipelineState; } const VKPipe::State *ReplayController::GetVulkanPipelineState() { + CHECK_REPLAY_THREAD(); + return m_VulkanPipelineState; } const PipeState &ReplayController::GetPipelineState() { + CHECK_REPLAY_THREAD(); + return m_PipeState; } rdcarray ReplayController::GetDisassemblyTargets() { + CHECK_REPLAY_THREAD(); + rdcarray ret; vector targets = m_pDevice->GetDisassemblyTargets(); @@ -268,6 +286,8 @@ rdcarray ReplayController::GetDisassemblyTargets() rdcstr ReplayController::DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const char *target) { + CHECK_REPLAY_THREAD(); + for(const std::string &t : m_GCNTargets) if(t == target) return GCNISA::Disassemble(refl->encoding, refl->stage, refl->rawBytes, target); @@ -277,16 +297,22 @@ rdcstr ReplayController::DisassembleShader(ResourceId pipeline, const ShaderRefl FrameDescription ReplayController::GetFrameInfo() { + CHECK_REPLAY_THREAD(); + return m_FrameRecord.frameInfo; } const SDFile &ReplayController::GetStructuredFile() { + CHECK_REPLAY_THREAD(); + return m_pDevice->GetStructuredFile(); } DrawcallDescription *ReplayController::GetDrawcallByEID(uint32_t eventId) { + CHECK_REPLAY_THREAD(); + if(eventId >= m_Drawcalls.size()) return NULL; @@ -295,11 +321,15 @@ DrawcallDescription *ReplayController::GetDrawcallByEID(uint32_t eventId) const rdcarray &ReplayController::GetDrawcalls() { + CHECK_REPLAY_THREAD(); + return m_FrameRecord.drawcallList; } bool ReplayController::ContainsMarker(const rdcarray &draws) { + CHECK_REPLAY_THREAD(); + bool ret = false; for(const DrawcallDescription &d : draws) @@ -317,6 +347,8 @@ bool ReplayController::ContainsMarker(const rdcarray &draws bool ReplayController::PassEquivalent(const DrawcallDescription &a, const DrawcallDescription &b) { + CHECK_REPLAY_THREAD(); + // don't group draws and compute executes if((a.flags & DrawFlags::Dispatch) != (b.flags & DrawFlags::Dispatch)) return false; @@ -387,6 +419,8 @@ bool ReplayController::PassEquivalent(const DrawcallDescription &a, const Drawca void ReplayController::AddFakeMarkers() { + CHECK_REPLAY_THREAD(); + rdcarray &draws = m_FrameRecord.drawcallList; if(ContainsMarker(draws)) @@ -502,6 +536,8 @@ void ReplayController::AddFakeMarkers() rdcarray ReplayController::FetchCounters(const rdcarray &counters) { + CHECK_REPLAY_THREAD(); + std::vector counterArray(counters.begin(), counters.end()); return m_pDevice->FetchCounters(counterArray); @@ -509,46 +545,64 @@ rdcarray ReplayController::FetchCounters(const rdcarray ReplayController::EnumerateCounters() { + CHECK_REPLAY_THREAD(); + return m_pDevice->EnumerateCounters(); } CounterDescription ReplayController::DescribeCounter(GPUCounter counterID) { + CHECK_REPLAY_THREAD(); + return m_pDevice->DescribeCounter(counterID); } const rdcarray &ReplayController::GetResources() { + CHECK_REPLAY_THREAD(); + return m_Resources; } const rdcarray &ReplayController::GetBuffers() { + CHECK_REPLAY_THREAD(); + return m_Buffers; } const rdcarray &ReplayController::GetTextures() { + CHECK_REPLAY_THREAD(); + return m_Textures; } rdcarray ReplayController::GetDebugMessages() { + CHECK_REPLAY_THREAD(); + return m_pDevice->GetDebugMessages(); } rdcarray ReplayController::GetShaderEntryPoints(ResourceId shader) { + CHECK_REPLAY_THREAD(); + return m_pDevice->GetShaderEntryPoints(m_pDevice->GetLiveID(shader)); } ShaderReflection *ReplayController::GetShader(ResourceId shader, ShaderEntryPoint entry) { + CHECK_REPLAY_THREAD(); + return m_pDevice->GetShader(m_pDevice->GetLiveID(shader), entry); } rdcarray ReplayController::GetUsage(ResourceId id) { + CHECK_REPLAY_THREAD(); + id = m_pDevice->GetLiveID(id); if(id == ResourceId()) return rdcarray(); @@ -557,6 +611,8 @@ rdcarray ReplayController::GetUsage(ResourceId id) MeshFormat ReplayController::GetPostVSData(uint32_t instID, uint32_t viewID, MeshDataStage stage) { + CHECK_REPLAY_THREAD(); + DrawcallDescription *draw = GetDrawcallByEID(m_EventID); MeshFormat ret; @@ -574,6 +630,8 @@ MeshFormat ReplayController::GetPostVSData(uint32_t instID, uint32_t viewID, Mes bytebuf ReplayController::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len) { + CHECK_REPLAY_THREAD(); + bytebuf retData; if(buff == ResourceId()) @@ -594,6 +652,8 @@ bytebuf ReplayController::GetBufferData(ResourceId buff, uint64_t offset, uint64 bytebuf ReplayController::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip) { + CHECK_REPLAY_THREAD(); + bytebuf ret; ResourceId liveId = m_pDevice->GetLiveID(tex); @@ -611,6 +671,8 @@ bytebuf ReplayController::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint bool ReplayController::SaveTexture(const TextureSave &saveData, const char *path) { + CHECK_REPLAY_THREAD(); + TextureSave sd = saveData; // mutable copy ResourceId liveid = m_pDevice->GetLiveID(sd.resourceId); @@ -1492,6 +1554,8 @@ rdcarray ReplayController::PixelHistory(ResourceId target, ui uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx, CompType typeHint) { + CHECK_REPLAY_THREAD(); + rdcarray ret; for(size_t t = 0; t < m_Textures.size(); t++) @@ -1600,6 +1664,8 @@ rdcarray ReplayController::PixelHistory(ResourceId target, ui ShaderDebugTrace *ReplayController::DebugVertex(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) { + CHECK_REPLAY_THREAD(); + ShaderDebugTrace *ret = new ShaderDebugTrace; *ret = m_pDevice->DebugVertex(m_EventID, vertid, instid, idx, instOffset, vertOffset); @@ -1612,6 +1678,8 @@ ShaderDebugTrace *ReplayController::DebugVertex(uint32_t vertid, uint32_t instid ShaderDebugTrace *ReplayController::DebugPixel(uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive) { + CHECK_REPLAY_THREAD(); + ShaderDebugTrace *ret = new ShaderDebugTrace; *ret = m_pDevice->DebugPixel(m_EventID, x, y, sample, primitive); @@ -1623,6 +1691,8 @@ ShaderDebugTrace *ReplayController::DebugPixel(uint32_t x, uint32_t y, uint32_t ShaderDebugTrace *ReplayController::DebugThread(const uint32_t groupid[3], const uint32_t threadid[3]) { + CHECK_REPLAY_THREAD(); + ShaderDebugTrace *ret = new ShaderDebugTrace; *ret = m_pDevice->DebugThread(m_EventID, groupid, threadid); @@ -1634,12 +1704,16 @@ ShaderDebugTrace *ReplayController::DebugThread(const uint32_t groupid[3], const void ReplayController::FreeTrace(ShaderDebugTrace *trace) { + CHECK_REPLAY_THREAD(); + delete trace; } rdcarray ReplayController::GetCBufferVariableContents( ResourceId shader, const char *entryPoint, uint32_t cbufslot, ResourceId buffer, uint64_t offs) { + CHECK_REPLAY_THREAD(); + bytebuf data; if(buffer != ResourceId()) { @@ -1660,11 +1734,15 @@ rdcarray ReplayController::GetCBufferVariableContents( rdcarray ReplayController::GetSupportedWindowSystems() { + CHECK_REPLAY_THREAD(); + return m_pDevice->GetSupportedWindowSystems(); } rdcstr ReplayController::CreateRGPProfile(WindowingData window) { + CHECK_REPLAY_THREAD(); + AMDRGPControl *rgp = m_pDevice->GetRGPControl(); if(!rgp) @@ -1734,6 +1812,8 @@ rdcstr ReplayController::CreateRGPProfile(WindowingData window) void ReplayController::ReplayLoop(WindowingData window, ResourceId texid) { + CHECK_REPLAY_THREAD(); + ReplayOutput *output = CreateOutput(window, ReplayOutputType::Texture); TextureDisplay d; @@ -1777,6 +1857,8 @@ void ReplayController::ReplayLoop(WindowingData window, ResourceId texid) void ReplayController::CancelReplayLoop() { + CHECK_REPLAY_THREAD(); + Atomic::Inc32(&m_ReplayLoopCancel); // wait for it to actually finish before returning @@ -1786,6 +1868,8 @@ void ReplayController::CancelReplayLoop() ReplayOutput *ReplayController::CreateOutput(WindowingData window, ReplayOutputType type) { + CHECK_REPLAY_THREAD(); + ReplayOutput *out = new ReplayOutput(this, window, type); m_Outputs.push_back(out); @@ -1801,6 +1885,8 @@ ReplayOutput *ReplayController::CreateOutput(WindowingData window, ReplayOutputT void ReplayController::ShutdownOutput(IReplayOutput *output) { + CHECK_REPLAY_THREAD(); + for(auto it = m_Outputs.begin(); it != m_Outputs.end(); ++it) { if((IReplayOutput *)*it == output) @@ -1816,11 +1902,15 @@ void ReplayController::ShutdownOutput(IReplayOutput *output) void ReplayController::Shutdown() { + CHECK_REPLAY_THREAD(); + delete this; } rdcarray ReplayController::GetTargetShaderEncodings() { + CHECK_REPLAY_THREAD(); + return m_pDevice->GetTargetShaderEncodings(); } @@ -1828,6 +1918,8 @@ rdcpair ReplayController::BuildTargetShader( const char *entry, ShaderEncoding sourceEncoding, bytebuf source, const ShaderCompileFlags &compileFlags, ShaderStage type) { + CHECK_REPLAY_THREAD(); + rdcarray encodings = m_pDevice->GetTargetShaderEncodings(); if(encodings.indexOf(sourceEncoding) == -1) @@ -1860,6 +1952,8 @@ rdcpair ReplayController::BuildTargetShader( rdcpair ReplayController::BuildCustomShader( const char *entry, const char *source, const ShaderCompileFlags &compileFlags, ShaderStage type) { + CHECK_REPLAY_THREAD(); + ResourceId id; string errs; @@ -1884,18 +1978,24 @@ rdcpair ReplayController::BuildCustomShader( void ReplayController::FreeTargetResource(ResourceId id) { + CHECK_REPLAY_THREAD(); + m_TargetResources.erase(id); m_pDevice->FreeTargetResource(id); } void ReplayController::FreeCustomShader(ResourceId id) { + CHECK_REPLAY_THREAD(); + m_CustomShaders.erase(id); m_pDevice->FreeCustomShader(id); } void ReplayController::ReplaceResource(ResourceId from, ResourceId to) { + CHECK_REPLAY_THREAD(); + m_pDevice->ReplaceResource(from, to); SetFrameEvent(m_EventID, true); @@ -1907,6 +2007,8 @@ void ReplayController::ReplaceResource(ResourceId from, ResourceId to) void ReplayController::RemoveReplacement(ResourceId id) { + CHECK_REPLAY_THREAD(); + m_pDevice->RemoveReplacement(id); SetFrameEvent(m_EventID, true); @@ -1918,6 +2020,8 @@ void ReplayController::RemoveReplacement(ResourceId id) ReplayStatus ReplayController::CreateDevice(RDCFile *rdc) { + CHECK_REPLAY_THREAD(); + IReplayDriver *driver = NULL; ReplayStatus status = RenderDoc::Inst().CreateReplayDriver(rdc, &driver); @@ -1933,6 +2037,8 @@ ReplayStatus ReplayController::CreateDevice(RDCFile *rdc) ReplayStatus ReplayController::SetDevice(IReplayDriver *device) { + CHECK_REPLAY_THREAD(); + if(device) { RDCLOG("Got replay driver."); @@ -1945,6 +2051,8 @@ ReplayStatus ReplayController::SetDevice(IReplayDriver *device) ReplayStatus ReplayController::PostCreateInit(IReplayDriver *device, RDCFile *rdc) { + CHECK_REPLAY_THREAD(); + m_pDevice = device; ReplayStatus status = m_pDevice->ReadLogInitialisation(rdc, false); @@ -1992,16 +2100,22 @@ ReplayStatus ReplayController::PostCreateInit(IReplayDriver *device, RDCFile *rd void ReplayController::FileChanged() { + CHECK_REPLAY_THREAD(); + m_pDevice->FileChanged(); } APIProperties ReplayController::GetAPIProperties() { + CHECK_REPLAY_THREAD(); + return m_pDevice->GetAPIProperties(); } void ReplayController::FetchPipelineState() { + CHECK_REPLAY_THREAD(); + m_pDevice->SavePipelineState(); m_D3D11PipelineState = m_pDevice->GetD3D11PipelineState(); diff --git a/renderdoc/replay/replay_controller.h b/renderdoc/replay/replay_controller.h index 41259a717..899c34162 100644 --- a/renderdoc/replay/replay_controller.h +++ b/renderdoc/replay/replay_controller.h @@ -32,6 +32,8 @@ #include "core/core.h" #include "replay/replay_driver.h" +#define CHECK_REPLAY_THREAD() RDCASSERT(Threading::GetCurrentID() == m_ThreadID); + struct ReplayController; struct ReplayOutput : public IReplayOutput @@ -76,6 +78,8 @@ private: void DisplayMesh(); + uint64_t m_ThreadID; + ReplayController *m_pRenderer; bool m_OverlayDirty; @@ -219,6 +223,8 @@ private: FrameRecord m_FrameRecord; vector m_Drawcalls; + uint64_t m_ThreadID; + APIProperties m_APIProps; std::vector m_GCNTargets; diff --git a/renderdoc/replay/replay_output.cpp b/renderdoc/replay/replay_output.cpp index 26ec389e0..10de0cd7b 100644 --- a/renderdoc/replay/replay_output.cpp +++ b/renderdoc/replay/replay_output.cpp @@ -76,6 +76,8 @@ static uint64_t GetHandle(WindowingData window) ReplayOutput::ReplayOutput(ReplayController *parent, WindowingData window, ReplayOutputType type) { + m_ThreadID = Threading::GetCurrentID(); + m_pRenderer = parent; m_MainOutput.dirty = true; @@ -116,6 +118,8 @@ ReplayOutput::ReplayOutput(ReplayController *parent, WindowingData window, Repla void ReplayOutput::SetDimensions(int32_t width, int32_t height) { + CHECK_REPLAY_THREAD(); + if(m_MainOutput.outputID == 0) { m_Width = width; @@ -125,6 +129,8 @@ void ReplayOutput::SetDimensions(int32_t width, int32_t height) ReplayOutput::~ReplayOutput() { + CHECK_REPLAY_THREAD(); + m_pDevice->DestroyOutputWindow(m_MainOutput.outputID); m_pDevice->DestroyOutputWindow(m_PixelContext.outputID); @@ -135,11 +141,15 @@ ReplayOutput::~ReplayOutput() void ReplayOutput::Shutdown() { + CHECK_REPLAY_THREAD(); + m_pRenderer->ShutdownOutput(this); } void ReplayOutput::SetTextureDisplay(const TextureDisplay &o) { + CHECK_REPLAY_THREAD(); + if(o.overlay != m_RenderData.texDisplay.overlay || o.typeHint != m_RenderData.texDisplay.typeHint || o.resourceId != m_RenderData.texDisplay.resourceId) { @@ -159,6 +169,8 @@ void ReplayOutput::SetTextureDisplay(const TextureDisplay &o) void ReplayOutput::SetMeshDisplay(const MeshDisplay &o) { + CHECK_REPLAY_THREAD(); + if(o.showWholePass != m_RenderData.meshDisplay.showWholePass) m_OverlayDirty = true; m_RenderData.meshDisplay = o; @@ -167,6 +179,8 @@ void ReplayOutput::SetMeshDisplay(const MeshDisplay &o) void ReplayOutput::SetFrameEvent(int eventId) { + CHECK_REPLAY_THREAD(); + m_EventID = eventId; m_OverlayDirty = true; @@ -180,6 +194,8 @@ void ReplayOutput::SetFrameEvent(int eventId) void ReplayOutput::RefreshOverlay() { + CHECK_REPLAY_THREAD(); + DrawcallDescription *draw = m_pRenderer->GetDrawcallByEID(m_EventID); passEvents = m_pDevice->GetPassEvents(m_EventID); @@ -236,11 +252,15 @@ void ReplayOutput::RefreshOverlay() ResourceId ReplayOutput::GetCustomShaderTexID() { + CHECK_REPLAY_THREAD(); + return m_CustomShaderResourceId; } ResourceId ReplayOutput::GetDebugOverlayTexID() { + CHECK_REPLAY_THREAD(); + if(m_OverlayDirty) { m_pDevice->ReplayLog(m_EventID, eReplay_WithoutDraw); @@ -253,6 +273,8 @@ ResourceId ReplayOutput::GetDebugOverlayTexID() void ReplayOutput::ClearThumbnails() { + CHECK_REPLAY_THREAD(); + for(size_t i = 0; i < m_Thumbnails.size(); i++) m_pDevice->DestroyOutputWindow(m_Thumbnails[i].outputID); @@ -261,6 +283,8 @@ void ReplayOutput::ClearThumbnails() bool ReplayOutput::SetPixelContext(WindowingData window) { + CHECK_REPLAY_THREAD(); + m_PixelContext.outputID = m_pDevice->MakeOutputWindow(window, false); m_PixelContext.texture = ResourceId(); m_PixelContext.depthMode = false; @@ -272,6 +296,8 @@ bool ReplayOutput::SetPixelContext(WindowingData window) bool ReplayOutput::AddThumbnail(WindowingData window, ResourceId texID, CompType typeHint) { + CHECK_REPLAY_THREAD(); + OutputPair p; RDCASSERT(window.system != WindowingSystem::Unknown); @@ -320,6 +346,8 @@ bool ReplayOutput::AddThumbnail(WindowingData window, ResourceId texID, CompType rdcpair ReplayOutput::GetMinMax() { + CHECK_REPLAY_THREAD(); + PixelValue minval = {{0.0f, 0.0f, 0.0f, 0.0f}}; PixelValue maxval = {{1.0f, 1.0f, 1.0f, 1.0f}}; @@ -347,6 +375,8 @@ rdcpair ReplayOutput::GetMinMax() rdcarray ReplayOutput::GetHistogram(float minval, float maxval, bool channels[4]) { + CHECK_REPLAY_THREAD(); + vector hist; ResourceId tex = m_pDevice->GetLiveID(m_RenderData.texDisplay.resourceId); @@ -373,6 +403,8 @@ rdcarray ReplayOutput::GetHistogram(float minval, float maxval, bool c PixelValue ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample) { + CHECK_REPLAY_THREAD(); + PixelValue ret; RDCEraseEl(ret.floatValue); @@ -408,6 +440,8 @@ PixelValue ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x rdcpair ReplayOutput::PickVertex(uint32_t eventId, uint32_t x, uint32_t y) { + CHECK_REPLAY_THREAD(); + DrawcallDescription *draw = m_pRenderer->GetDrawcallByEID(eventId); const rdcpair errorReturn = make_rdcpair(~0U, ~0U); @@ -481,6 +515,8 @@ rdcpair ReplayOutput::PickVertex(uint32_t eventId, uint32_t void ReplayOutput::SetPixelContextLocation(uint32_t x, uint32_t y) { + CHECK_REPLAY_THREAD(); + m_ContextX = RDCMAX((float)x, 0.0f); m_ContextY = RDCMAX((float)y, 0.0f); @@ -489,6 +525,8 @@ void ReplayOutput::SetPixelContextLocation(uint32_t x, uint32_t y) void ReplayOutput::DisablePixelContext() { + CHECK_REPLAY_THREAD(); + m_ContextX = -1.0f; m_ContextY = -1.0f; @@ -497,6 +535,8 @@ void ReplayOutput::DisablePixelContext() void ReplayOutput::ClearBackground(uint64_t outputID, const FloatVector &backgroundColor) { + CHECK_REPLAY_THREAD(); + if(m_RenderData.texDisplay.backgroundColor.x == 0.0f && m_RenderData.texDisplay.backgroundColor.y == 0.0f && m_RenderData.texDisplay.backgroundColor.z == 0.0f && @@ -508,6 +548,8 @@ void ReplayOutput::ClearBackground(uint64_t outputID, const FloatVector &backgro void ReplayOutput::DisplayContext() { + CHECK_REPLAY_THREAD(); + if(m_PixelContext.outputID == 0) return; m_pDevice->BindOutputWindow(m_PixelContext.outputID, false); @@ -570,6 +612,8 @@ void ReplayOutput::DisplayContext() void ReplayOutput::Display() { + CHECK_REPLAY_THREAD(); + if(m_pDevice->CheckResizeOutputWindow(m_MainOutput.outputID)) { m_pDevice->GetOutputWindowDimensions(m_MainOutput.outputID, m_Width, m_Height); @@ -677,6 +721,8 @@ void ReplayOutput::Display() void ReplayOutput::DisplayTex() { + CHECK_REPLAY_THREAD(); + DrawcallDescription *draw = m_pRenderer->GetDrawcallByEID(m_EventID); if(m_MainOutput.outputID == 0) @@ -760,6 +806,8 @@ void ReplayOutput::DisplayTex() void ReplayOutput::DisplayMesh() { + CHECK_REPLAY_THREAD(); + DrawcallDescription *draw = m_pRenderer->GetDrawcallByEID(m_EventID); if(draw == NULL || m_MainOutput.outputID == 0 || m_Width <= 0 || m_Height <= 0 ||