Generalise progress tracking to allow multiple progress updates

* We track the progress through making a capture as well as the progress
  we already tracked loading a capture.
* Also incidentally fix a copy-paste bug that was calculating the wrong
  progress for loading captures by applying FileInitialRead instead of
  FrameEventsRead for the frame replay.
This commit is contained in:
baldurk
2017-12-29 14:25:33 +00:00
parent 332e9b70a3
commit ed98925eef
14 changed files with 173 additions and 62 deletions
+4 -25
View File
@@ -218,8 +218,6 @@ RenderDoc::RenderDoc()
m_CaptureKeys.push_back(eRENDERDOC_Key_F12);
m_CaptureKeys.push_back(eRENDERDOC_Key_PrtScrn);
m_ProgressPtr = NULL;
m_ExHandler = NULL;
m_Overlay = eRENDERDOC_Overlay_Default;
@@ -1041,31 +1039,10 @@ void RenderDoc::SetLogFile(const char *logFile)
FileIO::CreateParentDirectory(m_LogFile);
}
void RenderDoc::SetProgress(LoadProgressSection section, float delta)
{
if(m_ProgressPtr == NULL || section < 0 || section >= NumSections)
return;
float weights[NumSections];
// must sum to 1.0
weights[DebugManagerInit] = 0.1f;
weights[FileInitialRead] = 0.75f;
weights[FrameEventsRead] = 0.15f;
float progress = 0.0f;
for(int i = 0; i < section; i++)
{
progress += weights[i];
}
progress += weights[section] * delta;
*m_ProgressPtr = progress;
}
void RenderDoc::FinishCaptureWriting(RDCFile *rdc, uint32_t frameNumber)
{
RenderDoc::Inst().SetProgress(CaptureProgress::FileWriting, 0.0f);
if(rdc)
{
// add the resolve database if we were capturing callstacks.
@@ -1099,6 +1076,8 @@ void RenderDoc::FinishCaptureWriting(RDCFile *rdc, uint32_t frameNumber)
m_Captures.push_back(cap);
}
}
RenderDoc::Inst().SetProgress(CaptureProgress::FileWriting, 1.0f);
}
void RenderDoc::AddDeviceFrameCapturer(void *dev, IFrameCapturer *cap)
+77 -5
View File
@@ -221,14 +221,58 @@ struct CaptureData
bool retrieved;
};
enum LoadProgressSection
enum class LoadProgress
{
DebugManagerInit,
First = DebugManagerInit,
FileInitialRead,
FrameEventsRead,
NumSections,
Count,
};
DECLARE_REFLECTION_ENUM(LoadProgress);
ITERABLE_OPERATORS(LoadProgress);
inline constexpr float ProgressWeight(LoadProgress section)
{
// values must sum to 1.0
return section == LoadProgress::DebugManagerInit
? 0.1f
: section == LoadProgress::FileInitialRead
? 0.75f
: section == LoadProgress::FrameEventsRead ? 0.15f : 0.0f;
}
enum class CaptureProgress
{
PrepareInitialStates,
First = PrepareInitialStates,
// frame capture goes here but we have no way to estimate its length, and the progress would be
// updated all over the place as every API call or every draw call would have to update it.
AddReferencedResources,
SerialiseInitialStates,
SerialiseFrameContents,
FileWriting,
Count,
};
DECLARE_REFLECTION_ENUM(CaptureProgress);
ITERABLE_OPERATORS(CaptureProgress);
inline constexpr float ProgressWeight(CaptureProgress section)
{
// values must sum to 1.0
return section == CaptureProgress::PrepareInitialStates
? 0.35f
: section == CaptureProgress::AddReferencedResources
? 0.1f
: section == CaptureProgress::SerialiseInitialStates
? 0.5f
: section == CaptureProgress::SerialiseFrameContents
? 0.04f
: section == CaptureProgress::FileWriting ? 0.01f : 0.0f;
}
class IRemoteDriver;
class IReplayDriver;
@@ -262,8 +306,36 @@ class RenderDoc
public:
static RenderDoc &Inst();
void SetProgressPtr(float *progress) { m_ProgressPtr = progress; }
void SetProgress(LoadProgressSection section, float delta);
template <typename ProgressType>
void SetProgressPointer(float *progress)
{
m_ProgressPointers[TypeName<ProgressType>()] = progress;
}
template <typename ProgressType>
void SetProgress(ProgressType section, float delta)
{
float *ptr = m_ProgressPointers[TypeName<ProgressType>()];
if(ptr == NULL || section < ProgressType::First || section >= ProgressType::Count)
return;
float progress = 0.0f;
for(ProgressType s : values<ProgressType>())
{
if(s == section)
break;
progress += ProgressWeight(s);
}
progress += ProgressWeight(section) * delta;
// round up to ensure that we always finish on a 1.0 to let things know that the process is over
if(progress >= 0.9999f)
progress = 1.0f;
*ptr = progress;
}
// set from outside of the device creation interface
void SetLogFile(const char *logFile);
@@ -462,7 +534,7 @@ private:
Threading::CriticalSection m_DriverLock;
std::map<RDCDriver, uint64_t> m_ActiveDrivers;
float *m_ProgressPtr;
std::map<std::string, float *> m_ProgressPointers;
Threading::CriticalSection m_CaptureLock;
vector<CaptureData> m_Captures;
+2 -2
View File
@@ -406,7 +406,7 @@ static void ActiveRemoteClientThread(ClientThread *threadData)
bool kill = false;
float progress = 0.0f;
RenderDoc::Inst().SetProgressPtr(&progress);
RenderDoc::Inst().SetProgressPointer<LoadProgress>(&progress);
Threading::ThreadHandle ticker = Threading::CreateThread([&writer, &kill, &progress]() {
while(!kill)
@@ -439,7 +439,7 @@ static void ActiveRemoteClientThread(ClientThread *threadData)
}
else
{
RenderDoc::Inst().SetProgressPtr(NULL);
RenderDoc::Inst().SetProgressPointer<LoadProgress>(NULL);
kill = true;
Threading::JoinThread(ticker);
+24
View File
@@ -865,8 +865,14 @@ void ResourceManagerType::InsertReferencedChunks(WriteSerialiser &ser)
if(RenderDoc::Inst().GetCaptureOptions().refAllResources)
{
float num = float(m_ResourceRecords.size());
float idx = 0.0f;
for(auto it = m_ResourceRecords.begin(); it != m_ResourceRecords.end(); ++it)
{
RenderDoc::Inst().SetProgress(CaptureProgress::AddReferencedResources, idx / num);
idx += 1.0f;
if(!SerialisableResource(it->first, it->second))
continue;
@@ -875,8 +881,14 @@ void ResourceManagerType::InsertReferencedChunks(WriteSerialiser &ser)
}
else
{
float num = float(m_FrameReferencedResources.size());
float idx = 0.0f;
for(auto it = m_FrameReferencedResources.begin(); it != m_FrameReferencedResources.end(); ++it)
{
RenderDoc::Inst().SetProgress(CaptureProgress::AddReferencedResources, idx / num);
idx += 1.0f;
RecordType *record = GetResourceRecord(it->first);
if(record)
record->Insert(sortedChunks);
@@ -899,10 +911,16 @@ void ResourceManagerType::PrepareInitialContents()
RDCDEBUG("Preparing up to %u potentially dirty resources", (uint32_t)m_DirtyResources.size());
uint32_t prepared = 0;
float num = float(m_DirtyResources.size());
float idx = 0.0f;
for(auto it = m_DirtyResources.begin(); it != m_DirtyResources.end(); ++it)
{
ResourceId id = *it;
RenderDoc::Inst().SetProgress(CaptureProgress::PrepareInitialStates, idx / num);
idx += 1.0f;
if(!HasCurrentResource(id))
continue;
@@ -950,10 +968,16 @@ void ResourceManagerType::InsertInitialContentsChunks(WriteSerialiser &ser)
RDCDEBUG("Checking %u possibly dirty resources", (uint32_t)m_DirtyResources.size());
float num = float(m_DirtyResources.size());
float idx = 0.0f;
for(auto it = m_DirtyResources.begin(); it != m_DirtyResources.end(); ++it)
{
ResourceId id = *it;
RenderDoc::Inst().SetProgress(CaptureProgress::SerialiseInitialStates, idx / num);
idx += 1.0f;
if(m_FrameReferencedResources.find(id) == m_FrameReferencedResources.end() &&
!RenderDoc::Inst().GetCaptureOptions().refAllResources)
{
+2 -1
View File
@@ -1189,7 +1189,8 @@ ReplayStatus WrappedID3D11DeviceContext::ReplayLog(CaptureState readType, uint32
return m_FailedReplayStatus;
RenderDoc::Inst().SetProgress(
FrameEventsRead, float(m_CurChunkOffset - startOffset) / float(ser.GetReader()->GetSize()));
LoadProgress::FrameEventsRead,
float(m_CurChunkOffset - startOffset) / float(ser.GetReader()->GetSize()));
if((SystemChunk)chunktype == SystemChunk::CaptureEnd)
break;
+6 -6
View File
@@ -103,7 +103,7 @@ D3D11DebugManager::D3D11DebugManager(WrappedID3D11Device *wrapper)
wrapper->InternalRef();
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.0f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.0f);
m_pFactory = NULL;
@@ -156,7 +156,7 @@ D3D11DebugManager::D3D11DebugManager(WrappedID3D11Device *wrapper)
PostDeviceInitCounters();
RenderDoc::Inst().SetProgress(DebugManagerInit, 1.0f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 1.0f);
if(RenderDoc::Inst().IsReplayApp())
{
@@ -720,7 +720,7 @@ bool D3D11DebugManager::InitDebugRendering()
histogramhlsl += GetEmbeddedResource(debugcommon_hlsl);
histogramhlsl += GetEmbeddedResource(histogram_hlsl);
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.1f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.1f);
for(int t = eTexType_1D; t < eTexType_Max; t++)
{
@@ -745,13 +745,13 @@ bool D3D11DebugManager::InitDebugRendering()
MakeCShader(hlsl.c_str(), "RENDERDOC_ResultMinMaxCS", "cs_5_0");
RenderDoc::Inst().SetProgress(
DebugManagerInit,
LoadProgress::DebugManagerInit,
(float(i + 3.0f * t) / float(2.0f + 3.0f * (eTexType_Max - 1))) * 0.7f + 0.1f);
}
}
}
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.8f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.8f);
RDCCOMPILE_ASSERT(eTexType_1D == RESTYPE_TEX1D, "Tex type enum doesn't match shader defines");
RDCCOMPILE_ASSERT(eTexType_2D == RESTYPE_TEX2D, "Tex type enum doesn't match shader defines");
@@ -923,7 +923,7 @@ bool D3D11DebugManager::InitDebugRendering()
}
}
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.9f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.9f);
if(RenderDoc::Inst().IsReplayApp())
{
+9 -1
View File
@@ -1012,7 +1012,8 @@ ReplayStatus WrappedID3D11Device::ReadLogInitialisation(RDCFile *rdc, bool store
uint64_t offsetEnd = reader->GetOffset();
RenderDoc::Inst().SetProgress(FileInitialRead, float(offsetEnd) / float(reader->GetSize()));
RenderDoc::Inst().SetProgress(LoadProgress::FileInitialRead,
float(offsetEnd) / float(reader->GetSize()));
if((SystemChunk)context == SystemChunk::CaptureScope)
{
@@ -1722,8 +1723,15 @@ bool WrappedID3D11Device::EndFrameCapture(void *dev, void *wnd)
RDCDEBUG("Flushing %u records to file serialiser", (uint32_t)recordlist.size());
float num = float(recordlist.size());
float idx = 0.0f;
for(auto it = recordlist.begin(); it != recordlist.end(); ++it)
{
RenderDoc::Inst().SetProgress(CaptureProgress::SerialiseFrameContents, idx / num);
idx += 1.0f;
it->second->Write(ser);
}
RDCDEBUG("Done");
}
+3 -2
View File
@@ -629,8 +629,9 @@ ReplayStatus WrappedID3D12CommandQueue::ReplayLog(CaptureState readType, uint32_
if(!success)
return m_FailedReplayStatus;
RenderDoc::Inst().SetProgress(FileInitialRead, float(m_Cmd.m_CurChunkOffset - startOffset) /
float(ser.GetReader()->GetSize()));
RenderDoc::Inst().SetProgress(
LoadProgress::FrameEventsRead,
float(m_Cmd.m_CurChunkOffset - startOffset) / float(ser.GetReader()->GetSize()));
if((SystemChunk)context == SystemChunk::CaptureEnd)
break;
+7 -7
View File
@@ -110,7 +110,7 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
RDCEraseEl(m_TileMinMaxPipe);
RDCEraseEl(m_HistogramPipe);
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.0f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.0f);
m_pFactory = NULL;
@@ -281,7 +281,7 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
m_DebugList->Close();
}
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.2f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.2f);
// create fixed samplers, point and linear
D3D12_CPU_DESCRIPTOR_HANDLE samp;
@@ -310,7 +310,7 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
m_RingConstantBuffer = MakeCBuffer(bufsize);
m_RingConstantOffset = 0;
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.4f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.4f);
bool success = LoadShaderCache("d3d12shaders.cache", m_ShaderCacheMagic, m_ShaderCacheVersion,
m_ShaderCache, ShaderCache12Callbacks);
@@ -525,7 +525,7 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
SAFE_RELEASE(root);
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.6f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.6f);
D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeDesc;
RDCEraseEl(pipeDesc);
@@ -703,7 +703,7 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
histogramhlsl += GetEmbeddedResource(debugcommon_hlsl);
histogramhlsl += GetEmbeddedResource(histogram_hlsl);
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.7f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.7f);
D3D12_COMPUTE_PIPELINE_STATE_DESC compPipeDesc;
RDCEraseEl(compPipeDesc);
@@ -986,7 +986,7 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
m_WrappedDevice->CreateUnorderedAccessView(m_MinMaxResultBuffer, NULL, &tileDesc, uav);
}
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.8f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.8f);
// font rendering
{
@@ -1262,7 +1262,7 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
SAFE_RELEASE(TextPS);
}
RenderDoc::Inst().SetProgress(DebugManagerInit, 1.0f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 1.0f);
m_CacheShaders = false;
}
+9 -1
View File
@@ -1648,8 +1648,15 @@ bool WrappedID3D12Device::EndFrameCapture(void *dev, void *wnd)
RDCDEBUG("Flushing %u chunks to file serialiser from context record",
(uint32_t)recordlist.size());
float num = float(recordlist.size());
float idx = 0.0f;
for(auto it = recordlist.begin(); it != recordlist.end(); ++it)
{
RenderDoc::Inst().SetProgress(CaptureProgress::SerialiseFrameContents, idx / num);
idx += 1.0f;
it->second->Write(ser);
}
RDCDEBUG("Done");
}
@@ -2454,7 +2461,8 @@ ReplayStatus WrappedID3D12Device::ReadLogInitialisation(RDCFile *rdc, bool store
uint64_t offsetEnd = reader->GetOffset();
RenderDoc::Inst().SetProgress(FileInitialRead, float(offsetEnd) / float(reader->GetSize()));
RenderDoc::Inst().SetProgress(LoadProgress::FileInitialRead,
float(offsetEnd) / float(reader->GetSize()));
if((SystemChunk)context == SystemChunk::CaptureScope)
{
+6 -6
View File
@@ -247,7 +247,7 @@ void GLReplay::InitDebugData()
m_HighlightCache.driver = m_pDriver->GetReplay();
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.0f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.0f);
{
uint64_t id = MakeOutputWindow(WindowingSystem::Unknown, NULL, true);
@@ -308,7 +308,7 @@ void GLReplay::InitDebugData()
DebugData.texDisplayProg[i] = CreateShaderProgram(empty, fs);
}
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.2f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.2f);
if(GLCoreVersion >= 43 && !IsGLES)
{
@@ -414,7 +414,7 @@ void GLReplay::InitDebugData()
gl.glGenProgramPipelines(1, &DebugData.texDisplayPipe);
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.4f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.4f);
gl.glGenSamplers(1, &DebugData.linearSampler);
gl.glSamplerParameteri(DebugData.linearSampler, eGL_TEXTURE_MIN_FILTER, eGL_LINEAR);
@@ -470,7 +470,7 @@ void GLReplay::InitDebugData()
gl.glGenVertexArrays(1, &DebugData.emptyVAO);
gl.glBindVertexArray(DebugData.emptyVAO);
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.6f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.6f);
// histogram/minmax data
{
@@ -597,7 +597,7 @@ void GLReplay::InitDebugData()
"GL_ARB_compute_shader not supported, disabling mesh picking.");
}
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.8f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.8f);
DebugData.pickResultBuf = 0;
@@ -691,7 +691,7 @@ void GLReplay::InitDebugData()
gl.glBindBufferBase(eGL_TRANSFORM_FEEDBACK_BUFFER, 0, DebugData.feedbackBuffer);
gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, 0);
RenderDoc::Inst().SetProgress(DebugManagerInit, 1.0f);
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 1.0f);
if(!HasExt[ARB_gpu_shader5])
{
+11 -2
View File
@@ -2474,8 +2474,15 @@ bool WrappedOpenGL::EndFrameCapture(void *dev, void *wnd)
RDCDEBUG("Flushing %u records to file serialiser", (uint32_t)recordlist.size());
float num = float(recordlist.size());
float idx = 0.0f;
for(auto it = recordlist.begin(); it != recordlist.end(); ++it)
{
RenderDoc::Inst().SetProgress(CaptureProgress::SerialiseFrameContents, idx / num);
idx += 1.0f;
it->second->Write(ser);
}
RDCDEBUG("Done");
}
@@ -3137,7 +3144,8 @@ ReplayStatus WrappedOpenGL::ReadLogInitialisation(RDCFile *rdc, bool storeStruct
uint64_t offsetEnd = reader->GetOffset();
RenderDoc::Inst().SetProgress(FileInitialRead, float(offsetEnd) / float(reader->GetSize()));
RenderDoc::Inst().SetProgress(LoadProgress::FileInitialRead,
float(offsetEnd) / float(reader->GetSize()));
if((SystemChunk)context == SystemChunk::CaptureScope)
{
@@ -4773,7 +4781,8 @@ ReplayStatus WrappedOpenGL::ContextReplayLog(CaptureState readType, uint32_t sta
return m_FailedReplayStatus;
RenderDoc::Inst().SetProgress(
FileInitialRead, float(m_CurChunkOffset - startOffset) / float(ser.GetReader()->GetSize()));
LoadProgress::FrameEventsRead,
float(m_CurChunkOffset - startOffset) / float(ser.GetReader()->GetSize()));
if((SystemChunk)chunktype == SystemChunk::CaptureEnd)
break;
+11 -2
View File
@@ -1369,8 +1369,15 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd)
RDCDEBUG("Flushing %u chunks to file serialiser from context record",
(uint32_t)recordlist.size());
float num = float(recordlist.size());
float idx = 0.0f;
for(auto it = recordlist.begin(); it != recordlist.end(); ++it)
{
RenderDoc::Inst().SetProgress(CaptureProgress::SerialiseFrameContents, idx / num);
idx += 1.0f;
it->second->Write(ser);
}
RDCDEBUG("Done");
}
@@ -1498,7 +1505,8 @@ ReplayStatus WrappedVulkan::ReadLogInitialisation(RDCFile *rdc, bool storeStruct
uint64_t offsetEnd = reader->GetOffset();
RenderDoc::Inst().SetProgress(FileInitialRead, float(offsetEnd) / float(reader->GetSize()));
RenderDoc::Inst().SetProgress(LoadProgress::FileInitialRead,
float(offsetEnd) / float(reader->GetSize()));
if((SystemChunk)context == SystemChunk::CaptureScope)
{
@@ -1672,7 +1680,8 @@ ReplayStatus WrappedVulkan::ContextReplayLog(CaptureState readType, uint32_t sta
return m_FailedReplayStatus;
RenderDoc::Inst().SetProgress(
FileInitialRead, float(m_CurChunkOffset - startOffset) / float(ser.GetReader()->GetSize()));
LoadProgress::FrameEventsRead,
float(m_CurChunkOffset - startOffset) / float(ser.GetReader()->GetSize()));
if((SystemChunk)chunktype == SystemChunk::CaptureEnd)
break;
+2 -2
View File
@@ -332,11 +332,11 @@ rdcpair<ReplayStatus, IReplayController *> CaptureFile::OpenCapture(float *progr
ReplayController *render = new ReplayController();
ReplayStatus ret;
RenderDoc::Inst().SetProgressPtr(progress);
RenderDoc::Inst().SetProgressPointer<LoadProgress>(progress);
ret = render->CreateDevice(m_RDC);
RenderDoc::Inst().SetProgressPtr(NULL);
RenderDoc::Inst().SetProgressPointer<LoadProgress>(NULL);
if(ret != ReplayStatus::Succeeded)
SAFE_DELETE(render);