From 9545e6f27b49179405b3d987b9d244deed43910e Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 9 Jun 2025 16:07:44 +0100 Subject: [PATCH] Add specific annotation for GPU address serialised values --- qrenderdoc/Code/QRDUtils.cpp | 10 ++++++++++ .../VulkanPipelineStateViewer.cpp | 1 + renderdoc/api/replay/structured_data.h | 7 +++++++ renderdoc/driver/vulkan/vk_serialise.cpp | 4 ++-- renderdoc/serialise/codecs/xml_codec.cpp | 11 +++++++---- renderdoc/serialise/serialiser.cpp | 2 ++ renderdoc/serialise/serialiser.h | 19 +++++++++++++++++++ 7 files changed, 48 insertions(+), 6 deletions(-) diff --git a/qrenderdoc/Code/QRDUtils.cpp b/qrenderdoc/Code/QRDUtils.cpp index 90c2bae91..21ca74968 100644 --- a/qrenderdoc/Code/QRDUtils.cpp +++ b/qrenderdoc/Code/QRDUtils.cpp @@ -1961,6 +1961,13 @@ QVariant SDObject2Variant(const SDObject *obj, bool inlineImportant) { param = QVariant::fromValue(obj->data.basic.id); } + else if(obj->type.basetype == SDBasic::GPUAddress) + { + PointerVal p; + p.pointerTypeID = ~0U; + p.pointer = obj->data.basic.u; + param = ToQStr(p); + } else if(obj->type.flags & SDTypeFlags::NullString) { param = lit("NULL"); @@ -2085,7 +2092,10 @@ QVariant SDObject2Variant(const SDObject *obj, bool inlineImportant) param = trimmedStr.trimmed(); break; } + // won't be hit, these are handled above case SDBasic::Resource: + case SDBasic::GPUAddress: + // normal cases case SDBasic::Enum: case SDBasic::UnsignedInteger: param = Formatter::HumanFormat(obj->data.basic.u, flags); diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index bd2b6af52..cee272e25 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -4728,6 +4728,7 @@ QVariant VulkanPipelineStateViewer::ConvertSDObjectToFossilizeJSON(const SDObjec return list; } case SDBasic::String: return QString(obj->AsString()); + case SDBasic::GPUAddress: case SDBasic::Enum: case SDBasic::UnsignedInteger: return (qulonglong)obj->AsUInt64(); case SDBasic::SignedInteger: return (qlonglong)obj->AsInt64(); diff --git a/renderdoc/api/replay/structured_data.h b/renderdoc/api/replay/structured_data.h index 9337afa0c..7e939ba43 100644 --- a/renderdoc/api/replay/structured_data.h +++ b/renderdoc/api/replay/structured_data.h @@ -91,6 +91,11 @@ DOCUMENT(R"(The basic irreducible type of an object. Every other more complex ty A ResourceId. Equivalent to (and stored as) an 8-byte unsigned integer, but specifically contains the unique Id of a resource in a capture. + +.. data:: GPUAddress + + A GPU pointer. Equivalent to (and stored as) an 8-byte unsigned integer, but specifically contains + the address of a resource in a capture. )"); enum class SDBasic : uint32_t { @@ -107,6 +112,7 @@ enum class SDBasic : uint32_t Boolean, Character, Resource, + GPUAddress, }; DECLARE_REFLECTION_ENUM(SDBasic); @@ -932,6 +938,7 @@ Invalid if the object is not actually a :class:`ResourceId`. case SDBasic::Buffer: return QVariant(); case SDBasic::String: return data.str; case SDBasic::Enum: + case SDBasic::GPUAddress: case SDBasic::UnsignedInteger: return QVariant(qulonglong(data.basic.u)); case SDBasic::SignedInteger: return QVariant(qlonglong(data.basic.i)); case SDBasic::Resource: return (QVariant)data.basic.id; diff --git a/renderdoc/driver/vulkan/vk_serialise.cpp b/renderdoc/driver/vulkan/vk_serialise.cpp index e330a7565..eca2dfab8 100644 --- a/renderdoc/driver/vulkan/vk_serialise.cpp +++ b/renderdoc/driver/vulkan/vk_serialise.cpp @@ -9786,7 +9786,7 @@ void DoSerialise(SerialiserType &ser, VkDescriptorBufferBindingInfoEXT &el) RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT); SerialiseNext(ser, el.sType, el.pNext); - SERIALISE_MEMBER(address); + SERIALISE_MEMBER(address).GPUAddress(); SERIALISE_MEMBER_VKFLAGS(VkBufferUsageFlags, usage); } @@ -9818,7 +9818,7 @@ void DoSerialise(SerialiserType &ser, VkDescriptorAddressInfoEXT &el) RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT); SerialiseNext(ser, el.sType, el.pNext); - SERIALISE_MEMBER(address); + SERIALISE_MEMBER(address).GPUAddress(); SERIALISE_MEMBER(range); SERIALISE_MEMBER(format); } diff --git a/renderdoc/serialise/codecs/xml_codec.cpp b/renderdoc/serialise/codecs/xml_codec.cpp index d4e4060bf..fef804a44 100644 --- a/renderdoc/serialise/codecs/xml_codec.cpp +++ b/renderdoc/serialise/codecs/xml_codec.cpp @@ -40,7 +40,7 @@ struct ThumbTypeAndData static const char *typeNames[] = { "chunk", "struct", "array", "null", "buffer", "string", "enum", - "uint", "int", "float", "bool", "char", "ResourceId", + "uint", "int", "float", "bool", "char", "ResourceId", "GPUAddress", }; struct LiteralFileSection @@ -232,7 +232,8 @@ static bool Obj2XML(pugi::xml_node &parent, SDObject &child) if(child.type.basetype == SDBasic::UnsignedInteger || child.type.basetype == SDBasic::SignedInteger || child.type.basetype == SDBasic::Float || - child.type.basetype == SDBasic::Resource || child.type.basetype == SDBasic::Enum) + child.type.basetype == SDBasic::GPUAddress || child.type.basetype == SDBasic::Resource || + child.type.basetype == SDBasic::Enum) { obj.append_attribute("width") = child.type.byteSize; } @@ -299,6 +300,7 @@ static bool Obj2XML(pugi::xml_node &parent, SDObject &child) switch(child.type.basetype) { + case SDBasic::GPUAddress: case SDBasic::Resource: case SDBasic::Enum: case SDBasic::UnsignedInteger: obj.text() = child.data.basic.u; break; @@ -544,8 +546,8 @@ static SDObject *XML2Obj(pugi::xml_node &obj) } } - if(ret->type.basetype == SDBasic::UnsignedInteger || - ret->type.basetype == SDBasic::SignedInteger || ret->type.basetype == SDBasic::Float || + if(ret->type.basetype == SDBasic::UnsignedInteger || ret->type.basetype == SDBasic::SignedInteger || + ret->type.basetype == SDBasic::Float || ret->type.basetype == SDBasic::GPUAddress || ret->type.basetype == SDBasic::Resource || ret->type.basetype == SDBasic::Enum) { ret->type.byteSize = obj.attribute("width").as_uint(4); @@ -624,6 +626,7 @@ static SDObject *XML2Obj(pugi::xml_node &obj) switch(ret->type.basetype) { + case SDBasic::GPUAddress: case SDBasic::Resource: case SDBasic::Enum: case SDBasic::UnsignedInteger: ret->data.basic.u = obj.text().as_ullong(); break; diff --git a/renderdoc/serialise/serialiser.cpp b/renderdoc/serialise/serialiser.cpp index 8b1e2239f..5a12a384d 100644 --- a/renderdoc/serialise/serialiser.cpp +++ b/renderdoc/serialise/serialiser.cpp @@ -69,6 +69,7 @@ void DumpObject(FileIO::LogFileHandle *log, const rdcstr &indent, SDObject *obj) case SDBasic::Boolean: val = ToStr(obj->data.basic.b); break; case SDBasic::Character: val = ToStr(obj->data.basic.c); break; case SDBasic::Resource: val = ToStr(obj->data.basic.id); break; + case SDBasic::GPUAddress: val = "GPUAddress::" + ToStr(obj->data.basic.u); break; } rdcstr msg = StringFormat::Fmt("%s%s %s = %s\n", indent.c_str(), obj->type.name.c_str(), obj->name.c_str(), val.c_str()); @@ -838,6 +839,7 @@ void DoSerialise(SerialiserType &ser, SDObject *el) case SDBasic::Character: ser.Serialise(""_lit, el->data.basic.c); break; case SDBasic::Resource: ser.Serialise(""_lit, el->data.basic.id); break; case SDBasic::Enum: + case SDBasic::GPUAddress: case SDBasic::UnsignedInteger: if(el->type.byteSize == 1) { diff --git a/renderdoc/serialise/serialiser.h b/renderdoc/serialise/serialiser.h index e9ca9eb14..3eca34d87 100644 --- a/renderdoc/serialise/serialiser.h +++ b/renderdoc/serialise/serialiser.h @@ -1269,6 +1269,24 @@ public: return *this; } + Serialiser &GPUAddress() + { + if(ExportStructure() && !m_StructureStack.empty()) + { + SDObject ¤t = *m_StructureStack.back(); + + if(current.NumChildren() > 0) + { + SDType &type = current.GetChild(current.NumChildren() - 1)->type; + RDCASSERT(type.basetype == SDBasic::UnsignedInteger); + RDCASSERT(type.byteSize == 8); + type.basetype = SDBasic::GPUAddress; + } + } + + return *this; + } + // these functions should be used very carefully, they completely disable structured export for // anything serialised while internal is set. void PushInternal() { m_InternalElement++; } @@ -1309,6 +1327,7 @@ public: case SDBasic::String: RDCFATAL("eString should be specialised!"); break; case SDBasic::Enum: case SDBasic::Resource: + case SDBasic::GPUAddress: case SDBasic::UnsignedInteger: if(byteSize == 1) current.data.basic.u = (uint64_t)(uint8_t)el;