mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-07 14:25:44 +00:00
Implement drawcall callbacks on D3D12 (untested - nothing uses them)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user