diff --git a/src/gfxstream/codegen/scripts/cereal/decoder.py b/src/gfxstream/codegen/scripts/cereal/decoder.py
index 9d49808e00f..d5db5cef184 100644
--- a/src/gfxstream/codegen/scripts/cereal/decoder.py
+++ b/src/gfxstream/codegen/scripts/cereal/decoder.py
@@ -35,6 +35,13 @@ GLOBAL_COMMANDS_WITHOUT_DISPATCH = [
"vkEnumerateInstanceExtensionProperties",
"vkEnumerateInstanceLayerProperties",
"vkTraceAsyncGOOGLE",
+ "vkSetDebugMetadataAsyncGOOGLE",
+]
+
+COMMANDS_WITHOUT_TRACE = [
+ # This command is used to set perfetto track names (using the guest process and thread name)
+ # and track names should (ideally) be set before any trace events
+ 'vkSetDebugMetadataAsyncGOOGLE',
]
SNAPSHOT_API_CALL_HANDLE_VARNAME = "snapshotApiCallHandle"
@@ -792,6 +799,7 @@ custom_decodes = {
"vkGetBlobGOOGLE" : emit_global_state_wrapped_decoding,
"vkGetSemaphoreGOOGLE" : emit_global_state_wrapped_decoding,
"vkTraceAsyncGOOGLE" : emit_global_state_wrapped_decoding,
+ "vkSetDebugMetadataAsyncGOOGLE" : emit_global_state_wrapped_decoding,
# Descriptor update templates
"vkCreateDescriptorUpdateTemplate" : emit_global_state_wrapped_decoding,
@@ -968,7 +976,9 @@ size_t VkDecoder::Impl::decode(void* buf, size_t len, IOStream* ioStream,
cgen.line("case OP_%s:" % name)
cgen.beginBlock()
- cgen.stmt("GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_DECODER_CATEGORY, \"VkDecoder %s\")" % name)
+
+ if name not in COMMANDS_WITHOUT_TRACE:
+ cgen.stmt("GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_DECODER_CATEGORY, \"VkDecoder %s\")" % name)
if api.name in custom_decodes.keys():
custom_decodes[api.name](typeInfo, api, cgen)
diff --git a/src/gfxstream/codegen/xml/vk_gfxstream.xml b/src/gfxstream/codegen/xml/vk_gfxstream.xml
index 52fcc068782..13f7218c73a 100644
--- a/src/gfxstream/codegen/xml/vk_gfxstream.xml
+++ b/src/gfxstream/codegen/xml/vk_gfxstream.xml
@@ -37,6 +37,30 @@ specific entries.
uint32_t blobFlags
uint64_t blobId
+
+ VkStructureType sType
+ const void* pNext
+
+
+ VkStructureType sType
+ const void* pNext
+ const char* pName
+
+
+ VkStructureType sType
+ const void* pNext
+ uint64_t id
+
+
+ VkStructureType sType
+ const void* pNext
+ const char* pName
+
+
+ VkStructureType sType
+ const void* pNext
+ uint64_t id
+
@@ -245,6 +269,10 @@ specific entries.
void vkTraceAsyncGOOGLE
uint64_t id
+
+ void vkSetDebugMetadataAsyncGOOGLE
+ const VkDebugMetadataGOOGLE* pDebugMetadata
+
@@ -256,9 +284,19 @@ specific entries.
+
+
+
+
+
+
+
+
+
+
@@ -285,6 +323,7 @@ specific entries.
+
diff --git a/src/gfxstream/guest/vulkan_enc/GfxStreamVulkanConnection.cpp b/src/gfxstream/guest/vulkan_enc/GfxStreamVulkanConnection.cpp
index ec269e6c2f4..5753694f103 100644
--- a/src/gfxstream/guest/vulkan_enc/GfxStreamVulkanConnection.cpp
+++ b/src/gfxstream/guest/vulkan_enc/GfxStreamVulkanConnection.cpp
@@ -5,8 +5,94 @@
#include "GfxStreamVulkanConnection.h"
+#include
+
+#include "util/detect_os.h"
+#include "util/u_process.h"
+#include "VirtGpu.h"
+
+#if DETECT_OS_LINUX
+#include
+#if !defined(HAVE_GETTID)
+#include
+#endif // !defined(HAVE_GETTID)
+#include
+#endif
+
+namespace {
+
+// TODO: move to a more common src/util location.
+static uint64_t getProcessId() {
+#if DETECT_OS_LINUX
+ return getpid();
+#endif
+ return -1;
+}
+
+// TODO: move to a more common src/util location.
+static std::string getThreadName() {
+ std::string threadName;
+#if DETECT_OS_LINUX
+ char buf[16] = {};
+ if (prctl(PR_GET_NAME, buf) == 0) {
+ threadName = buf;
+ }
+#endif
+ return threadName;
+}
+
+// TODO: move to a more common src/util location.
+static uint64_t getThreadId() {
+#if DETECT_OS_LINUX
+#if defined(HAVE_GETTID)
+ return gettid();
+#else
+ return (pid_t)syscall(SYS_gettid);
+#endif // defined(HAVE_GETTID)
+#endif
+ return -1;
+}
+
+} // namespace
+
GfxStreamVulkanConnection::GfxStreamVulkanConnection(gfxstream::guest::IOStream* stream) {
mVkEnc = std::make_unique(stream);
+
+ auto* device = VirtGpuDevice::getInstance(kCapsetGfxStreamVulkan);
+ if (device != nullptr) {
+ const auto caps = device->getCaps();
+ if (caps.vulkanCapset.hasSetMetadataCommand) {
+ const std::string processName = util_get_process_name();
+ const struct VkDebugMetadataGuestProcessNameGOOGLE debugMetadataGuestProcessName = {
+ .sType = VK_STRUCTURE_TYPE_DEBUG_METADATA_GUEST_PROCESS_NAME_GOOGLE,
+ .pNext = nullptr,
+ .pName = processName.c_str(),
+ };
+ const uint64_t processId = getProcessId();
+ const struct VkDebugMetadataGuestThreadIdGOOGLE debugMetadataGuestProcessId = {
+ .sType = VK_STRUCTURE_TYPE_DEBUG_METADATA_GUEST_PROCESS_ID_GOOGLE,
+ .pNext = &debugMetadataGuestProcessName,
+ .id = processId,
+ };
+ const std::string threadName = getThreadName();
+ const struct VkDebugMetadataGuestThreadNameGOOGLE debugMetadataGuestThreadName = {
+ .sType = VK_STRUCTURE_TYPE_DEBUG_METADATA_GUEST_THREAD_NAME_GOOGLE,
+ .pNext = &debugMetadataGuestProcessId,
+ .pName = threadName.c_str(),
+ };
+ const uint64_t threadId = getThreadId();
+ const struct VkDebugMetadataGuestThreadIdGOOGLE debugMetadataGuestThreadId = {
+ .sType = VK_STRUCTURE_TYPE_DEBUG_METADATA_GUEST_THREAD_ID_GOOGLE,
+ .pNext = &debugMetadataGuestThreadName,
+ .id = threadId,
+ };
+ const struct VkDebugMetadataGOOGLE debugMetadata = {
+ .sType = VK_STRUCTURE_TYPE_DEBUG_METADATA_GOOGLE,
+ .pNext = &debugMetadataGuestThreadId,
+ };
+ mVkEnc->vkSetDebugMetadataAsyncGOOGLE(&debugMetadata, false /* no lock */);
+ }
+ }
}
GfxStreamVulkanConnection::~GfxStreamVulkanConnection() {}
diff --git a/src/gfxstream/guest/vulkan_enc/ResourceTracker.h b/src/gfxstream/guest/vulkan_enc/ResourceTracker.h
index 2aee92c0d2e..b59c09acb89 100644
--- a/src/gfxstream/guest/vulkan_enc/ResourceTracker.h
+++ b/src/gfxstream/guest/vulkan_enc/ResourceTracker.h
@@ -523,7 +523,6 @@ class ResourceTracker {
void setupFeatures(const struct GfxStreamVkFeatureInfo* features);
void setupCaps(uint32_t& noRenderControlEnc);
void setupPlatformHelpers();
-
void setThreadingCallbacks(const ThreadingCallbacks& callbacks);
bool hostSupportsVulkan() const;
bool usingDirectMapping() const;
@@ -890,6 +889,8 @@ class ResourceTracker {
void EmitGuestAndHostTraceMarker(VkEncoder* encoder);
+ void sendGuestInfo(VkEncoder* encoder);
+
std::recursive_mutex mLock;
std::optional mCachedPhysicalDeviceMemoryProps;
diff --git a/src/virtio/virtio-gpu/virtgpu_gfxstream_protocol.h b/src/virtio/virtio-gpu/virtgpu_gfxstream_protocol.h
index 247fd4bb900..d35e0dbc363 100644
--- a/src/virtio/virtio-gpu/virtgpu_gfxstream_protocol.h
+++ b/src/virtio/virtio-gpu/virtgpu_gfxstream_protocol.h
@@ -107,6 +107,7 @@ struct vulkanCapset {
uint32_t virglSupportedFormats[16];
uint32_t vulkanBatchedDescriptorSetUpdate;
uint32_t hasTraceAsyncCommand;
+ uint32_t hasSetMetadataCommand;
};
struct magmaCapset {