diff --git a/renderdoc/api/replay/structured_data.h b/renderdoc/api/replay/structured_data.h index 7947ac85f..6139f5c89 100644 --- a/renderdoc/api/replay/structured_data.h +++ b/renderdoc/api/replay/structured_data.h @@ -206,11 +206,17 @@ DOCUMENT(R"(Bitfield flags that could be applied to an :class:`SDChunk`. This chunk wasn't supported for decoding or was skipped for another reason and was detailed as an opaque byte stream. It should be preserved as-is and will remain in native RDC format. + +.. data:: HasCallstack + + This chunk has a callstack. Used to indicate the presence of a callstack even if it's empty + (perhaps due to failure to collect the stack frames). )"); enum class SDChunkFlags : uint64_t { NoFlags = 0x0, OpaqueChunk = 0x1, + HasCallstack = 0x2, }; BITMASK_OPERATORS(SDChunkFlags); diff --git a/renderdoc/serialise/codecs/xml_codec.cpp b/renderdoc/serialise/codecs/xml_codec.cpp index aabc2f3b0..cc1bf1fc5 100644 --- a/renderdoc/serialise/codecs/xml_codec.cpp +++ b/renderdoc/serialise/codecs/xml_codec.cpp @@ -414,7 +414,7 @@ static ReplayStatus Structured2XML(const char *filename, const RDCFile &file, ui xChunk.append_attribute("timestamp") = chunk->metadata.timestampMicro; if(chunk->metadata.durationMicro >= 0) xChunk.append_attribute("duration") = chunk->metadata.durationMicro; - if(!chunk->metadata.callstack.empty()) + if(chunk->metadata.flags & SDChunkFlags::HasCallstack) { pugi::xml_node stack = xChunk.append_child("callstack"); @@ -746,6 +746,8 @@ static ReplayStatus XML2Structured(const char *xml, const ThumbTypeAndData &thum pugi::xml_node callstack = xChunk.child("callstack"); if(callstack) { + chunk->metadata.flags |= SDChunkFlags::HasCallstack; + size_t i = 0; for(pugi::xml_node address = callstack.first_child(); address; address = address.next_sibling()) { diff --git a/renderdoc/serialise/serialiser.cpp b/renderdoc/serialise/serialiser.cpp index 1c7dd2e11..d6acb37aa 100644 --- a/renderdoc/serialise/serialiser.cpp +++ b/renderdoc/serialise/serialiser.cpp @@ -85,6 +85,8 @@ uint32_t Serialiser::BeginChunk(uint32_t, uint32_t) uint32_t numFrames = 0; m_Read->Read(numFrames); + m_ChunkMetadata.flags |= SDChunkFlags::HasCallstack; + m_ChunkMetadata.callstack.resize((size_t)numFrames); m_Read->Read(m_ChunkMetadata.callstack.data(), m_ChunkMetadata.callstack.byteSize()); } @@ -297,6 +299,8 @@ uint32_t Serialiser::BeginChunk(uint32_t chunkID, uint3 } } + m_ChunkMetadata.flags |= SDChunkFlags::HasCallstack; + uint32_t numFrames = (uint32_t)m_ChunkMetadata.callstack.size(); m_Write->Write(numFrames); @@ -433,7 +437,7 @@ void Serialiser::WriteStructuredFile(const SDFile &file m_ChunkFlags = 0; - if(!m_ChunkMetadata.callstack.empty()) + if(m_ChunkMetadata.flags & SDChunkFlags::HasCallstack) m_ChunkFlags |= ChunkCallstack; if(m_ChunkMetadata.threadID != 0)