Implement drawcall callbacks on D3D12 (untested - nothing uses them)

This commit is contained in:
baldurk
2016-08-06 18:31:39 +02:00
parent 6ca41cc681
commit 00cea7bbd5
8 changed files with 104 additions and 42 deletions
@@ -174,11 +174,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Reset(ID3D12CommandAllocator *p
}
}
D3D12NOTIMP("m_DrawcallCallback");
// const bool recordAllCmds = false; // m_DrawcallCallback &&
// m_DrawcallCallback->RecordAllCmds()
if(partial) // || recordAllCmds
if(partial || (m_Cmd->m_DrawcallCallback && m_Cmd->m_DrawcallCallback->RecordAllCmds()))
{
pAllocator = GetResourceManager()->GetLiveAs<ID3D12CommandAllocator>(Allocator);
pInitialState =
@@ -338,23 +334,15 @@ bool WrappedID3D12GraphicsCommandList::Serialise_DrawIndexedInstanced(UINT Index
{
ID3D12GraphicsCommandList *list = m_Cmd->RerecordCmdList(CommandList);
uint32_t eventID = m_Cmd->HandlePreCallback(list);
Unwrap(list)->DrawIndexedInstanced(idxCount, instCount, startIdx, startVtx, startInst);
D3D12NOTIMP("Drawcall callbacks");
/*
uint32_t eventID = HandlePreCallback(commandBuffer);
ObjDisp(commandBuffer)
->CmdDrawIndexed(Unwrap(commandBuffer), idxCount, instCount, firstIdx, vtxOffs,
firstInst);
if(eventID && m_DrawcallCallback->PostDraw(eventID, commandBuffer))
if(eventID && m_Cmd->m_DrawcallCallback->PostDraw(eventID, list))
{
ObjDisp(commandBuffer)
->CmdDrawIndexed(Unwrap(commandBuffer), idxCount, instCount, firstIdx, vtxOffs,
firstInst);
m_DrawcallCallback->PostRedraw(eventID, commandBuffer);
}*/
Unwrap(list)->DrawIndexedInstanced(idxCount, instCount, startIdx, startVtx, startInst);
m_Cmd->m_DrawcallCallback->PostRedraw(eventID, list);
}
}
}
else if(m_State == READING)
@@ -173,8 +173,6 @@ bool WrappedID3D12CommandQueue::Serialise_ExecuteCommandLists(UINT NumCommandLis
// same accounting for the outer loop as above
m_Cmd.m_RootEventID--;
D3D12NOTIMP("m_DrawcallCallback");
if(numCmds == 0)
{
// do nothing, don't bother with the logic below
@@ -185,30 +183,28 @@ bool WrappedID3D12CommandQueue::Serialise_ExecuteCommandLists(UINT NumCommandLis
RDCDEBUG("Queue Submit no replay %u == %u", m_Cmd.m_LastEventID, startEID);
#endif
}
/*
else if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds())
else if(m_Cmd.m_DrawcallCallback && m_Cmd.m_DrawcallCallback->RecordAllCmds())
{
#ifdef VERBOSE_PARTIAL_REPLAY
RDCDEBUG("Queue Submit re-recording from %u", m_RootEventID);
RDCDEBUG("Queue Submit re-recording from %u", m_Cmd.m_RootEventID);
#endif
vector<ID3D12CommandList *> rerecordedCmds;
for(uint32_t c = 0; c < numCmds; c++)
{
ID3D12CommandList *cmd = RerecordCmdBuf(cmdIds[c]);
ID3D12CommandList *cmd = m_Cmd.RerecordCmdList(cmdIds[c]);
ResourceId rerecord = GetResID(cmd);
#ifdef VERBOSE_PARTIAL_REPLAY
RDCDEBUG("Queue Submit fully re-recorded replay of %llu, using %llu", cmdIds[c], rerecord);
#endif
rerecordedCmds.push_back(Unwrap(cmd));
m_pDevice->ApplyBarriers(m_BakedCmdBufferInfo[rerecord].imgbarriers);
m_pDevice->ApplyBarriers(m_Cmd.m_BakedCmdListInfo[rerecord].barriers);
}
m_pReal->ExecuteCommandLists((UINT)rerecordedCmds.size(), &rerecordedCmds[0]);
}
*/
else if(m_Cmd.m_LastEventID > startEID && m_Cmd.m_LastEventID < m_Cmd.m_RootEventID)
{
#ifdef VERBOSE_PARTIAL_REPLAY
+39 -9
View File
@@ -169,6 +169,7 @@ WrappedID3D12CommandQueue::WrappedID3D12CommandQueue(ID3D12CommandQueue *real,
m_QueueRecord = NULL;
m_Cmd.m_pSerialiser = m_pSerialiser;
m_Cmd.m_pDevice = m_pDevice;
if(!RenderDoc::Inst().IsReplayApp())
{
@@ -585,16 +586,51 @@ D3D12CommandData::D3D12CommandData()
m_RootDrawcallStack.push_back(&m_ParentDrawcall);
}
uint32_t D3D12CommandData::HandlePreCallback(ID3D12GraphicsCommandList *list, bool dispatch,
uint32_t multiDrawOffset)
{
if(!m_DrawcallCallback)
return 0;
// look up the EID this drawcall came from
DrawcallUse use(m_CurChunkOffset, 0);
auto it = std::lower_bound(m_DrawcallUses.begin(), m_DrawcallUses.end(), use);
RDCASSERT(it != m_DrawcallUses.end());
uint32_t eventID = it->eventID;
RDCASSERT(eventID != 0);
// handle all aliases of this drawcall as long as it's not a multidraw
const FetchDrawcall *draw = m_pDevice->GetDrawcall(eventID);
if(draw == NULL || (draw->flags & eDraw_MultiDraw) == 0)
{
++it;
while(it != m_DrawcallUses.end() && it->fileOffset == m_CurChunkOffset)
{
m_DrawcallCallback->AliasEvent(eventID, it->eventID);
++it;
}
}
eventID += multiDrawOffset;
if(dispatch)
m_DrawcallCallback->PreDispatch(eventID, list);
else
m_DrawcallCallback->PreDraw(eventID, list);
return eventID;
}
bool D3D12CommandData::ShouldRerecordCmd(ResourceId cmdid)
{
if(m_Partial[Primary].outsideCmdList != NULL)
return true;
D3D12NOTIMP("m_DrawcallCallback");
/*
if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds())
return true;
*/
return cmdid == m_Partial[Primary].partialParent || cmdid == m_Partial[Secondary].partialParent;
}
@@ -604,11 +640,8 @@ bool D3D12CommandData::InRerecordRange(ResourceId cmdid)
if(m_Partial[Primary].outsideCmdList != NULL)
return true;
D3D12NOTIMP("m_DrawcallCallback");
/*
if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds())
return true;
*/
for(int p = 0; p < ePartialNum; p++)
{
@@ -628,8 +661,6 @@ ID3D12GraphicsCommandList *D3D12CommandData::RerecordCmdList(ResourceId cmdid,
if(m_Partial[Primary].outsideCmdList != NULL)
return m_Partial[Primary].outsideCmdList;
D3D12NOTIMP("m_DrawcallCallback");
/*
if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds())
{
auto it = m_RerecordCmds.find(cmdid);
@@ -638,7 +669,6 @@ ID3D12GraphicsCommandList *D3D12CommandData::RerecordCmdList(ResourceId cmdid,
return it->second;
}
*/
if(partialType != ePartialNum)
return m_Partial[partialType].resultPartialCmdList;
+48
View File
@@ -83,6 +83,44 @@ struct D3D12DrawcallTreeNode
}
};
struct D3D12DrawcallCallback
{
// the three callbacks are used to allow the callback implementor to either
// do a modified draw before or after the real thing.
//
// PreDraw()
// do draw call as specified by the log
// PostDraw()
// if PostDraw() returns true:
// do draw call again
// PostRedraw()
//
// So either the modification happens in PreDraw, the modified draw happens,
// then in PostDraw() the implementation can elect to undo the modifications
// and do the real draw by returning true. OR they can do nothing in PreDraw,
// do the real draw, then in PostDraw return true to apply the modifications
// which are then undone in PostRedraw.
virtual void PreDraw(uint32_t eid, ID3D12GraphicsCommandList *cmd) = 0;
virtual bool PostDraw(uint32_t eid, ID3D12GraphicsCommandList *cmd) = 0;
virtual void PostRedraw(uint32_t eid, ID3D12GraphicsCommandList *cmd) = 0;
// same principle as above, but for dispatch calls
virtual void PreDispatch(uint32_t eid, ID3D12GraphicsCommandList *cmd) = 0;
virtual bool PostDispatch(uint32_t eid, ID3D12GraphicsCommandList *cmd) = 0;
virtual void PostRedispatch(uint32_t eid, ID3D12GraphicsCommandList *cmd) = 0;
// should we re-record all command lists? this needs to be true if the range
// being replayed is larger than one command list (which usually means the
// whole frame).
virtual bool RecordAllCmds() = 0;
// if a command list is recorded once and submitted N > 1 times, then the same
// drawcall will have several EIDs that refer to it. We'll only do the full
// callbacks above for the first EID, then call this function for the others
// to indicate that they are the same.
virtual void AliasEvent(uint32_t primary, uint32_t alias) = 0;
};
struct BakedCmdListInfo
{
void BakeFrom(BakedCmdListInfo &parent)
@@ -127,12 +165,17 @@ struct BakedCmdListInfo
uint32_t drawCount; // similar to above
};
class WrappedID3D12Device;
struct D3D12CommandData
{
D3D12CommandData();
WrappedID3D12Device *m_pDevice;
Serialiser *m_pSerialiser;
D3D12DrawcallCallback *m_DrawcallCallback;
ResourceId m_LastCmdListID;
map<ResourceId, BakedCmdListInfo> m_BakedCmdListInfo;
@@ -247,6 +290,11 @@ struct D3D12CommandData
return m_RootDrawcallStack;
}
// util function to handle fetching the right eventID, calling any
// aliases then calling PreDraw/PreDispatch.
uint32_t HandlePreCallback(ID3D12GraphicsCommandList *list, bool dispatch = false,
uint32_t multiDrawOffset = 0);
bool ShouldRerecordCmd(ResourceId cmdid);
bool InRerecordRange(ResourceId cmdid);
ID3D12GraphicsCommandList *RerecordCmdList(ResourceId cmdid,
+3 -3
View File
@@ -122,7 +122,7 @@ struct VulkanDrawcallTreeNode
#undef SERIALISED_PARAMETER
#define SERIALISED_PARAMETER Serialiser *localSerialiser,
struct DrawcallCallback
struct VulkanDrawcallCallback
{
// the three callbacks are used to allow the callback implementor to either
// do a modified draw before or after the real thing.
@@ -239,7 +239,7 @@ private:
Threading::CriticalSection m_CapTransitionLock;
DrawcallCallback *m_DrawcallCallback;
VulkanDrawcallCallback *m_DrawcallCallback;
// util function to handle fetching the right eventID, calling any
// aliases then calling PreDraw/PreDispatch.
@@ -700,7 +700,7 @@ public:
void FlushQ();
VulkanRenderState &GetRenderState() { return m_RenderState; }
void SetDrawcallCB(DrawcallCallback *cb) { m_DrawcallCallback = cb; }
void SetDrawcallCB(VulkanDrawcallCallback *cb) { m_DrawcallCallback = cb; }
VkResult FilterDeviceExtensionProperties(VkPhysicalDevice physDev, uint32_t *pPropertyCount,
VkExtensionProperties *pProperties);
static VkResult GetProvidedExtensionProperties(uint32_t *pPropertyCount,
+1 -1
View File
@@ -74,7 +74,7 @@ void VulkanReplay::DescribeCounter(uint32_t counterID, CounterDescription &desc)
desc.units = eUnits_Absolute;
}
}
struct GPUTimerCallback : public DrawcallCallback
struct GPUTimerCallback : public VulkanDrawcallCallback
{
GPUTimerCallback(WrappedVulkan *vk, VulkanReplay *rp, VkQueryPool qp)
: m_pDriver(vk), m_pReplay(rp), m_QueryPool(qp)
+1 -1
View File
@@ -3697,7 +3697,7 @@ void VulkanDebugManager::PatchFixedColShader(VkShaderModule &mod, float col[4])
RDCASSERTEQUAL(vkr, VK_SUCCESS);
}
struct QuadOverdrawCallback : public DrawcallCallback
struct QuadOverdrawCallback : public VulkanDrawcallCallback
{
QuadOverdrawCallback(WrappedVulkan *vk, const vector<uint32_t> &events)
: m_pDriver(vk), m_pDebug(vk->GetDebugManager()), m_Events(events), m_PrevState(NULL)
+1 -1
View File
@@ -4502,7 +4502,7 @@ void VulkanReplay::InitPostVSBuffers(uint32_t eventID)
GetDebugManager()->InitPostVSBuffers(eventID);
}
struct InitPostVSCallback : public DrawcallCallback
struct InitPostVSCallback : public VulkanDrawcallCallback
{
InitPostVSCallback(WrappedVulkan *vk, const vector<uint32_t> &events)
: m_pDriver(vk), m_Events(events)