Add ability to convert a capture to structured data without replaying

This commit is contained in:
baldurk
2017-10-05 16:58:49 +01:00
parent 15f78b7ffd
commit 7ca6c80414
21 changed files with 347 additions and 68 deletions
+17
View File
@@ -784,6 +784,13 @@ void RenderDoc::RegisterRemoteProvider(RDCDriver driver, const char *name,
m_RemoteDriverProviders[driver] = provider;
}
void RenderDoc::RegisterStructuredProcessor(RDCDriver driver, StructuredProcessor provider)
{
RDCASSERT(m_StructProcesssors.find(driver) == m_StructProcesssors.end());
m_StructProcesssors[driver] = provider;
}
void RenderDoc::RegisterCaptureExporter(const char *filetype, const char *description,
CaptureExporter exporter)
{
@@ -805,6 +812,16 @@ void RenderDoc::RegisterCaptureImportExporter(const char *filetype, const char *
m_Exporters[filetype] = exporter;
}
StructuredProcessor RenderDoc::GetStructuredProcessor(RDCDriver driver)
{
auto it = m_StructProcesssors.find(driver);
if(it == m_StructProcesssors.end())
return NULL;
return it->second;
}
CaptureExporter RenderDoc::GetCaptureExporter(const char *filetype)
{
auto it = m_Exporters.find(filetype);
+21
View File
@@ -142,6 +142,11 @@ constexpr inline bool IsActiveCapturing(CaptureState state)
return state == CaptureState::ActiveCapturing;
}
constexpr inline bool IsStructuredExporting(CaptureState state)
{
return state == CaptureState::StructuredExport;
}
enum class SystemChunk : uint32_t
{
// 0 is reserved as a 'null' chunk that is only for debug
@@ -232,6 +237,8 @@ class RDCFile;
typedef ReplayStatus (*RemoteDriverProvider)(RDCFile *rdc, IRemoteDriver **driver);
typedef ReplayStatus (*ReplayDriverProvider)(RDCFile *rdc, IReplayDriver **driver);
typedef void (*StructuredProcessor)(RDCFile *rdc, SDFile &structData);
typedef ReplayStatus (*CaptureImporter)(const char *filename, StreamReader &reader, RDCFile *rdc,
SDFile &structData);
typedef ReplayStatus (*CaptureExporter)(const char *filename, const RDCFile &rdc,
@@ -311,11 +318,15 @@ public:
void RegisterReplayProvider(RDCDriver driver, const char *name, ReplayDriverProvider provider);
void RegisterRemoteProvider(RDCDriver driver, const char *name, RemoteDriverProvider provider);
void RegisterStructuredProcessor(RDCDriver driver, StructuredProcessor provider);
void RegisterCaptureExporter(const char *filetype, const char *description,
CaptureExporter exporter);
void RegisterCaptureImportExporter(const char *filetype, const char *description,
CaptureImporter importer, CaptureExporter exporter);
StructuredProcessor GetStructuredProcessor(RDCDriver driver);
CaptureExporter GetCaptureExporter(const char *filetype);
CaptureImporter GetCaptureImporter(const char *filetype);
@@ -462,6 +473,8 @@ private:
map<RDCDriver, ReplayDriverProvider> m_ReplayDriverProviders;
map<RDCDriver, RemoteDriverProvider> m_RemoteDriverProviders;
std::map<RDCDriver, StructuredProcessor> m_StructProcesssors;
std::map<std::string, std::string> m_ImportExportFormats;
std::map<std::string, CaptureImporter> m_Importers;
std::map<std::string, CaptureExporter> m_Exporters;
@@ -542,6 +555,14 @@ struct DriverRegistration
}
};
struct StructuredProcessRegistration
{
StructuredProcessRegistration(RDCDriver driver, StructuredProcessor provider)
{
RenderDoc::Inst().RegisterStructuredProcessor(driver, provider);
}
};
struct ConversionRegistration
{
ConversionRegistration(const char *filetype, const char *description, CaptureImporter importer,
+1 -1
View File
@@ -148,7 +148,7 @@ public:
FrameRecord GetFrameRecord() { return m_FrameRecord; }
const D3D11Pipe::State &GetD3D11PipelineState() { return m_PipelineState; }
// other operations are dropped/ignored, to avoid confusion
void ReadLogInitialisation(RDCFile *rdc) {}
void ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers) {}
void RenderMesh(uint32_t eventID, const vector<MeshFormat> &secondaryDraws, const MeshDisplay &cfg)
{
}
+1 -1
View File
@@ -424,7 +424,7 @@ static void ActiveRemoteClientThread(ClientThread *threadData)
}
else
{
driver->ReadLogInitialisation(rdc);
driver->ReadLogInitialisation(rdc, false);
RenderDoc::Inst().SetProgressPtr(NULL);
+1 -1
View File
@@ -115,7 +115,7 @@ public:
bool IsRemoteProxy() { return !m_RemoteServer; }
void Shutdown() { delete this; }
void ReadLogInitialisation(RDCFile *rdc) {}
void ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers) {}
vector<WindowingSystem> GetSupportedWindowSystems()
{
if(m_Proxy)
+23 -11
View File
@@ -97,23 +97,27 @@ WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *real
D3D11_FEATURE_DATA_D3D11_OPTIONS features;
RDCEraseEl(features);
HRESULT hr =
m_pDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &features, sizeof(features));
HRESULT hr = S_OK;
if(m_pRealContext)
hr = m_pDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &features, sizeof(features));
m_SetCBuffer1 = false;
if(SUCCEEDED(hr))
m_SetCBuffer1 = features.ConstantBufferOffsetting == TRUE;
m_pRealContext1 = NULL;
m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext1), (void **)&m_pRealContext1);
m_pRealContext2 = NULL;
m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext2), (void **)&m_pRealContext2);
m_pRealContext3 = NULL;
m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext3), (void **)&m_pRealContext3);
if(m_pRealContext)
{
m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext1), (void **)&m_pRealContext1);
m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext2), (void **)&m_pRealContext2);
m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext3), (void **)&m_pRealContext3);
}
m_NeedUpdateSubWorkaround = false;
if(m_pRealContext)
{
D3D11_FEATURE_DATA_THREADING caps = {FALSE, FALSE};
@@ -167,7 +171,7 @@ WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *real
m_DeferredSavedState = NULL;
m_DoStateVerify = IsCaptureMode(m_State);
if(context->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE)
if(!context || context->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE)
{
m_CurrentPipelineState->SetImmediatePipeline(m_pDevice);
}
@@ -188,7 +192,7 @@ WrappedID3D11DeviceContext::~WrappedID3D11DeviceContext()
if(m_ContextRecord)
m_ContextRecord->Delete(m_pDevice->GetResourceManager());
if(m_pRealContext->GetType() != D3D11_DEVICE_CONTEXT_IMMEDIATE)
if(m_pRealContext && m_pRealContext->GetType() != D3D11_DEVICE_CONTEXT_IMMEDIATE)
m_pDevice->RemoveDeferredContext(this);
for(auto it = m_StreamOutCounters.begin(); it != m_StreamOutCounters.end(); ++it)
@@ -1049,8 +1053,12 @@ void WrappedID3D11DeviceContext::ReplayLog(CaptureState readType, uint32_t start
ser.SetStringDatabase(&m_StringDB);
ser.SetUserData(GetResourceManager());
if(IsLoading(m_State))
ser.ConfigureStructuredExport(&GetChunkName, false);
if(IsLoading(m_State) || IsStructuredExporting(m_State))
{
ser.ConfigureStructuredExport(&GetChunkName, IsStructuredExporting(m_State));
ser.GetStructuredFile().swap(m_pDevice->GetStructuredFile());
}
m_DoStateVerify = true;
@@ -1196,6 +1204,10 @@ void WrappedID3D11DeviceContext::ReplayLog(CaptureState readType, uint32_t start
// RDCDEBUG("Can skip %d initial states.", initialSkips);
}
// swap the structure back now that we've accumulated the frame as well.
if(IsLoading(m_State) || IsStructuredExporting(m_State))
ser.GetStructuredFile().swap(m_pDevice->GetStructuredFile());
m_pDevice->GetResourceManager()->MarkInFrame(false);
m_DoStateVerify = false;
+46 -28
View File
@@ -68,17 +68,19 @@ WrappedID3D11Device::WrappedID3D11Device(ID3D11Device *realDevice, D3D11InitPara
m_ScratchSerialiser.SetChunkMetadataRecording(flags);
m_StructuredFile = &m_StoredStructuredData;
m_pDevice1 = NULL;
m_pDevice->QueryInterface(__uuidof(ID3D11Device1), (void **)&m_pDevice1);
m_pDevice2 = NULL;
m_pDevice->QueryInterface(__uuidof(ID3D11Device2), (void **)&m_pDevice2);
m_pDevice3 = NULL;
m_pDevice->QueryInterface(__uuidof(ID3D11Device3), (void **)&m_pDevice3);
m_pDevice4 = NULL;
m_pDevice->QueryInterface(__uuidof(ID3D11Device4), (void **)&m_pDevice4);
if(m_pDevice)
{
m_pDevice->QueryInterface(__uuidof(ID3D11Device1), (void **)&m_pDevice1);
m_pDevice->QueryInterface(__uuidof(ID3D11Device2), (void **)&m_pDevice2);
m_pDevice->QueryInterface(__uuidof(ID3D11Device3), (void **)&m_pDevice3);
m_pDevice->QueryInterface(__uuidof(ID3D11Device4), (void **)&m_pDevice4);
}
m_Replay.SetDevice(this);
@@ -104,12 +106,6 @@ WrappedID3D11Device::WrappedID3D11Device(ID3D11Device *realDevice, D3D11InitPara
m_AppControlledCapture = false;
#if ENABLED(RDOC_RELEASE)
const bool debugSerialiser = false;
#else
const bool debugSerialiser = true;
#endif
if(RenderDoc::Inst().IsReplayApp())
{
m_State = CaptureState::LoadingReplaying;
@@ -148,17 +144,22 @@ WrappedID3D11Device::WrappedID3D11Device(ID3D11Device *realDevice, D3D11InitPara
}
ID3D11DeviceContext *context = NULL;
realDevice->GetImmediateContext(&context);
if(realDevice)
realDevice->GetImmediateContext(&context);
m_pImmediateContext = new WrappedID3D11DeviceContext(this, context);
realDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&m_pInfoQueue);
realDevice->QueryInterface(__uuidof(ID3D11Debug), (void **)&m_WrappedDebug.m_pDebug);
m_pInfoQueue = NULL;
if(realDevice)
{
realDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&m_pInfoQueue);
realDevice->QueryInterface(__uuidof(ID3D11Debug), (void **)&m_WrappedDebug.m_pDebug);
}
// useful for marking regions during replay for self-captures
m_RealAnnotations = NULL;
m_pImmediateContext->GetReal()->QueryInterface(__uuidof(ID3DUserDefinedAnnotation),
(void **)&m_RealAnnotations);
if(context)
context->QueryInterface(__uuidof(ID3DUserDefinedAnnotation), (void **)&m_RealAnnotations);
if(m_pInfoQueue)
{
@@ -186,12 +187,13 @@ WrappedID3D11Device::WrappedID3D11Device(ID3D11Device *realDevice, D3D11InitPara
if(RenderDoc::Inst().IsReplayApp())
m_pInfoQueue->SetMuteDebugOutput(false);
}
else
else if(m_pDevice)
{
RDCDEBUG("Couldn't get ID3D11InfoQueue.");
}
m_InitParams = *params;
if(params)
m_InitParams = *params;
// ATI workaround - these dlls can get unloaded and cause a crash.
@@ -752,8 +754,11 @@ void WrappedID3D11Device::ProcessChunk(ReadSerialiser &ser, D3D11Chunk context)
// add a reference for the resource manager - normally it takes ownership of the resource on
// creation and releases it
// to destruction, but we want to control our immediate context ourselves.
m_pImmediateContext->AddRef();
m_ResourceManager->AddLiveResource(ImmediateContext, m_pImmediateContext);
if(IsReplayingAndReading())
{
m_pImmediateContext->AddRef();
m_ResourceManager->AddLiveResource(ImmediateContext, m_pImmediateContext);
}
break;
}
case D3D11Chunk::SetResourceName: Serialise_SetResourceName(ser, 0x0, ""); break;
@@ -901,7 +906,7 @@ void WrappedID3D11Device::Serialise_CaptureScope(SerialiserType &ser)
}
}
void WrappedID3D11Device::ReadLogInitialisation(RDCFile *rdc)
void WrappedID3D11Device::ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers)
{
int sectionIdx = rdc->SectionIndex(SectionType::FrameCapture);
@@ -918,8 +923,11 @@ void WrappedID3D11Device::ReadLogInitialisation(RDCFile *rdc)
ser.SetStringDatabase(&m_StringDB);
ser.SetUserData(GetResourceManager());
// TODO make this an option passed in
ser.ConfigureStructuredExport(&GetChunkName, false);
ser.ConfigureStructuredExport(&GetChunkName, storeStructuredBuffers);
m_StructuredFile = &ser.GetStructuredFile();
m_StoredStructuredData.version = m_StructuredFile->version = m_SectionVersion;
int chunkIdx = 0;
@@ -964,7 +972,8 @@ void WrappedID3D11Device::ReadLogInitialisation(RDCFile *rdc)
m_pImmediateContext->SetFrameReader(new StreamReader(reader, frameDataSize));
GetResourceManager()->ApplyInitialContents();
if(!IsStructuredExporting(m_State))
GetResourceManager()->ApplyInitialContents();
m_pImmediateContext->ReplayLog(m_State, 0, 0, false);
}
@@ -977,8 +986,17 @@ void WrappedID3D11Device::ReadLogInitialisation(RDCFile *rdc)
break;
}
DrawcallDescription *previous = NULL;
SetupDrawcallPointers(&m_Drawcalls, GetFrameRecord().drawcallList, NULL, previous);
// steal the structured data for ourselves
m_StructuredFile->swap(m_StoredStructuredData);
// and in future use this file.
m_StructuredFile = &m_StoredStructuredData;
if(!IsStructuredExporting(m_State))
{
DrawcallDescription *previous = NULL;
SetupDrawcallPointers(&m_Drawcalls, GetFrameRecord().drawcallList, NULL, previous);
}
#if ENABLED(RDOC_DEVEL)
for(auto it = chunkInfos.begin(); it != chunkInfos.end(); ++it)
+10 -1
View File
@@ -393,6 +393,9 @@ private:
CaptureFailReason m_FailedReason;
uint32_t m_Failures;
SDFile *m_StructuredFile = NULL;
SDFile m_StoredStructuredData;
vector<DebugMessage> m_DebugMessages;
vector<FrameDescription> m_CapturedFrames;
@@ -440,6 +443,7 @@ public:
void LockForChunkRemoval();
void UnlockForChunkRemoval();
SDFile &GetStructuredFile() { return *m_StructuredFile; }
void FirstFrame(WrappedIDXGISwapChain4 *swapChain);
std::vector<DebugMessage> GetDebugMessages();
@@ -500,7 +504,12 @@ public:
void Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData);
void Apply_InitialState(ID3D11DeviceChild *live, D3D11ResourceManager::InitialContentData initial);
void ReadLogInitialisation(RDCFile *rdc);
void SetStructuredExport(uint64_t sectionVersion)
{
m_SectionVersion = sectionVersion;
m_State = CaptureState::StructuredExport;
}
void ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers);
void ProcessChunk(ReadSerialiser &ser, D3D11Chunk context);
void ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType);
@@ -934,6 +934,9 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId
void WrappedID3D11Device::Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData)
{
if(IsStructuredExporting(m_State))
return;
ResourceType type = IdentifyTypeByPtr(live);
{
+15 -2
View File
@@ -1290,9 +1290,9 @@ void D3D11Replay::SavePipelineState()
}
}
void D3D11Replay::ReadLogInitialisation(RDCFile *rdc)
void D3D11Replay::ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers)
{
m_pDevice->ReadLogInitialisation(rdc);
m_pDevice->ReadLogInitialisation(rdc, storeStructuredBuffers);
}
void D3D11Replay::ReplayLog(uint32_t endEventID, ReplayLogType replayType)
@@ -2110,3 +2110,16 @@ ReplayStatus D3D11_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
}
static DriverRegistration D3D11DriverRegistration(RDC_D3D11, "D3D11", &D3D11_CreateReplayDevice);
void D3D11_ProcessStructured(RDCFile *rdc, SDFile &output)
{
WrappedID3D11Device device(NULL, NULL);
device.SetStructuredExport(
rdc->GetSectionProperties(rdc->SectionIndex(SectionType::FrameCapture)).version);
device.ReadLogInitialisation(rdc, true);
device.GetStructuredFile().swap(output);
}
static StructuredProcessRegistration D3D11ProcessRegistration(RDC_D3D11, &D3D11_ProcessStructured);
+1 -1
View File
@@ -73,7 +73,7 @@ public:
void FreeTargetResource(ResourceId id);
void FreeCustomShader(ResourceId id);
void ReadLogInitialisation(RDCFile *rdc);
void ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers);
void ReplayLog(uint32_t endEventID, ReplayLogType replayType);
vector<uint32_t> GetPassEvents(uint32_t eventID);
+42 -11
View File
@@ -99,6 +99,8 @@ WrappedVulkan::WrappedVulkan() : m_RenderState(this, &m_CreationInfo)
m_State = CaptureState::BackgroundCapturing;
}
m_StructuredFile = &m_StoredStructuredData;
m_SectionVersion = VkInitParams::CurrentVersion;
InitSPIRVCompiler();
@@ -1383,7 +1385,7 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd)
return true;
}
void WrappedVulkan::ReadLogInitialisation(RDCFile *rdc)
void WrappedVulkan::ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers)
{
int sectionIdx = rdc->SectionIndex(SectionType::FrameCapture);
@@ -1400,9 +1402,11 @@ void WrappedVulkan::ReadLogInitialisation(RDCFile *rdc)
ser.SetStringDatabase(&m_StringDB);
ser.SetUserData(GetResourceManager());
// TODO make this an option passed in
ser.ConfigureStructuredExport(&GetChunkName, false);
ser.ConfigureStructuredExport(&GetChunkName, storeStructuredBuffers);
m_StructuredFile = &ser.GetStructuredFile();
m_StoredStructuredData.version = m_StructuredFile->version = m_SectionVersion;
int chunkIdx = 0;
@@ -1472,6 +1476,12 @@ void WrappedVulkan::ReadLogInitialisation(RDCFile *rdc)
}
#endif
// steal the structured data for ourselves
m_StructuredFile->swap(m_StoredStructuredData);
// and in future use this file.
m_StructuredFile = &m_StoredStructuredData;
m_FrameRecord.frameInfo.uncompressedFileSize =
rdc->GetSectionProperties(sectionIdx).uncompressedSize;
m_FrameRecord.frameInfo.compressedFileSize = rdc->GetSectionProperties(sectionIdx).compressedSize;
@@ -1483,8 +1493,11 @@ void WrappedVulkan::ReadLogInitialisation(RDCFile *rdc)
m_FrameRecord.frameInfo.persistentSize);
// ensure the capture at least created a device and fetched a queue.
RDCASSERT(m_Device != VK_NULL_HANDLE && m_Queue != VK_NULL_HANDLE &&
m_InternalCmds.cmdpool != VK_NULL_HANDLE);
if(!IsStructuredExporting(m_State))
{
RDCASSERT(m_Device != VK_NULL_HANDLE && m_Queue != VK_NULL_HANDLE &&
m_InternalCmds.cmdpool != VK_NULL_HANDLE);
}
}
void WrappedVulkan::ContextReplayLog(CaptureState readType, uint32_t startEventID,
@@ -1497,9 +1510,17 @@ void WrappedVulkan::ContextReplayLog(CaptureState readType, uint32_t startEventI
ser.SetStringDatabase(&m_StringDB);
ser.SetUserData(GetResourceManager());
if(IsLoading(m_State))
SDFile *prevFile = m_StructuredFile;
if(IsLoading(m_State) || IsStructuredExporting(m_State))
{
ser.ConfigureStructuredExport(&GetChunkName, false);
ser.GetStructuredFile().swap(*m_StructuredFile);
m_StructuredFile = &ser.GetStructuredFile();
}
VulkanChunk header = ser.ReadChunk<VulkanChunk>();
RDCASSERTEQUAL(header, VulkanChunk::CaptureBegin);
@@ -1510,7 +1531,8 @@ void WrappedVulkan::ContextReplayLog(CaptureState readType, uint32_t startEventI
ser.EndChunk();
ObjDisp(GetDev())->DeviceWaitIdle(Unwrap(GetDev()));
if(!IsStructuredExporting(m_State))
ObjDisp(GetDev())->DeviceWaitIdle(Unwrap(GetDev()));
// apply initial contents here so that images are in the right layout
// (not undefined)
@@ -1606,6 +1628,12 @@ void WrappedVulkan::ContextReplayLog(CaptureState readType, uint32_t startEventI
}
}
// swap the structure back now that we've accumulated the frame as well.
if(IsLoading(m_State) || IsStructuredExporting(m_State))
ser.GetStructuredFile().swap(*prevFile);
m_StructuredFile = prevFile;
if(IsLoading(m_State))
{
GetFrameRecord().drawcallList = m_ParentDrawcall.Bake();
@@ -1622,11 +1650,14 @@ void WrappedVulkan::ContextReplayLog(CaptureState readType, uint32_t startEventI
m_ParentDrawcall.children.clear();
}
ObjDisp(GetDev())->DeviceWaitIdle(Unwrap(GetDev()));
if(!IsStructuredExporting(m_State))
{
ObjDisp(GetDev())->DeviceWaitIdle(Unwrap(GetDev()));
// destroy any events we created for waiting on
for(size_t i = 0; i < m_CleanupEvents.size(); i++)
ObjDisp(GetDev())->DestroyEvent(Unwrap(GetDev()), m_CleanupEvents[i], NULL);
// destroy any events we created for waiting on
for(size_t i = 0; i < m_CleanupEvents.size(); i++)
ObjDisp(GetDev())->DestroyEvent(Unwrap(GetDev()), m_CleanupEvents[i], NULL);
}
m_CleanupEvents.clear();
+10 -1
View File
@@ -259,6 +259,9 @@ private:
VulkanDrawcallCallback *m_DrawcallCallback;
SDFile *m_StructuredFile;
SDFile m_StoredStructuredData;
// util function to handle fetching the right eventID, calling any
// aliases then calling PreDraw/PreDispatch.
uint32_t HandlePreCallback(VkCommandBuffer commandBuffer, DrawFlags type = DrawFlags::Drawcall,
@@ -742,10 +745,16 @@ public:
ReplayStatus Initialise(VkInitParams &params, uint64_t sectionVersion);
uint64_t GetLogVersion() { return m_SectionVersion; }
void SetStructuredExport(uint64_t sectionVersion)
{
m_SectionVersion = sectionVersion;
m_State = CaptureState::StructuredExport;
}
void Shutdown();
void ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType);
void ReadLogInitialisation(RDCFile *rdc);
void ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers);
SDFile &GetStructuredFile() { return *m_StructuredFile; }
FrameRecord &GetFrameRecord() { return m_FrameRecord; }
const APIEvent &GetEvent(uint32_t eventID);
uint32_t GetMaxEID() { return m_Events.back().eventID; }
+6 -2
View File
@@ -712,7 +712,7 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W
}
else if(type == eResDeviceMemory || type == eResImage)
{
VkDevice d = GetDev();
VkDevice d = !IsStructuredExporting(m_State) ? GetDev() : VK_NULL_HANDLE;
VulkanResourceManager::InitialContentData initContents =
GetResourceManager()->GetInitialContents(id);
@@ -797,7 +797,8 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W
ser.Serialise("Contents", Contents, ContentsSize, SerialiserFlags::NoFlags);
// unmap the resource we mapped before - we need to do this on read and on write.
ObjDisp(d)->UnmapMemory(Unwrap(d), Unwrap(mappedMem));
if(!IsStructuredExporting(m_State))
ObjDisp(d)->UnmapMemory(Unwrap(d), Unwrap(mappedMem));
// if we're handling a device memory object, we're done - we note the memory object to delete at
// the end of the program, and store the buffer to copy off in Apply
@@ -1023,6 +1024,9 @@ template bool WrappedVulkan::Serialise_InitialState(WriteSerialiser &ser, Resour
void WrappedVulkan::Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData)
{
if(IsStructuredExporting(m_State))
return;
VkResourceType type = IdentifyTypeByPtr(live);
if(type == eResDescriptorSet)
+14 -2
View File
@@ -659,9 +659,9 @@ APIProperties VulkanReplay::GetAPIProperties()
return ret;
}
void VulkanReplay::ReadLogInitialisation(RDCFile *rdc)
void VulkanReplay::ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers)
{
m_pDriver->ReadLogInitialisation(rdc);
m_pDriver->ReadLogInitialisation(rdc, storeStructuredBuffers);
}
void VulkanReplay::ReplayLog(uint32_t endEventID, ReplayLogType replayType)
@@ -5429,3 +5429,15 @@ struct VulkanDriverRegistration
};
static VulkanDriverRegistration VkDriverRegistration;
void Vulkan_ProcessStructured(RDCFile *rdc, SDFile &output)
{
WrappedVulkan vulkan;
vulkan.SetStructuredExport(
rdc->GetSectionProperties(rdc->SectionIndex(SectionType::FrameCapture)).version);
vulkan.ReadLogInitialisation(rdc, true);
vulkan.GetStructuredFile().swap(output);
}
static StructuredProcessRegistration VulkanProcessRegistration(RDC_Vulkan, &Vulkan_ProcessStructured);
+1 -1
View File
@@ -159,7 +159,7 @@ public:
const VKPipe::State &GetVulkanPipelineState() { return m_VulkanPipelineState; }
void FreeTargetResource(ResourceId id);
void ReadLogInitialisation(RDCFile *rdc);
void ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers);
void ReplayLog(uint32_t endEventID, ReplayLogType replayType);
vector<uint32_t> GetPassEvents(uint32_t eventID);
@@ -478,7 +478,7 @@ template <typename SerialiserType>
bool WrappedVulkan::Serialise_SparseBufferInitialState(
SerialiserType &ser, ResourceId id, VulkanResourceManager::InitialContentData contents)
{
VkDevice d = GetDev();
VkDevice d = !IsStructuredExporting(m_State) ? GetDev() : VK_NULL_HANDLE;
VkResult vkr = VK_SUCCESS;
SparseBufferInitState *info = (SparseBufferInitState *)contents.blob;
@@ -580,7 +580,7 @@ template <typename SerialiserType>
bool WrappedVulkan::Serialise_SparseImageInitialState(SerialiserType &ser, ResourceId id,
VulkanResourceManager::InitialContentData contents)
{
VkDevice d = GetDev();
VkDevice d = !IsStructuredExporting(m_State) ? GetDev() : VK_NULL_HANDLE;
VkResult vkr = VK_SUCCESS;
SparseImageInitState *info = (SparseImageInitState *)contents.blob;
+11 -1
View File
@@ -131,7 +131,17 @@ public:
const SDFile &GetStructuredData()
{
// TODO - fetch structured data from capture on demand?
if(m_StructuredData.chunks.empty() && m_RDC && m_RDC->SectionIndex(SectionType::FrameCapture) >= 0)
{
// decompile to structured data on demand.
StructuredProcessor proc = RenderDoc::Inst().GetStructuredProcessor(m_RDC->GetDriver());
if(proc)
proc(m_RDC, m_StructuredData);
else
RDCERR("Can't get structured data for driver %s", m_RDC->GetDriverName().c_str());
}
return m_StructuredData;
}
+1 -1
View File
@@ -1545,7 +1545,7 @@ ReplayStatus ReplayController::PostCreateInit(IReplayDriver *device, RDCFile *rd
{
m_pDevice = device;
m_pDevice->ReadLogInitialisation(rdc);
m_pDevice->ReadLogInitialisation(rdc, false);
FetchPipelineState();
+1 -1
View File
@@ -114,7 +114,7 @@ public:
virtual FrameRecord GetFrameRecord() = 0;
virtual void ReadLogInitialisation(RDCFile *rdc) = 0;
virtual void ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers) = 0;
virtual void ReplayLog(uint32_t endEventID, ReplayLogType replayType) = 0;
virtual vector<uint32_t> GetPassEvents(uint32_t eventID) = 0;
+120
View File
@@ -618,6 +618,125 @@ struct ReplayCommand : public Command
}
};
struct ConvertCommand : public Command
{
rdcarray<CaptureFileFormat> m_Formats;
ConvertCommand(const GlobalEnvironment &env) : Command(env)
{
ICaptureFile *tmp = RENDERDOC_OpenCaptureFile();
m_Formats = tmp->GetCaptureFileFormats();
tmp->Shutdown();
}
virtual void AddOptions(cmdline::parser &parser)
{
cmdline::oneof_reader<string> formatOptions;
for(CaptureFileFormat f : m_Formats)
formatOptions.add(f.name);
parser.add<string>("filename", 'f', "The file to convert from.", false);
parser.add<string>("output", 'o', "The file to convert from.", false);
parser.add<string>("input-format", 'i', "The format of the input file.", false, "",
formatOptions);
parser.add<string>("convert-format", 'c', "The format of the output file.", false, "",
formatOptions);
parser.add("list-formats", '\0', "print a list of target formats");
parser.stop_at_rest(true);
}
virtual const char *Description() { return "Run internal tests such as unit tests."; }
virtual bool IsInternalOnly() { return false; }
virtual bool IsCaptureCommand() { return false; }
virtual int Execute(cmdline::parser &parser, const CaptureOptions &)
{
if(parser.exist("list-formats"))
{
std::cerr << "Available formats:" << std::endl;
for(CaptureFileFormat f : m_Formats)
std::cerr << "'" << (std::string)f.name << "': " << (std::string)f.description << std::endl;
return 0;
}
std::string infile = parser.get<string>("filename");
std::string outfile = parser.get<string>("output");
if(infile.empty())
{
std::cerr << "Need an input filename." << std::endl;
std::cerr << parser.usage() << std::endl;
return 1;
}
if(outfile.empty())
{
std::cerr << "Need an output filename." << std::endl;
std::cerr << parser.usage() << std::endl;
return 1;
}
std::string infmt = parser.get<string>("input-format");
std::string outfmt = parser.get<string>("convert-format");
if(infmt.empty())
{
// try to guess the format by looking for the extension in the filename
for(CaptureFileFormat f : m_Formats)
{
string extension = ".";
extension += f.name;
if(infile.find(extension.c_str()) != string::npos)
{
infmt = f.name;
break;
}
}
}
if(outfmt.empty())
{
// try to guess the format by looking for the extension in the filename
for(CaptureFileFormat f : m_Formats)
{
string extension = ".";
extension += f.name;
if(outfile.find(extension.c_str()) != string::npos)
{
outfmt = f.name;
break;
}
}
}
ICaptureFile *file = RENDERDOC_OpenCaptureFile();
ReplayStatus st = file->OpenFile(infile.c_str(), infmt.c_str());
if(st != ReplayStatus::Succeeded)
{
std::cerr << "Couldn't load '" << infile << "' as '" << infmt << "': " << ToStr(st)
<< std::endl;
return 1;
}
st = file->Convert(outfile.c_str(), outfmt.c_str());
if(st != ReplayStatus::Succeeded)
{
std::cerr << "Couldn't convert '" << infile << "' to '" << outfile << "' as '" << outfmt
<< "': " << ToStr(st) << std::endl;
return 1;
}
std::cout << "Converted '" << infile << "' to '" << outfile << "'" << std::endl;
return 0;
}
};
struct TestCommand : public Command
{
TestCommand(const GlobalEnvironment &env) : Command(env) {}
@@ -783,6 +902,7 @@ int renderdoccmd(const GlobalEnvironment &env, std::vector<std::string> &argv)
add_command("replay", new ReplayCommand(env));
add_command("capaltbit", new CapAltBitCommand(env));
add_command("test", new TestCommand(env));
add_command("convert", new ConvertCommand(env));
if(argv.size() <= 1)
{