mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-26 00:16:45 +00:00
Add de-interleaving and flattening of deferred context captures
This commit is contained in:
@@ -345,6 +345,7 @@ enum D3D11ChunkType
|
||||
CREATE_UAV1,
|
||||
|
||||
SWAP_PRESENT,
|
||||
RESTORE_STATE_AFTER_EXEC,
|
||||
|
||||
NUM_D3D11_CHUNKS,
|
||||
};
|
||||
|
||||
@@ -134,6 +134,8 @@ WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *real
|
||||
m_State = WRITING_IDLE;
|
||||
}
|
||||
|
||||
m_OwnSerialiser = false;
|
||||
|
||||
// create a temporary and grab its resource ID
|
||||
m_ResourceID = ResourceIDGen::GetNewUniqueID();
|
||||
|
||||
@@ -165,6 +167,7 @@ WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *real
|
||||
m_UserAnnotation.SetContext(this);
|
||||
|
||||
m_CurrentPipelineState = new D3D11RenderState((Serialiser *)NULL);
|
||||
m_DeferredSavedState = NULL;
|
||||
m_DoStateVerify = m_State >= WRITING;
|
||||
|
||||
if(context->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE)
|
||||
@@ -196,7 +199,7 @@ WrappedID3D11DeviceContext::~WrappedID3D11DeviceContext()
|
||||
SAFE_RELEASE(it->second.query);
|
||||
}
|
||||
|
||||
if(m_State >= WRITING)
|
||||
if(m_State >= WRITING || m_OwnSerialiser)
|
||||
{
|
||||
SAFE_DELETE(m_pSerialiser);
|
||||
}
|
||||
@@ -607,30 +610,11 @@ void WrappedID3D11DeviceContext::ProcessChunk(uint64_t offset, D3D11ChunkType ch
|
||||
{
|
||||
m_CurChunkOffset = offset;
|
||||
|
||||
RDCASSERT(GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE);
|
||||
|
||||
uint64_t cOffs = m_pSerialiser->GetOffset();
|
||||
|
||||
ResourceId ctxId;
|
||||
m_pSerialiser->Serialise("context", ctxId);
|
||||
|
||||
WrappedID3D11DeviceContext *context =
|
||||
(WrappedID3D11DeviceContext *)m_pDevice->GetResourceManager()->GetLiveResource(ctxId);
|
||||
|
||||
if(m_FakeContext != ResourceId())
|
||||
{
|
||||
if(m_FakeContext == ctxId)
|
||||
context = this;
|
||||
else
|
||||
{
|
||||
m_pSerialiser->SetOffset(cOffs);
|
||||
m_pSerialiser->SkipCurrentChunk();
|
||||
m_pSerialiser->PopContext(chunk);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RDCASSERTMSG("Context is invalid", WrappedID3D11DeviceContext::IsAlloc(context), ctxId, context);
|
||||
// ctxId is now ignored
|
||||
WrappedID3D11DeviceContext *context = this;
|
||||
|
||||
LogState state = context->m_State;
|
||||
|
||||
@@ -759,6 +743,17 @@ void WrappedID3D11DeviceContext::ProcessChunk(uint64_t offset, D3D11ChunkType ch
|
||||
case DISCARD_VIEW: context->Serialise_DiscardView(NULL); break;
|
||||
case DISCARD_VIEW1: context->Serialise_DiscardView1(NULL, NULL, 0); break;
|
||||
|
||||
case RESTORE_STATE_AFTER_EXEC:
|
||||
{
|
||||
// apply saved state.
|
||||
if(m_DeferredSavedState)
|
||||
{
|
||||
m_DeferredSavedState->ApplyState(this);
|
||||
SAFE_DELETE(m_DeferredSavedState);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SWAP_PRESENT:
|
||||
{
|
||||
// we don't do anything with these parameters, they're just here to store
|
||||
@@ -958,9 +953,6 @@ void WrappedID3D11DeviceContext::AddDrawcall(const FetchDrawcall &d, bool hasEve
|
||||
{
|
||||
FetchDrawcall draw = d;
|
||||
|
||||
if(draw.context == ResourceId())
|
||||
draw.context = m_pDevice->GetResourceManager()->GetOriginalID(m_ResourceID);
|
||||
|
||||
if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED)
|
||||
{
|
||||
m_pDevice->GetImmediateContext()->AddDrawcall(draw, hasEvents);
|
||||
@@ -969,11 +961,6 @@ void WrappedID3D11DeviceContext::AddDrawcall(const FetchDrawcall &d, bool hasEve
|
||||
|
||||
m_AddedDrawcall = true;
|
||||
|
||||
WrappedID3D11DeviceContext *context =
|
||||
(WrappedID3D11DeviceContext *)m_pDevice->GetResourceManager()->GetLiveResource(draw.context);
|
||||
|
||||
RDCASSERT(context);
|
||||
|
||||
draw.eventID = m_CurEventID;
|
||||
draw.drawcallID = m_CurDrawcallID;
|
||||
|
||||
@@ -1007,34 +994,20 @@ void WrappedID3D11DeviceContext::AddDrawcall(const FetchDrawcall &d, bool hasEve
|
||||
|
||||
if(hasEvents)
|
||||
{
|
||||
vector<FetchAPIEvent> evs;
|
||||
evs.reserve(m_CurEvents.size());
|
||||
for(size_t i = 0; i < m_CurEvents.size();)
|
||||
{
|
||||
if(m_CurEvents[i].context == draw.context)
|
||||
{
|
||||
evs.push_back(m_CurEvents[i]);
|
||||
m_CurEvents.erase(m_CurEvents.begin() + i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
draw.events = evs;
|
||||
draw.events = m_CurEvents;
|
||||
m_CurEvents.clear();
|
||||
}
|
||||
|
||||
AddUsage(draw);
|
||||
|
||||
// should have at least the root drawcall here, push this drawcall
|
||||
// onto the back's children list.
|
||||
if(!context->m_DrawcallStack.empty())
|
||||
if(!m_DrawcallStack.empty())
|
||||
{
|
||||
DrawcallTreeNode node(draw);
|
||||
node.children.insert(node.children.begin(), draw.children.elems,
|
||||
draw.children.elems + draw.children.count);
|
||||
context->m_DrawcallStack.back()->children.push_back(node);
|
||||
m_DrawcallStack.back()->children.push_back(node);
|
||||
}
|
||||
else
|
||||
RDCERR("Somehow lost drawcall stack!");
|
||||
@@ -1053,7 +1026,6 @@ void WrappedID3D11DeviceContext::AddEvent(D3D11ChunkType type, string descriptio
|
||||
|
||||
FetchAPIEvent apievent;
|
||||
|
||||
apievent.context = ctx;
|
||||
apievent.fileOffset = m_CurChunkOffset;
|
||||
apievent.eventID = m_CurEventID;
|
||||
|
||||
@@ -1088,23 +1060,368 @@ void WrappedID3D11DeviceContext::ReplayFakeContext(ResourceId id)
|
||||
m_FakeContext = id;
|
||||
}
|
||||
|
||||
static void PadToAligned(Serialiser *dst, uint64_t alignment)
|
||||
{
|
||||
uint64_t offs = dst->GetOffset();
|
||||
uint64_t alignedoffs = AlignUp(offs, alignment);
|
||||
|
||||
// nothing to do
|
||||
if(offs == alignedoffs)
|
||||
return;
|
||||
|
||||
uint16_t chunkIdx = 0;
|
||||
dst->Serialise("", chunkIdx);
|
||||
offs += sizeof(chunkIdx);
|
||||
|
||||
uint8_t controlByte = 0; // control byte 0 indicates padding
|
||||
dst->Serialise("", controlByte);
|
||||
offs += sizeof(controlByte);
|
||||
|
||||
offs++; // we will have to write out a byte indicating how much padding exists, so add 1
|
||||
alignedoffs = AlignUp(offs, alignment);
|
||||
|
||||
uint8_t padLength = (alignedoffs - offs) & 0xff;
|
||||
dst->Serialise("", padLength);
|
||||
|
||||
// we might have padded with the control bytes, so only write some bytes if we need to
|
||||
if(padLength > 0)
|
||||
{
|
||||
const byte zeroes[256] = {};
|
||||
dst->RawWriteBytes(zeroes, (size_t)padLength);
|
||||
}
|
||||
}
|
||||
|
||||
static void CopyChunk(Serialiser *src, Serialiser *dst, uint64_t offsBegin)
|
||||
{
|
||||
uint64_t offsEnd = src->GetOffset();
|
||||
|
||||
// this whole function is quite an abuse of the serialiser interface :(.
|
||||
// It will all go away when I can break backwards compatibility and remove
|
||||
// this code and greatly tidy up the interface.
|
||||
|
||||
src->SetOffset(offsBegin);
|
||||
|
||||
dst->RawWriteBytes(src->RawReadBytes(size_t(offsEnd - offsBegin)), size_t(offsEnd - offsBegin));
|
||||
}
|
||||
|
||||
static void CopyUnmap(Serialiser *src, Serialiser *dst, Serialiser *tmp)
|
||||
{
|
||||
ResourceId Resource;
|
||||
uint32_t Subresource = 0;
|
||||
D3D11_MAP MapType = D3D11_MAP_WRITE_DISCARD;
|
||||
uint32_t MapFlags = 0;
|
||||
uint32_t DiffStart = 0;
|
||||
uint32_t DiffEnd = 0;
|
||||
byte *buf = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
tmp->Rewind();
|
||||
tmp->PushContext("", "", UNMAP, false);
|
||||
|
||||
// context id - ignored but needed to match expected format
|
||||
tmp->Serialise("", Resource);
|
||||
|
||||
src->Serialise("", Resource);
|
||||
tmp->Serialise("", Resource);
|
||||
|
||||
src->Serialise("", Subresource);
|
||||
tmp->Serialise("", Subresource);
|
||||
|
||||
src->Serialise("", MapType);
|
||||
tmp->Serialise("", MapType);
|
||||
|
||||
src->Serialise("", MapFlags);
|
||||
tmp->Serialise("", MapFlags);
|
||||
|
||||
src->Serialise("", DiffStart);
|
||||
tmp->Serialise("", DiffStart);
|
||||
|
||||
src->Serialise("", DiffEnd);
|
||||
tmp->Serialise("", DiffEnd);
|
||||
|
||||
src->SerialiseBuffer("", buf, len);
|
||||
tmp->SerialiseBuffer("", buf, len);
|
||||
|
||||
src->PopContext(UNMAP);
|
||||
tmp->PopContext(UNMAP);
|
||||
|
||||
SAFE_DELETE_ARRAY(buf);
|
||||
|
||||
dst->RawWriteBytes(tmp->GetRawPtr(0), size_t(tmp->GetOffset()));
|
||||
}
|
||||
|
||||
static void CopyUpdateSubresource(Serialiser *src, Serialiser *dst, Serialiser *tmp)
|
||||
{
|
||||
ResourceId idx;
|
||||
uint32_t flags = 0;
|
||||
uint32_t DestSubresource = 0;
|
||||
uint8_t isUpdate = true;
|
||||
|
||||
uint8_t HasDestBox = 0;
|
||||
D3D11_BOX box = {};
|
||||
uint32_t SourceRowPitch = 0;
|
||||
uint32_t SourceDepthPitch = 0;
|
||||
|
||||
uint32_t ResourceBufLen = 0;
|
||||
|
||||
byte *buf = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
tmp->Rewind();
|
||||
tmp->PushContext("", "", UPDATE_SUBRESOURCE1, false);
|
||||
|
||||
// context id - ignored but needed to match expected format
|
||||
tmp->Serialise("", idx);
|
||||
|
||||
src->Serialise("", idx);
|
||||
tmp->Serialise("", idx);
|
||||
|
||||
src->Serialise("", flags);
|
||||
tmp->Serialise("", flags);
|
||||
|
||||
src->Serialise("", DestSubresource);
|
||||
tmp->Serialise("", DestSubresource);
|
||||
|
||||
src->Serialise("", isUpdate);
|
||||
tmp->Serialise("", isUpdate);
|
||||
|
||||
if(isUpdate)
|
||||
{
|
||||
src->Serialise("", HasDestBox);
|
||||
tmp->Serialise("", HasDestBox);
|
||||
|
||||
if(HasDestBox)
|
||||
{
|
||||
src->Serialise("", box);
|
||||
tmp->Serialise("", box);
|
||||
}
|
||||
|
||||
src->Serialise("", SourceRowPitch);
|
||||
tmp->Serialise("", SourceRowPitch);
|
||||
|
||||
src->Serialise("", SourceDepthPitch);
|
||||
tmp->Serialise("", SourceDepthPitch);
|
||||
|
||||
src->Serialise("", ResourceBufLen);
|
||||
tmp->Serialise("", ResourceBufLen);
|
||||
|
||||
src->SerialiseBuffer("", buf, len);
|
||||
tmp->SerialiseBuffer("", buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
// shouldn't get in here, any chunks we're looking at are context chunks
|
||||
// so they should be recorded as updates
|
||||
|
||||
src->Serialise("", ResourceBufLen);
|
||||
tmp->Serialise("", ResourceBufLen);
|
||||
|
||||
src->SerialiseBuffer("", buf, len);
|
||||
tmp->SerialiseBuffer("", buf, len);
|
||||
}
|
||||
|
||||
src->PopContext(UPDATE_SUBRESOURCE1);
|
||||
tmp->PopContext(UPDATE_SUBRESOURCE1);
|
||||
|
||||
SAFE_DELETE_ARRAY(buf);
|
||||
|
||||
dst->RawWriteBytes(tmp->GetRawPtr(0), size_t(tmp->GetOffset()));
|
||||
}
|
||||
|
||||
void WrappedID3D11DeviceContext::FlattenLog()
|
||||
{
|
||||
Serialiser *src = m_pSerialiser;
|
||||
Serialiser *dst = new Serialiser(NULL, Serialiser::WRITING, false);
|
||||
|
||||
Serialiser *tmp = new Serialiser(NULL, Serialiser::WRITING, false);
|
||||
|
||||
map<ResourceId, Serialiser *> deferred;
|
||||
|
||||
uint64_t offsBegin = src->GetOffset();
|
||||
|
||||
D3D11ChunkType chunk = (D3D11ChunkType)src->PushContext(NULL, NULL, 1, false);
|
||||
RDCASSERTEQUAL(chunk, CONTEXT_CAPTURE_HEADER);
|
||||
src->SkipCurrentChunk();
|
||||
src->PopContext(chunk);
|
||||
|
||||
CopyChunk(src, dst, offsBegin);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
offsBegin = src->GetOffset();
|
||||
|
||||
chunk = (D3D11ChunkType)src->PushContext(NULL, NULL, 1, false);
|
||||
|
||||
ResourceId ctx;
|
||||
src->Serialise("ctx", ctx);
|
||||
|
||||
WrappedID3D11DeviceContext *context =
|
||||
(WrappedID3D11DeviceContext *)m_pDevice->GetResourceManager()->GetLiveResource(ctx);
|
||||
|
||||
// if it's a local chunk just copy it
|
||||
if(context == this)
|
||||
{
|
||||
ResourceId cmdList;
|
||||
uint8_t restore = 0;
|
||||
|
||||
if(chunk == EXECUTE_CMD_LIST)
|
||||
{
|
||||
m_pSerialiser->Serialise("RestoreContextState", restore);
|
||||
m_pSerialiser->Serialise("cmdList", cmdList);
|
||||
}
|
||||
|
||||
// these chunks need to be reserialised individually to ensure padding bytes in
|
||||
// between all remain the same
|
||||
if(chunk == UNMAP)
|
||||
{
|
||||
PadToAligned(dst, 64);
|
||||
CopyUnmap(src, dst, tmp);
|
||||
}
|
||||
else if(chunk == UPDATE_SUBRESOURCE || chunk == UPDATE_SUBRESOURCE1)
|
||||
{
|
||||
PadToAligned(dst, 64);
|
||||
CopyUpdateSubresource(src, dst, tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
src->SetOffset(offsBegin);
|
||||
src->PushContext(NULL, NULL, 1, false);
|
||||
src->SkipCurrentChunk();
|
||||
src->PopContext(chunk);
|
||||
|
||||
CopyChunk(src, dst, offsBegin);
|
||||
}
|
||||
|
||||
if(chunk == EXECUTE_CMD_LIST)
|
||||
{
|
||||
Serialiser *def = deferred[cmdList];
|
||||
|
||||
if(def == NULL)
|
||||
{
|
||||
RDCERR("ExecuteCommandList found for command list we didn't Finish!");
|
||||
}
|
||||
else
|
||||
{
|
||||
// when inserting, ensure the chunks stay aligned (this is harmless if they don't need
|
||||
// alignment). Do this by inserting padding bytes, ugly but it works.
|
||||
PadToAligned(dst, 64);
|
||||
|
||||
// now insert the chunks to replay
|
||||
dst->RawWriteBytes(deferred[cmdList]->GetRawPtr(0), (size_t)deferred[cmdList]->GetSize());
|
||||
|
||||
// if we have to restore the state, the above Execute.. will have
|
||||
// saved it, so we just add a little chunk to let it pop it again
|
||||
if(restore)
|
||||
{
|
||||
tmp->Rewind();
|
||||
tmp->PushContext("", "", RESTORE_STATE_AFTER_EXEC, false);
|
||||
tmp->PopContext(RESTORE_STATE_AFTER_EXEC);
|
||||
|
||||
dst->RawWriteBytes(tmp->GetRawPtr(0), size_t(tmp->GetOffset()));
|
||||
}
|
||||
|
||||
// again since we inserted chunks we need to align again
|
||||
PadToAligned(dst, 64);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(deferred[ctx] == NULL)
|
||||
deferred[ctx] = new Serialiser(NULL, Serialiser::WRITING, false);
|
||||
|
||||
ResourceId cmdList;
|
||||
uint8_t restore = 0;
|
||||
|
||||
if(chunk == FINISH_CMD_LIST)
|
||||
{
|
||||
m_pSerialiser->Serialise("RestoreDeferredContextState", restore);
|
||||
m_pSerialiser->Serialise("cmdList", cmdList);
|
||||
|
||||
if(restore != 0)
|
||||
{
|
||||
RDCWARN(
|
||||
"RestoreDeferredContextState == TRUE was set for command list %llu. "
|
||||
"On old captures this wasn't properly replayed and can't be fixed as-is, "
|
||||
"re-capture with latest RenderDoc to solve this issue.");
|
||||
}
|
||||
}
|
||||
|
||||
// these chunks need to be reserialised individually to ensure padding bytes in
|
||||
// between all remain the same
|
||||
if(chunk == UNMAP)
|
||||
{
|
||||
PadToAligned(deferred[ctx], 64);
|
||||
CopyUnmap(src, deferred[ctx], tmp);
|
||||
}
|
||||
else if(chunk == UPDATE_SUBRESOURCE || chunk == UPDATE_SUBRESOURCE1)
|
||||
{
|
||||
PadToAligned(deferred[ctx], 64);
|
||||
CopyUpdateSubresource(src, deferred[ctx], tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
src->SetOffset(offsBegin);
|
||||
src->PushContext(NULL, NULL, 1, false);
|
||||
src->SkipCurrentChunk();
|
||||
src->PopContext(chunk);
|
||||
|
||||
CopyChunk(src, deferred[ctx], offsBegin);
|
||||
}
|
||||
|
||||
if(chunk == FINISH_CMD_LIST)
|
||||
{
|
||||
// here is where RestoreDeferredContextState is broken, this doesn't
|
||||
// take into account the inherited state from previous recordings.
|
||||
deferred[cmdList] = deferred[ctx];
|
||||
deferred[ctx] = new Serialiser(NULL, Serialiser::WRITING, false);
|
||||
}
|
||||
}
|
||||
|
||||
if(chunk == CONTEXT_CAPTURE_FOOTER)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_pSerialiser = new Serialiser(dst->GetSize(), dst->GetRawPtr(0), false);
|
||||
m_OwnSerialiser = true;
|
||||
|
||||
// tidy up the temporary serialisers
|
||||
SAFE_DELETE(dst);
|
||||
SAFE_DELETE(tmp);
|
||||
|
||||
for(auto it = deferred.begin(); it != deferred.end(); ++it)
|
||||
SAFE_DELETE(it->second);
|
||||
}
|
||||
|
||||
void WrappedID3D11DeviceContext::ReplayLog(LogState readType, uint32_t startEventID,
|
||||
uint32_t endEventID, bool partial)
|
||||
{
|
||||
m_State = readType;
|
||||
|
||||
if(readType == READING && m_pDevice->GetNumDeferredContexts() &&
|
||||
m_pDevice->GetLogVersion() < 0x00000A)
|
||||
{
|
||||
// flatten the log
|
||||
FlattenLog();
|
||||
}
|
||||
|
||||
m_DoStateVerify = true;
|
||||
|
||||
if(readType == EXECUTING && m_pDevice->GetNumDeferredContexts() &&
|
||||
m_pDevice->GetLogVersion() < 0x00000A)
|
||||
{
|
||||
m_pSerialiser->SetOffset(0);
|
||||
}
|
||||
|
||||
D3D11ChunkType header = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false);
|
||||
RDCASSERTEQUAL(header, CONTEXT_CAPTURE_HEADER);
|
||||
|
||||
ResourceId id;
|
||||
m_pSerialiser->Serialise("context", id);
|
||||
|
||||
WrappedID3D11DeviceContext *context =
|
||||
(WrappedID3D11DeviceContext *)m_pDevice->GetResourceManager()->GetLiveResource(id);
|
||||
|
||||
RDCASSERT(WrappedID3D11DeviceContext::IsAlloc(context) && context == this);
|
||||
// id is now ignored
|
||||
|
||||
Serialise_BeginCaptureFrame(!partial);
|
||||
|
||||
|
||||
@@ -202,6 +202,7 @@ private:
|
||||
ResourceId m_ResourceID;
|
||||
D3D11ResourceRecord *m_ContextRecord;
|
||||
|
||||
bool m_OwnSerialiser;
|
||||
Serialiser *m_pSerialiser;
|
||||
LogState m_State;
|
||||
CaptureFailReason m_FailureReason;
|
||||
@@ -215,6 +216,8 @@ private:
|
||||
bool m_DoStateVerify;
|
||||
D3D11RenderState *m_CurrentPipelineState;
|
||||
|
||||
D3D11RenderState *m_DeferredSavedState;
|
||||
|
||||
vector<FetchAPIEvent> m_CurEvents, m_Events;
|
||||
bool m_AddedDrawcall;
|
||||
|
||||
@@ -243,6 +246,8 @@ private:
|
||||
|
||||
list<DrawcallTreeNode *> m_DrawcallStack;
|
||||
|
||||
void FlattenLog();
|
||||
|
||||
const char *GetChunkName(D3D11ChunkType idx);
|
||||
|
||||
void Serialise_DebugMessages();
|
||||
|
||||
@@ -4787,48 +4787,22 @@ bool WrappedID3D11DeviceContext::Serialise_ExecuteCommandList(ID3D11CommandList
|
||||
SERIALISE_ELEMENT(uint8_t, RestoreContextState, RestoreContextState_ == TRUE);
|
||||
SERIALISE_ELEMENT(ResourceId, cmdList, GetIDForResource(pCommandList));
|
||||
|
||||
RDCASSERT(GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE);
|
||||
|
||||
if(m_State <= EXECUTING)
|
||||
{
|
||||
if(m_pDevice->GetResourceManager()->HasLiveResource(cmdList))
|
||||
m_pRealContext->ExecuteCommandList(
|
||||
UNWRAP(WrappedID3D11CommandList, m_pDevice->GetResourceManager()->GetLiveResource(cmdList)),
|
||||
RestoreContextState);
|
||||
else
|
||||
RDCERR("Don't have command list serialised for %llu", cmdList);
|
||||
|
||||
if(!RestoreContextState)
|
||||
m_CurrentPipelineState->Clear();
|
||||
|
||||
VerifyState();
|
||||
}
|
||||
|
||||
const string desc = m_pSerialiser->GetDebugStr();
|
||||
|
||||
Serialise_DebugMessages();
|
||||
|
||||
if(m_State <= EXECUTING && RestoreContextState)
|
||||
{
|
||||
m_DeferredSavedState = new D3D11RenderState(this);
|
||||
}
|
||||
|
||||
if(m_State == READING)
|
||||
{
|
||||
string name = "ExecuteCommandList(" + ToStr::Get(cmdList) + ")";
|
||||
|
||||
FetchDrawcall draw;
|
||||
draw.name = name;
|
||||
draw.flags |= eDraw_CmdList | eDraw_PushMarker;
|
||||
|
||||
AddDrawcall(draw, true);
|
||||
|
||||
auto cmdDrawChildren = m_CmdLists.find(cmdList);
|
||||
|
||||
if(!m_DrawcallStack.empty() && !m_DrawcallStack.back()->children.empty() &&
|
||||
cmdDrawChildren != m_CmdLists.end())
|
||||
{
|
||||
m_DrawcallStack.back()->children.back().children = cmdDrawChildren->second.children;
|
||||
|
||||
// assign new drawcall IDs so that we don't get duplicates if this commandlist is executed
|
||||
// again
|
||||
RefreshDrawcallIDs(cmdDrawChildren->second);
|
||||
}
|
||||
draw.flags |= eDraw_CmdList | eDraw_SetMarker;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -5063,29 +5037,6 @@ bool WrappedID3D11DeviceContext::Serialise_FinishCommandList(BOOL RestoreDeferre
|
||||
SERIALISE_ELEMENT(uint8_t, RestoreDeferredContextState, RestoreDeferredContextState_ == TRUE);
|
||||
SERIALISE_ELEMENT(ResourceId, cmdList, GetIDForResource(*ppCommandList));
|
||||
|
||||
if(m_State <= EXECUTING && GetType() == D3D11_DEVICE_CONTEXT_DEFERRED)
|
||||
{
|
||||
ID3D11CommandList *ret = NULL;
|
||||
HRESULT hr = m_pRealContext->FinishCommandList(RestoreDeferredContextState, &ret);
|
||||
|
||||
if(!RestoreDeferredContextState)
|
||||
m_CurrentPipelineState->Clear();
|
||||
|
||||
VerifyState();
|
||||
|
||||
if(FAILED(hr))
|
||||
RDCERR("Failed on finishing command list, HRESULT: 0x%08x", hr);
|
||||
|
||||
RDCASSERT(SUCCEEDED(hr) && ret);
|
||||
|
||||
ret = new WrappedID3D11CommandList(ret, m_pDevice, this, true);
|
||||
|
||||
if(ret)
|
||||
{
|
||||
m_pDevice->GetResourceManager()->AddLiveResource(cmdList, ret);
|
||||
}
|
||||
}
|
||||
|
||||
const string desc = m_pSerialiser->GetDebugStr();
|
||||
|
||||
Serialise_DebugMessages();
|
||||
@@ -5097,12 +5048,9 @@ bool WrappedID3D11DeviceContext::Serialise_FinishCommandList(BOOL RestoreDeferre
|
||||
|
||||
FetchDrawcall draw;
|
||||
draw.name = name;
|
||||
draw.flags |= eDraw_CmdList;
|
||||
draw.flags |= eDraw_CmdList | eDraw_SetMarker;
|
||||
|
||||
AddDrawcall(draw, true);
|
||||
|
||||
m_pDevice->GetImmediateContext()->m_CmdLists[cmdList] = m_ParentDrawcall;
|
||||
m_ParentDrawcall.children.clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -193,6 +193,8 @@ const char *D3D11ChunkNames[] = {
|
||||
"ID3D11Device3::CreateUnorderedAccessView1",
|
||||
|
||||
"IDXGISwapChain::Present",
|
||||
|
||||
"ID3D11DeviceContext::ExecuteCommandList",
|
||||
};
|
||||
|
||||
WRAPPED_POOL_INST(WrappedID3D11Device);
|
||||
@@ -229,6 +231,10 @@ const uint32_t D3D11InitParams::D3D11_OLD_VERSIONS[D3D11InitParams::D3D11_NUM_SU
|
||||
// from 0x8 to 0x9, we added the view creation details to clear calls in the device
|
||||
// record so that we can still perform the clear even if the view wasn't referenced.
|
||||
0x000008,
|
||||
// from 0x9 to 0xA, we refactored deferred context handling - it's flattened on
|
||||
// capture now. So on replay if deferred contexts are present, we go through a
|
||||
// flattening stpe.
|
||||
0x000009,
|
||||
};
|
||||
|
||||
ReplayCreateStatus D3D11InitParams::Serialise()
|
||||
|
||||
@@ -62,10 +62,10 @@ struct D3D11InitParams : public RDCInitParams
|
||||
UINT NumFeatureLevels;
|
||||
D3D_FEATURE_LEVEL FeatureLevels[16];
|
||||
|
||||
static const uint32_t D3D11_SERIALISE_VERSION = 0x0000009;
|
||||
static const uint32_t D3D11_SERIALISE_VERSION = 0x000000A;
|
||||
|
||||
// backwards compatibility for old logs described at the declaration of this array
|
||||
static const uint32_t D3D11_NUM_SUPPORTED_OLD_VERSIONS = 5;
|
||||
static const uint32_t D3D11_NUM_SUPPORTED_OLD_VERSIONS = 6;
|
||||
static const uint32_t D3D11_OLD_VERSIONS[D3D11_NUM_SUPPORTED_OLD_VERSIONS];
|
||||
|
||||
// version number internal to d3d11 stream
|
||||
|
||||
@@ -302,22 +302,6 @@ namespace renderdocui.Windows
|
||||
def.eventID = eventNum;
|
||||
def.marker = (drawcall.flags & DrawcallFlags.SetMarker) != 0;
|
||||
|
||||
if (drawcall.context != m_Core.FrameInfo.immContextId)
|
||||
{
|
||||
def.defCtx = drawcall.context;
|
||||
def.lastDefEv = drawcall.eventID;
|
||||
|
||||
FetchDrawcall parent = drawcall.parent;
|
||||
while(!parent.name.Contains("ExecuteCommand"))
|
||||
parent = parent.parent;
|
||||
|
||||
def.eventID = parent.eventID-1;
|
||||
|
||||
def.firstDefEv = parent.children[0].eventID;
|
||||
if(parent.children[0].events.Length > 0)
|
||||
def.firstDefEv = parent.children[0].events[0].eventID;
|
||||
}
|
||||
|
||||
drawNode.Tag = def;
|
||||
|
||||
if (drawcall.children != null && drawcall.children.Length > 0)
|
||||
|
||||
Reference in New Issue
Block a user