Shift responsibility for 'whole pass' type processing to replay drivers

* Note, currently broken as the drivers don't have previous/next EIDs
  set up on their drawcalls
This commit is contained in:
baldurk
2015-12-20 17:00:06 +01:00
parent b2bbe4541a
commit 459196fd21
15 changed files with 267 additions and 70 deletions
+14 -11
View File
@@ -398,17 +398,18 @@ enum ResourceUsage
enum DrawcallFlags
{
// types
eDraw_Clear = 0x01,
eDraw_Drawcall = 0x02,
eDraw_Dispatch = 0x04,
eDraw_CmdList = 0x08,
eDraw_SetMarker = 0x10,
eDraw_PushMarker = 0x20,
eDraw_Present = 0x40,
eDraw_MultiDraw = 0x80,
eDraw_Copy = 0x100,
eDraw_Resolve = 0x200,
eDraw_GenMips = 0x400,
eDraw_Clear = 0x01,
eDraw_Drawcall = 0x02,
eDraw_Dispatch = 0x04,
eDraw_CmdList = 0x08,
eDraw_SetMarker = 0x10,
eDraw_PushMarker = 0x20,
eDraw_Present = 0x40,
eDraw_MultiDraw = 0x80,
eDraw_Copy = 0x100,
eDraw_Resolve = 0x200,
eDraw_GenMips = 0x400,
eDraw_PassBoundary = 0x800,
// flags
eDraw_UseIBuffer = 0x01000,
@@ -417,6 +418,8 @@ enum DrawcallFlags
eDraw_Indirect = 0x08000,
eDraw_ClearColour = 0x10000,
eDraw_ClearDepthStencil = 0x20000,
eDraw_BeginPass = 0x40000,
eDraw_EndPass = 0x80000,
};
enum SolidShadeMode
+2
View File
@@ -120,6 +120,7 @@ class ImageViewer : public IReplayDriver
VulkanPipelineState GetVulkanPipelineState() { return VulkanPipelineState(); }
void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) {}
void ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType) {}
vector<uint32_t> GetPassEvents(uint32_t frameID, uint32_t eventID) { return vector<uint32_t>(); }
vector<EventUsage> GetUsage(ResourceId id) { return vector<EventUsage>(); }
bool IsRenderOutput(ResourceId id) { return false; }
ResourceId GetLiveID(ResourceId id) { return id; }
@@ -129,6 +130,7 @@ class ImageViewer : public IReplayDriver
void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector<ShaderVariable> &outvars, const vector<byte> &data) {}
void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector<byte> &retData) {}
void InitPostVSBuffers(uint32_t frameID, uint32_t eventID) {}
void InitPostVSBuffers(uint32_t frameID, const vector<uint32_t> &eventID) {}
MeshFormat GetPostVSBuffers(uint32_t frameID, uint32_t eventID, uint32_t instID, MeshDataStage stage) { MeshFormat ret; RDCEraseEl(ret); return ret; }
ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents) { return ResourceId(); }
ShaderReflection *GetShader(ResourceId shader, string entryPoint) { return NULL; }
+47
View File
@@ -1290,6 +1290,9 @@ bool ProxySerialiser::Tick()
case eCommand_ReplayLog:
ReplayLog(0, 0, 0, (ReplayLogType)0);
break;
case eCommand_GetPassEvents:
GetPassEvents(0, 0);
break;
case eCommand_GetAPIProperties:
GetAPIProperties();
break;
@@ -1375,6 +1378,12 @@ bool ProxySerialiser::Tick()
case eCommand_InitPostVS:
InitPostVSBuffers(0, 0);
break;
case eCommand_InitPostVSVec:
{
vector<uint32_t> dummy;
InitPostVSBuffers(0, dummy);
break;
}
case eCommand_GetPostVS:
GetPostVSBuffers(0, 0, 0, eMeshDataStage_Unknown);
break;
@@ -1624,6 +1633,28 @@ void ProxySerialiser::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_
}
}
vector<uint32_t> ProxySerialiser::GetPassEvents(uint32_t frameID, uint32_t eventID)
{
vector<uint32_t> ret;
m_ToReplaySerialiser->Serialise("", frameID);
m_ToReplaySerialiser->Serialise("", eventID);
if(m_ReplayHost)
{
ret = m_Remote->GetPassEvents(frameID, eventID);
}
else
{
if(!SendReplayCommand(eCommand_GetPassEvents))
return ret;
}
m_FromReplaySerialiser->Serialise("", ret);
return ret;
}
vector<EventUsage> ProxySerialiser::GetUsage(ResourceId id)
{
vector<EventUsage> ret;
@@ -1896,6 +1927,22 @@ void ProxySerialiser::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
}
}
void ProxySerialiser::InitPostVSBuffers(uint32_t frameID, const vector<uint32_t> &events)
{
m_ToReplaySerialiser->Serialise("", frameID);
m_ToReplaySerialiser->Serialise("", (vector<uint32_t> &)events);
if(m_ReplayHost)
{
m_Remote->InitPostVSBuffers(frameID, events);
}
else
{
if(!SendReplayCommand(eCommand_InitPostVSVec))
return;
}
}
MeshFormat ProxySerialiser::GetPostVSBuffers(uint32_t frameID, uint32_t eventID, uint32_t instID, MeshDataStage stage)
{
MeshFormat ret;
+6
View File
@@ -35,6 +35,8 @@ enum CommandPacketType
eCommand_SetCtxFilter,
eCommand_ReplayLog,
eCommand_GetPassEvents,
eCommand_GetTextures,
eCommand_GetTexture,
eCommand_GetBuffers,
@@ -59,6 +61,7 @@ enum CommandPacketType
eCommand_FillCBufferVariables,
eCommand_InitPostVS,
eCommand_InitPostVSVec,
eCommand_GetPostVS,
eCommand_InitStackResolver,
@@ -334,6 +337,8 @@ class ProxySerialiser : public IReplayDriver, Callstack::StackResolver
void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv);
void ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType);
vector<uint32_t> GetPassEvents(uint32_t frameID, uint32_t eventID);
vector<EventUsage> GetUsage(ResourceId id);
vector<FetchFrameRecord> GetFrameRecord();
@@ -351,6 +356,7 @@ class ProxySerialiser : public IReplayDriver, Callstack::StackResolver
byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize);
void InitPostVSBuffers(uint32_t frameID, uint32_t eventID);
void InitPostVSBuffers(uint32_t frameID, const vector<uint32_t> &passEvents);
MeshFormat GetPostVSBuffers(uint32_t frameID, uint32_t eventID, uint32_t instID, MeshDataStage stage);
ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents);
+52
View File
@@ -1243,6 +1243,36 @@ void D3D11Replay::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t en
m_pDevice->ReplayLog(frameID, startEventID, endEventID, replayType);
}
vector<uint32_t> D3D11Replay::GetPassEvents(uint32_t frameID, uint32_t eventID)
{
vector<uint32_t> passEvents;
const FetchDrawcall *draw = m_pDevice->GetDrawcall(frameID, eventID);
const FetchDrawcall *start = draw;
while(start && start->previous != 0 && (m_pDevice->GetDrawcall(frameID, (uint32_t)start->previous)->flags & eDraw_Clear) == 0)
{
const FetchDrawcall *prev = m_pDevice->GetDrawcall(frameID, (uint32_t)start->previous);
if(memcmp(start->outputs, prev->outputs, sizeof(start->outputs)) || start->depthOut != prev->depthOut)
break;
start = prev;
}
while(start)
{
if(start == draw)
break;
if(start->flags & eDraw_Drawcall)
passEvents.push_back(start->eventID);
start = m_pDevice->GetDrawcall((uint32_t)start->next, 0);
}
return passEvents;
}
uint64_t D3D11Replay::MakeOutputWindow(void *w, bool depth)
{
@@ -1294,6 +1324,28 @@ void D3D11Replay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
m_pDevice->GetDebugManager()->InitPostVSBuffers(frameID, eventID);
}
void D3D11Replay::InitPostVSBuffers(uint32_t frameID, const vector<uint32_t> &passEvents)
{
uint32_t prev = 0;
// since we can always replay between drawcalls, just loop through all the events
// doing partial replays and calling InitPostVSBuffers for each
for(size_t i=0; i < passEvents.size(); i++)
{
if(prev != passEvents[i])
{
m_pDevice->ReplayLog(frameID, prev, passEvents[i], eReplay_WithoutDraw);
prev = passEvents[i];
}
const FetchDrawcall *d = m_pDevice->GetDrawcall(frameID, passEvents[i]);
if(d)
m_pDevice->GetDebugManager()->InitPostVSBuffers(frameID, passEvents[i]);
}
}
ResourceId D3D11Replay::GetLiveID(ResourceId id)
{
return m_pDevice->GetResourceManager()->GetLiveID(id);
+3
View File
@@ -71,6 +71,8 @@ class D3D11Replay : public IReplayDriver
void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv);
void ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType);
vector<uint32_t> GetPassEvents(uint32_t frameID, uint32_t eventID);
uint64_t MakeOutputWindow(void *w, bool depth);
void DestroyOutputWindow(uint64_t id);
bool CheckResizeOutputWindow(uint64_t id);
@@ -82,6 +84,7 @@ class D3D11Replay : public IReplayDriver
void FlipOutputWindow(uint64_t id);
void InitPostVSBuffers(uint32_t frameID, uint32_t eventID);
void InitPostVSBuffers(uint32_t frameID, const vector<uint32_t> &passEvents);
ResourceId GetLiveID(ResourceId id);
+22
View File
@@ -3291,6 +3291,28 @@ void GLReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
gl.glEnable(eGL_RASTERIZER_DISCARD);
}
void GLReplay::InitPostVSBuffers(uint32_t frameID, const vector<uint32_t> &passEvents)
{
uint32_t prev = 0;
// since we can always replay between drawcalls, just loop through all the events
// doing partial replays and calling InitPostVSBuffers for each
for(size_t i=0; i < passEvents.size(); i++)
{
if(prev != passEvents[i])
{
m_pDriver->ReplayLog(frameID, prev, passEvents[i], eReplay_WithoutDraw);
prev = passEvents[i];
}
const FetchDrawcall *d = m_pDriver->GetDrawcall(frameID, passEvents[i]);
if(d)
InitPostVSBuffers(frameID, passEvents[i]);
}
}
MeshFormat GLReplay::GetPostVSBuffers(uint32_t frameID, uint32_t eventID, uint32_t instID, MeshDataStage stage)
{
GLPostVSData postvs;
+31
View File
@@ -71,6 +71,37 @@ void GLReplay::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t endEv
m_pDriver->ReplayLog(frameID, startEventID, endEventID, replayType);
}
vector<uint32_t> GLReplay::GetPassEvents(uint32_t frameID, uint32_t eventID)
{
vector<uint32_t> passEvents;
const FetchDrawcall *draw = m_pDriver->GetDrawcall(frameID, eventID);
const FetchDrawcall *start = draw;
while(start && start->previous != 0 && (m_pDriver->GetDrawcall(frameID, (uint32_t)start->previous)->flags & eDraw_Clear) == 0)
{
const FetchDrawcall *prev = m_pDriver->GetDrawcall(frameID, (uint32_t)start->previous);
if(memcmp(start->outputs, prev->outputs, sizeof(start->outputs)) || start->depthOut != prev->depthOut)
break;
start = prev;
}
while(start)
{
if(start == draw)
break;
if(start->flags & eDraw_Drawcall)
passEvents.push_back(start->eventID);
start = m_pDriver->GetDrawcall((uint32_t)start->next, 0);
}
return passEvents;
}
vector<FetchFrameRecord> GLReplay::GetFrameRecord()
{
return m_pDriver->GetFrameRecord();
+3
View File
@@ -117,6 +117,8 @@ class GLReplay : public IReplayDriver
void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv);
void ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType);
vector<uint32_t> GetPassEvents(uint32_t frameID, uint32_t eventID);
uint64_t MakeOutputWindow(void *w, bool depth);
void DestroyOutputWindow(uint64_t id);
bool CheckResizeOutputWindow(uint64_t id);
@@ -128,6 +130,7 @@ class GLReplay : public IReplayDriver
void FlipOutputWindow(uint64_t id);
void InitPostVSBuffers(uint32_t frameID, uint32_t eventID);
void InitPostVSBuffers(uint32_t frameID, const vector<uint32_t> &passEvents);
ResourceId GetLiveID(ResourceId id);
+62
View File
@@ -535,6 +535,63 @@ void VulkanReplay::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t e
m_pDriver->ReplayLog(frameID, startEventID, endEventID, replayType);
}
vector<uint32_t> VulkanReplay::GetPassEvents(uint32_t frameID, uint32_t eventID)
{
vector<uint32_t> passEvents;
const FetchDrawcall *draw = m_pDriver->GetDrawcall(frameID, eventID);
if(!draw)
return passEvents;
// for vulkan a pass == a renderpass, if we're not inside a
// renderpass then there are no pass events.
const FetchDrawcall *start = draw;
while(start)
{
// if we've come to the beginning of a pass, break out of the loop, we've
// found the start.
// Note that vkCmdNextSubPass has both Begin and End flags set, so it will
// break out here before we hit the terminating case looking for eDraw_EndPass
if(start->flags & eDraw_BeginPass)
break;
// if we come to the END of a pass, since we were iterating backwards that
// means we started outside of a pass, so return empty set.
// Note that vkCmdNextSubPass has both Begin and End flags set, so it will
// break out above before we hit this terminating case
if(start->flags & eDraw_EndPass)
return passEvents;
// if we've come to the start of the log we were outside of a render pass
// to start with
if(start->previous == 0)
return passEvents;
// step back
start = m_pDriver->GetDrawcall(frameID, (uint32_t)start->previous);
// something went wrong, start->previous was non-zero but we didn't
// get a draw. Abort
if(!start)
return passEvents;
}
// store all the draw eventIDs up to the one specified at the start
while(start)
{
if(start == draw)
break;
if(start->flags & eDraw_Drawcall)
passEvents.push_back(start->eventID);
start = m_pDriver->GetDrawcall((uint32_t)start->next, 0);
}
return passEvents;
}
ResourceId VulkanReplay::GetLiveID(ResourceId id)
{
return m_pDriver->GetResourceManager()->GetLiveID(id);
@@ -3715,6 +3772,11 @@ void VulkanReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
GetDebugManager()->InitPostVSBuffers(frameID, eventID);
}
void VulkanReplay::InitPostVSBuffers(uint32_t frameID, const vector<uint32_t> &events)
{
// Stub, will implement this in a minute
}
vector<EventUsage> VulkanReplay::GetUsage(ResourceId id)
{
VULKANNOTIMP("GetUsage");
+3
View File
@@ -103,6 +103,8 @@ class VulkanReplay : public IReplayDriver
void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv);
void ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType);
vector<uint32_t> GetPassEvents(uint32_t frameID, uint32_t eventID);
uint64_t MakeOutputWindow(void *w, bool depth);
void DestroyOutputWindow(uint64_t id);
bool CheckResizeOutputWindow(uint64_t id);
@@ -114,6 +116,7 @@ class VulkanReplay : public IReplayDriver
void FlipOutputWindow(uint64_t id);
void InitPostVSBuffers(uint32_t frameID, uint32_t eventID);
void InitPostVSBuffers(uint32_t frameID, const vector<uint32_t> &passEvents);
ResourceId GetLiveID(ResourceId id);
@@ -624,7 +624,7 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(
AddEvent(BEGIN_RENDERPASS, desc);
FetchDrawcall draw;
draw.name = StringFormat::Fmt("vkCmdBeginRenderPass(%s)", opDesc.c_str());
draw.flags |= eDraw_Clear;
draw.flags |= eDraw_PassBoundary|eDraw_BeginPass;
AddDrawcall(draw, true);
}
@@ -707,7 +707,7 @@ bool WrappedVulkan::Serialise_vkCmdNextSubpass(
AddEvent(NEXT_SUBPASS, desc);
FetchDrawcall draw;
draw.name = StringFormat::Fmt("vkCmdNextSubpass() => %u", m_RenderState.subpass);
draw.flags |= eDraw_Clear;
draw.flags |= eDraw_PassBoundary|eDraw_BeginPass|eDraw_EndPass;
AddDrawcall(draw, true);
}
@@ -856,7 +856,7 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass(
AddEvent(END_RENDERPASS, desc);
FetchDrawcall draw;
draw.name = StringFormat::Fmt("vkCmdEndRenderPass(%s)", opDesc.c_str());
draw.flags |= eDraw_Clear;
draw.flags |= eDraw_PassBoundary|eDraw_EndPass;
AddDrawcall(draw, true);
}
+3
View File
@@ -78,7 +78,10 @@ class IRemoteDriver
virtual void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) = 0;
virtual void ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType) = 0;
virtual vector<uint32_t> GetPassEvents(uint32_t frameID, uint32_t eventID) = 0;
virtual void InitPostVSBuffers(uint32_t frameID, uint32_t eventID) = 0;
virtual void InitPostVSBuffers(uint32_t frameID, const vector<uint32_t> &passEvents) = 0;
virtual ResourceId GetLiveID(ResourceId id) = 0;
+3 -45
View File
@@ -137,33 +137,8 @@ void ReplayOutput::RefreshOverlay()
{
FetchDrawcall *draw = m_pRenderer->GetDrawcallByEID(m_EventID, m_LastDeferredEvent);
{
passEvents.clear();
FetchDrawcall *start = draw;
while(start && start->previous != 0 && (m_pRenderer->GetDrawcallByEID((uint32_t)start->previous, 0)->flags & eDraw_Clear) == 0)
{
FetchDrawcall *prev = m_pRenderer->GetDrawcallByEID((uint32_t)start->previous, 0);
if(memcmp(start->outputs, prev->outputs, sizeof(start->outputs)) || start->depthOut != prev->depthOut)
break;
start = prev;
}
while(start)
{
if(start == draw)
break;
if(start->flags & eDraw_Drawcall)
{
passEvents.push_back(start->eventID);
}
start = m_pRenderer->GetDrawcallByEID((uint32_t)start->next, 0);
}
}
passEvents = m_pDevice->GetPassEvents(m_FrameID, m_LastDeferredEvent > 0 ? m_LastDeferredEvent : m_EventID);
if(m_Config.m_Type == eOutputType_TexDisplay && m_RenderData.texDisplay.overlay != eTexOverlay_None)
{
@@ -186,24 +161,7 @@ void ReplayOutput::RefreshOverlay()
if(!m_RenderData.meshDisplay.thisDrawOnly && !passEvents.empty())
{
uint32_t prev = 0;
for(size_t i=0; i < passEvents.size(); i++)
{
if(prev != passEvents[i])
{
m_pDevice->ReplayLog(m_FrameID, prev, passEvents[i], eReplay_WithoutDraw);
prev = passEvents[i];
}
FetchDrawcall *d = m_pRenderer->GetDrawcallByEID(m_EventID, m_LastDeferredEvent);
if(d)
{
m_pDevice->InitPostVSBuffers(m_FrameID, passEvents[i]);
}
}
m_pDevice->InitPostVSBuffers(m_FrameID, passEvents);
m_pDevice->ReplayLog(m_FrameID, 0, m_EventID, eReplay_WithoutDraw);
}
+13 -11
View File
@@ -395,17 +395,17 @@ namespace renderdoc
public enum DrawcallFlags
{
// types
Clear = 0x01,
Drawcall = 0x02,
Dispatch = 0x04,
CmdList = 0x08,
SetMarker = 0x10,
PushMarker = 0x20,
Present = 0x40,
MultiDraw = 0x80,
Copy = 0x100,
Resolve = 0x200,
GenMips = 0x400,
Clear = 0x01,
Drawcall = 0x02,
Dispatch = 0x04,
CmdList = 0x08,
SetMarker = 0x10,
PushMarker = 0x20,
Present = 0x40,
MultiDraw = 0x80,
Copy = 0x100,
Resolve = 0x200,
PassBoundary = 0x400,
// flags
UseIBuffer = 0x01000,
@@ -414,6 +414,8 @@ namespace renderdoc
Indirect = 0x08000,
ClearColour = 0x10000,
ClearDepth = 0x20000,
BeginPass = 0x40000,
EndPass = 0x80000,
};
public enum SolidShadeMode