Change previous/next/parent IDs in DrawcallDescription to pointers

* This is a legacy holdover from the C# interop not being able to preserve
  pointers easily.
This commit is contained in:
baldurk
2018-06-18 18:39:06 +01:00
parent f919ea81e2
commit 0dda96a045
25 changed files with 307 additions and 309 deletions
+9 -13
View File
@@ -963,9 +963,7 @@ struct DrawcallDescription
copySource = ResourceId();
copyDestination = ResourceId();
parent = 0;
previous = 0;
next = 0;
parent = previous = next = NULL;
for(int i = 0; i < 8; i++)
outputs[i] = ResourceId();
@@ -1044,19 +1042,17 @@ operation.
)");
ResourceId copyDestination;
DOCUMENT(R"(The :data:`eventId <APIEvent.eventId>` of the parent of this drawcall, or ``0`` if there
is no parent for this drawcall.
DOCUMENT(R"(The parent of this drawcall, or ``None`` if there is no parent for this drawcall.
)");
int64_t parent;
const DrawcallDescription *parent;
DOCUMENT(R"(The :data:`eventId <APIEvent.eventId>` of the previous drawcall in the frame, or ``0`` if
this is the first drawcall in the frame.
DOCUMENT(R"(The previous drawcall in the frame, or ``None`` if this is the first drawcall in the
frame.
)");
int64_t previous;
DOCUMENT(R"(The :data:`eventId <APIEvent.eventId>` of the next drawcall in the frame, or ``0`` if this
is the last drawcall in the frame.
)");
int64_t next;
const DrawcallDescription *previous;
DOCUMENT(
"The next drawcall in the frame, or ``None`` if this is the last drawcall in the frame.");
const DrawcallDescription *next;
DOCUMENT(R"(A simple list of the :class:`ResourceId` ids for the color outputs, which can be used
for very coarse bucketing of drawcalls into similar passes by their outputs.
+8 -1
View File
@@ -939,7 +939,14 @@ See :meth:`BuildTargetShader`.
:return: The list of root-level drawcalls in the capture.
:rtype: ``list`` of :class:`DrawcallDescription`
)");
virtual rdcarray<DrawcallDescription> GetDrawcalls() = 0;
virtual void AddFakeMarkers() = 0;
DOCUMENT(R"(Retrieve the list of root-level drawcalls in the capture.
:return: The list of root-level drawcalls in the capture.
:rtype: ``list`` of :class:`DrawcallDescription`
)");
virtual const rdcarray<DrawcallDescription> &GetDrawcalls() = 0;
DOCUMENT(R"(Retrieve the values of a specified set of counters.
+7
View File
@@ -381,6 +381,13 @@ FrameRecord ReplayProxy::Proxied_GetFrameRecord(ParamSerialiser &paramser, Retur
SERIALISE_RETURN(ret);
if(paramser.IsWriting())
{
// re-configure the drawcall pointers, since they will be invalid
DrawcallDescription *previous = NULL;
SetupDrawcallPointers(m_Drawcalls, ret.drawcallList, NULL, previous);
}
return ret;
}
+2
View File
@@ -649,6 +649,8 @@ private:
FrameRecord m_FrameRecord;
APIProperties m_APIProps;
std::vector<DrawcallDescription *> m_Drawcalls;
SDFile m_StructuredFile;
std::vector<ResourceDescription> m_Resources;
+1 -1
View File
@@ -1083,7 +1083,7 @@ ReplayStatus WrappedID3D11Device::ReadLogInitialisation(RDCFile *rdc, bool store
if(!IsStructuredExporting(m_State))
{
DrawcallDescription *previous = NULL;
SetupDrawcallPointers(&m_Drawcalls, GetFrameRecord().drawcallList, NULL, previous);
SetupDrawcallPointers(m_Drawcalls, GetFrameRecord().drawcallList, NULL, previous);
}
#if ENABLED(RDOC_DEVEL)
+3 -4
View File
@@ -1456,10 +1456,9 @@ vector<uint32_t> D3D11Replay::GetPassEvents(uint32_t eventId)
const DrawcallDescription *draw = m_pDevice->GetDrawcall(eventId);
const DrawcallDescription *start = draw;
while(start && start->previous != 0 &&
!(m_pDevice->GetDrawcall((uint32_t)start->previous)->flags & DrawFlags::Clear))
while(start && start->previous && !(start->previous->flags & DrawFlags::Clear))
{
const DrawcallDescription *prev = m_pDevice->GetDrawcall((uint32_t)start->previous);
const DrawcallDescription *prev = start->previous;
if(memcmp(start->outputs, prev->outputs, sizeof(start->outputs)) ||
start->depthOut != prev->depthOut)
@@ -1476,7 +1475,7 @@ vector<uint32_t> D3D11Replay::GetPassEvents(uint32_t eventId)
if(start->flags & DrawFlags::Drawcall)
passEvents.push_back(start->eventId);
start = m_pDevice->GetDrawcall((uint32_t)start->next);
start = start->next;
}
return passEvents;
+1 -1
View File
@@ -2721,7 +2721,7 @@ ReplayStatus WrappedID3D12Device::ReadLogInitialisation(RDCFile *rdc, bool store
m_Queue->GetParentDrawcall().children.clear();
DrawcallDescription *previous = NULL;
SetupDrawcallPointers(&m_Drawcalls, GetFrameRecord().drawcallList, NULL, previous);
SetupDrawcallPointers(m_Drawcalls, GetFrameRecord().drawcallList, NULL, previous);
D3D12CommandData &cmd = *m_Queue->GetCommandData();
+2 -2
View File
@@ -2528,7 +2528,7 @@ vector<uint32_t> D3D12Replay::GetPassEvents(uint32_t eventId)
return passEvents;
// step back
const DrawcallDescription *prev = m_pDevice->GetDrawcall((uint32_t)start->previous);
const DrawcallDescription *prev = start->previous;
// something went wrong, start->previous was non-zero but we didn't
// get a draw. Abort
@@ -2556,7 +2556,7 @@ vector<uint32_t> D3D12Replay::GetPassEvents(uint32_t eventId)
if(start->flags & (DrawFlags::Drawcall | DrawFlags::PassBoundary))
passEvents.push_back(start->eventId);
start = m_pDevice->GetDrawcall((uint32_t)start->next);
start = start->next;
}
return passEvents;
+1 -1
View File
@@ -4374,7 +4374,7 @@ ReplayStatus WrappedOpenGL::ContextReplayLog(CaptureState readType, uint32_t sta
GetFrameRecord().frameInfo.debugMessages = GetDebugMessages();
DrawcallDescription *previous = NULL;
SetupDrawcallPointers(&m_Drawcalls, GetFrameRecord().drawcallList, NULL, previous);
SetupDrawcallPointers(m_Drawcalls, GetFrameRecord().drawcallList, NULL, previous);
// it's easier to remove duplicate usages here than check it as we go.
// this means if textures are bound in multiple places in the same draw
+3 -4
View File
@@ -98,10 +98,9 @@ vector<uint32_t> GLReplay::GetPassEvents(uint32_t eventId)
const DrawcallDescription *draw = m_pDriver->GetDrawcall(eventId);
const DrawcallDescription *start = draw;
while(start && start->previous != 0 &&
!(m_pDriver->GetDrawcall((uint32_t)start->previous)->flags & DrawFlags::Clear))
while(start && start->previous && !(start->previous->flags & DrawFlags::Clear))
{
const DrawcallDescription *prev = m_pDriver->GetDrawcall((uint32_t)start->previous);
const DrawcallDescription *prev = start->previous;
if(memcmp(start->outputs, prev->outputs, sizeof(start->outputs)) ||
start->depthOut != prev->depthOut)
@@ -118,7 +117,7 @@ vector<uint32_t> GLReplay::GetPassEvents(uint32_t eventId)
if(start->flags & DrawFlags::Drawcall)
passEvents.push_back(start->eventId);
start = m_pDriver->GetDrawcall((uint32_t)start->next);
start = start->next;
}
return passEvents;
+1 -1
View File
@@ -1985,7 +1985,7 @@ ReplayStatus WrappedVulkan::ContextReplayLog(CaptureState readType, uint32_t sta
GetFrameRecord().drawcallList = m_ParentDrawcall.Bake();
DrawcallDescription *previous = NULL;
SetupDrawcallPointers(&m_Drawcalls, GetFrameRecord().drawcallList, NULL, previous);
SetupDrawcallPointers(m_Drawcalls, GetFrameRecord().drawcallList, NULL, previous);
struct SortEID
{
+3 -3
View File
@@ -130,11 +130,11 @@ vector<uint32_t> VulkanReplay::GetPassEvents(uint32_t eventId)
// if we've come to the start of the log we were outside of a render pass
// to start with
if(start->previous == 0)
if(start->previous == NULL)
return passEvents;
// step back
start = m_pDriver->GetDrawcall((uint32_t)start->previous);
start = start->previous;
// something went wrong, start->previous was non-zero but we didn't
// get a draw. Abort
@@ -155,7 +155,7 @@ vector<uint32_t> VulkanReplay::GetPassEvents(uint32_t eventId)
if(start->flags & (DrawFlags::Drawcall | DrawFlags::PassBoundary))
passEvents.push_back(start->eventId);
start = m_pDriver->GetDrawcall((uint32_t)start->next);
start = start->next;
}
return passEvents;
+2 -3
View File
@@ -491,9 +491,8 @@ void DoSerialise(SerialiserType &ser, DrawcallDescription &el)
SERIALISE_MEMBER(copySource);
SERIALISE_MEMBER(copyDestination);
SERIALISE_MEMBER(parent);
SERIALISE_MEMBER(previous);
SERIALISE_MEMBER(next);
if(ser.IsReading())
el.parent = el.previous = el.next = NULL;
SERIALISE_MEMBER(outputs);
SERIALISE_MEMBER(depthOut);
+210 -2
View File
@@ -290,11 +290,218 @@ DrawcallDescription *ReplayController::GetDrawcallByEID(uint32_t eventId)
return m_Drawcalls[eventId];
}
rdcarray<DrawcallDescription> ReplayController::GetDrawcalls()
const rdcarray<DrawcallDescription> &ReplayController::GetDrawcalls()
{
return m_FrameRecord.drawcallList;
}
bool ReplayController::ContainsMarker(const rdcarray<DrawcallDescription> &draws)
{
bool ret = false;
for(const DrawcallDescription &d : draws)
{
ret |= (d.flags & DrawFlags::PushMarker) &&
!(d.flags & (DrawFlags::CmdList | DrawFlags::MultiDraw)) && !d.children.empty();
ret |= ContainsMarker(d.children);
if(ret)
break;
}
return ret;
}
bool ReplayController::PassEquivalent(const DrawcallDescription &a, const DrawcallDescription &b)
{
// executing command lists can have children
if(!a.children.empty() || !b.children.empty())
return false;
// don't group draws and compute executes
if((a.flags & DrawFlags::Dispatch) != (b.flags & DrawFlags::Dispatch))
return false;
// don't group present with anything
if((a.flags & DrawFlags::Present) != (b.flags & DrawFlags::Present))
return false;
// don't group things with different depth outputs
if(a.depthOut != b.depthOut)
return false;
int numAOuts = 0, numBOuts = 0;
for(int i = 0; i < 8; i++)
{
if(a.outputs[i] != ResourceId())
numAOuts++;
if(b.outputs[i] != ResourceId())
numBOuts++;
}
int numSame = 0;
if(a.depthOut != ResourceId())
{
numAOuts++;
numBOuts++;
numSame++;
}
for(int i = 0; i < 8; i++)
{
if(a.outputs[i] != ResourceId())
{
for(int j = 0; j < 8; j++)
{
if(a.outputs[i] == b.outputs[j])
{
numSame++;
break;
}
}
}
else if(b.outputs[i] != ResourceId())
{
for(int j = 0; j < 8; j++)
{
if(a.outputs[j] == b.outputs[i])
{
numSame++;
break;
}
}
}
}
// use a kind of heuristic to group together passes where the outputs are similar enough.
// could be useful for example if you're rendering to a gbuffer and sometimes you render
// without one target, but the draws are still batched up.
if(numSame > RDCMAX(numAOuts, numBOuts) / 2 && RDCMAX(numAOuts, numBOuts) > 1)
return true;
if(numSame == RDCMAX(numAOuts, numBOuts))
return true;
return false;
}
void ReplayController::AddFakeMarkers()
{
rdcarray<DrawcallDescription> &draws = m_FrameRecord.drawcallList;
if(ContainsMarker(draws))
return;
std::vector<DrawcallDescription> ret;
int depthpassID = 1;
int copypassID = 1;
int computepassID = 1;
int passID = 1;
int start = 0;
int refdraw = 0;
DrawFlags drawFlags = DrawFlags::Copy | DrawFlags::Resolve | DrawFlags::SetMarker |
DrawFlags::APICalls | DrawFlags::CmdList;
for(int32_t i = 1; i < draws.count(); i++)
{
if(draws[refdraw].flags & drawFlags)
{
refdraw = i;
continue;
}
if(draws[i].flags & drawFlags)
continue;
if(PassEquivalent(draws[i], draws[refdraw]))
continue;
int end = i - 1;
if(end - start < 2 || !draws[i].children.empty() || !draws[refdraw].children.empty())
{
for(int j = start; j <= end; j++)
ret.push_back(draws[j]);
start = i;
refdraw = i;
continue;
}
int minOutCount = 100;
int maxOutCount = 0;
bool copyOnly = true;
for(int j = start; j <= end; j++)
{
int outCount = 0;
if(!(draws[j].flags & (DrawFlags::Copy | DrawFlags::Resolve | DrawFlags::Clear)))
copyOnly = false;
for(ResourceId o : draws[j].outputs)
if(o != ResourceId())
outCount++;
minOutCount = RDCMIN(minOutCount, outCount);
maxOutCount = RDCMAX(maxOutCount, outCount);
}
DrawcallDescription mark;
mark.eventId = draws[start].eventId;
mark.drawcallId = draws[start].drawcallId;
mark.flags = DrawFlags::PushMarker;
memcpy(mark.outputs, draws[end].outputs, sizeof(mark.outputs));
mark.depthOut = draws[end].depthOut;
mark.name = "Guessed Pass";
minOutCount = RDCMAX(1, minOutCount);
const char *targets = draws[end].depthOut == ResourceId() ? "Targets" : "Targets + Depth";
if(copyOnly)
mark.name = StringFormat::Fmt("Copy/Clear Pass #%d", copypassID++);
else if(draws[refdraw].flags & DrawFlags::Dispatch)
mark.name = StringFormat::Fmt("Compute Pass #%d", computepassID++);
else if(maxOutCount == 0)
mark.name = StringFormat::Fmt("Depth-only Pass #%d", depthpassID++);
else if(minOutCount == maxOutCount)
mark.name = StringFormat::Fmt("Colour Pass #%d (%d %s)", passID++, minOutCount, targets);
else
mark.name = StringFormat::Fmt("Colour Pass #%d (%d-%d %s)", passID++, minOutCount,
maxOutCount, targets);
mark.children.resize(end - start + 1);
for(int j = start; j <= end; j++)
mark.children[j - start] = draws[j];
ret.push_back(mark);
start = i;
refdraw = i;
}
if(start < draws.count())
{
for(int j = start; j < draws.count(); j++)
ret.push_back(draws[j]);
}
m_FrameRecord.drawcallList = ret;
// re-configure the previous/next pointeres
DrawcallDescription *previous = NULL;
m_Drawcalls.clear();
SetupDrawcallPointers(m_Drawcalls, m_FrameRecord.drawcallList, NULL, previous);
}
rdcarray<CounterResult> ReplayController::FetchCounters(const rdcarray<GPUCounter> &counters)
{
std::vector<GPUCounter> counterArray(counters.begin(), counters.end());
@@ -1718,7 +1925,8 @@ ReplayStatus ReplayController::PostCreateInit(IReplayDriver *device, RDCFile *rd
return ReplayStatus::APIReplayFailed;
DrawcallDescription *previous = NULL;
SetupDrawcallPointers(&m_Drawcalls, m_FrameRecord.drawcallList, NULL, previous);
m_Drawcalls.clear();
SetupDrawcallPointers(m_Drawcalls, m_FrameRecord.drawcallList, NULL, previous);
return ReplayStatus::Succeeded;
}
+4 -1
View File
@@ -159,7 +159,8 @@ public:
FrameDescription GetFrameInfo();
const SDFile &GetStructuredFile();
rdcarray<DrawcallDescription> GetDrawcalls();
const rdcarray<DrawcallDescription> &GetDrawcalls();
void AddFakeMarkers();
rdcarray<CounterResult> FetchCounters(const rdcarray<GPUCounter> &counters);
rdcarray<GPUCounter> EnumerateCounters();
CounterDescription DescribeCounter(GPUCounter counterID);
@@ -208,6 +209,8 @@ private:
ReplayStatus PostCreateInit(IReplayDriver *device, RDCFile *rdc);
DrawcallDescription *GetDrawcallByEID(uint32_t eventId);
bool ContainsMarker(const rdcarray<DrawcallDescription> &draws);
bool PassEquivalent(const DrawcallDescription &a, const DrawcallDescription &b);
IReplayDriver *GetDevice() { return m_pDevice; }
FrameRecord m_FrameRecord;
+17 -17
View File
@@ -53,7 +53,7 @@ void DoSerialise(SerialiserType &ser, GetTextureDataParams &el)
INSTANTIATE_SERIALISE_TYPE(GetTextureDataParams);
DrawcallDescription *SetupDrawcallPointers(vector<DrawcallDescription *> *drawcallTable,
DrawcallDescription *SetupDrawcallPointers(vector<DrawcallDescription *> &drawcallTable,
rdcarray<DrawcallDescription> &draws,
DrawcallDescription *parent,
DrawcallDescription *&previous)
@@ -64,15 +64,14 @@ DrawcallDescription *SetupDrawcallPointers(vector<DrawcallDescription *> *drawca
{
DrawcallDescription *draw = &draws[i];
draw->parent = parent ? parent->eventId : 0;
draw->parent = parent;
if(!draw->children.empty())
{
if(drawcallTable)
{
RDCASSERT(drawcallTable->empty() || draw->eventId > drawcallTable->back()->eventId);
drawcallTable->resize(RDCMAX(drawcallTable->size(), size_t(draw->eventId + 1)));
(*drawcallTable)[draw->eventId] = draw;
RDCASSERT(drawcallTable.empty() || draw->eventId > drawcallTable.back()->eventId);
drawcallTable.resize(RDCMAX(drawcallTable.size(), size_t(draw->eventId + 1)));
drawcallTable[draw->eventId] = draw;
}
ret = SetupDrawcallPointers(drawcallTable, draw->children, draw, previous);
@@ -82,24 +81,25 @@ DrawcallDescription *SetupDrawcallPointers(vector<DrawcallDescription *> *drawca
// don't want to set up previous/next links for markers, but still add them to the table
// Some markers like Present or API Calls should have previous/next and are not markers
if(drawcallTable)
{
RDCASSERT(drawcallTable->empty() || draw->eventId > drawcallTable->back()->eventId);
drawcallTable->resize(RDCMAX(drawcallTable->size(), size_t(draw->eventId + 1)));
(*drawcallTable)[draw->eventId] = draw;
RDCASSERT(drawcallTable.empty() || draw->eventId > drawcallTable.back()->eventId);
drawcallTable.resize(RDCMAX(drawcallTable.size(), size_t(draw->eventId + 1)));
drawcallTable[draw->eventId] = draw;
}
}
else
{
if(previous != NULL)
previous->next = draw->eventId;
draw->previous = previous ? previous->eventId : 0;
if(previous)
previous->next = draw;
draw->previous = previous;
if(drawcallTable)
{
RDCASSERT(drawcallTable->empty() || draw->eventId > drawcallTable->back()->eventId);
drawcallTable->resize(RDCMAX(drawcallTable->size(), size_t(draw->eventId + 1)));
(*drawcallTable)[draw->eventId] = draw;
// we also allow equal EIDs for fake markers that don't have their own EIDs
RDCASSERT(drawcallTable.empty() || draw->eventId > drawcallTable.back()->eventId ||
(draw->eventId == drawcallTable.back()->eventId &&
(drawcallTable.back()->flags & DrawFlags::PushMarker)));
drawcallTable.resize(RDCMAX(drawcallTable.size(), size_t(draw->eventId + 1)));
drawcallTable[draw->eventId] = draw;
}
ret = previous = draw;
+1 -1
View File
@@ -223,7 +223,7 @@ public:
};
// utility functions useful in any driver implementation
DrawcallDescription *SetupDrawcallPointers(std::vector<DrawcallDescription *> *drawcallTable,
DrawcallDescription *SetupDrawcallPointers(std::vector<DrawcallDescription *> &drawcallTable,
rdcarray<DrawcallDescription> &draws,
DrawcallDescription *parent,
DrawcallDescription *&previous);