diff --git a/src/gfxstream/codegen/scripts/cereal/decoder.py b/src/gfxstream/codegen/scripts/cereal/decoder.py
index bda453518bd..6396fffc835 100644
--- a/src/gfxstream/codegen/scripts/cereal/decoder.py
+++ b/src/gfxstream/codegen/scripts/cereal/decoder.py
@@ -791,6 +791,7 @@ custom_decodes = {
"vkGetMemoryHostAddressInfoGOOGLE" : emit_global_state_wrapped_decoding,
"vkGetBlobGOOGLE" : emit_global_state_wrapped_decoding,
"vkGetSemaphoreGOOGLE" : emit_global_state_wrapped_decoding,
+ "vkTraceAsyncGOOGLE" : emit_global_state_wrapped_decoding,
# Descriptor update templates
"vkCreateDescriptorUpdateTemplate" : emit_global_state_wrapped_decoding,
diff --git a/src/gfxstream/codegen/xml/vk_gfxstream.xml b/src/gfxstream/codegen/xml/vk_gfxstream.xml
index d1599b76d77..52fcc068782 100644
--- a/src/gfxstream/codegen/xml/vk_gfxstream.xml
+++ b/src/gfxstream/codegen/xml/vk_gfxstream.xml
@@ -239,7 +239,11 @@ specific entries.
VkResult vkGetSemaphoreGOOGLE
VkDevice device
VkSemaphore semaphore
- uint64_t syncId
+ uint64_t syncId
+
+
+ void vkTraceAsyncGOOGLE
+ uint64_t id
@@ -280,6 +284,7 @@ specific entries.
+
diff --git a/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp b/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp
index 66edc3f6a20..8efed4a409a 100644
--- a/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp
+++ b/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp
@@ -30,11 +30,24 @@
#include
#include
+#include
#include
#include
#include
#include
+#ifdef HAVE_PERFETTO
+#include
+
+#define GFXSTREAM_TRACE_DEFAULT_CATEGORY "gfxstream.default"
+
+PERFETTO_DEFINE_CATEGORIES(
+ perfetto::Category(GFXSTREAM_TRACE_DEFAULT_CATEGORY)
+ .SetDescription("Default events")
+ .SetTags("default"));
+
+#endif // HAVE_PERFETTO
+
#include "vk_util.h"
#if DETECT_OS_LINUX
@@ -78,8 +91,34 @@ static T vk_make_orphan_copy(const T& vk_struct) {
return copy;
}
+
namespace gfxstream {
namespace vk {
+namespace {
+
+uint64_t GeneratePseudoUniqueId() {
+ thread_local std::mt19937 generator(std::random_device{}());
+ std::uniform_int_distribution distribution(0, std::numeric_limits::max());
+ return distribution(generator);
+}
+
+void EmitGuestAndHostTraceMarker(VkEncoder* encoder) {
+#ifdef HAVE_PERFETTO
+ const uint64_t flowId = GeneratePseudoUniqueId();
+
+ TRACE_EVENT_INSTANT(
+ GFXSTREAM_TRACE_DEFAULT_CATEGORY,
+ "vkTraceAsyncGOOGLE",
+ perfetto::Flow::Global(flowId),
+ "flow id", flowId);
+
+ encoder->vkTraceAsyncGOOGLE(flowId, true /* do lock */);
+#else
+ (void)encoder;
+#endif // HAVE_PERFETTO
+}
+
+} // namespace
#define MAKE_HANDLE_MAPPING_FOREACH(type_name, map_impl, map_to_u64_impl, map_from_u64_impl) \
void mapHandles_##type_name(type_name* handles, size_t count) override { \
@@ -6219,6 +6258,7 @@ VkResult ResourceTracker::on_vkQueueSubmit(void* context, VkResult input_result,
uint32_t submitCount, const VkSubmitInfo* pSubmits,
VkFence fence) {
MESA_TRACE_SCOPE("on_vkQueueSubmit");
+ EmitGuestAndHostTraceMarker((VkEncoder*)context);
/* From the Vulkan 1.3.204 spec:
*
@@ -6256,6 +6296,7 @@ VkResult ResourceTracker::on_vkQueueSubmit2(void* context, VkResult input_result
uint32_t submitCount, const VkSubmitInfo2* pSubmits,
VkFence fence) {
MESA_TRACE_SCOPE("on_vkQueueSubmit2");
+ EmitGuestAndHostTraceMarker((VkEncoder*)context);
return on_vkQueueSubmitTemplate(context, input_result, queue, submitCount,
pSubmits, fence);
}
diff --git a/src/gfxstream/guest/vulkan_enc/VkEncoder.cpp b/src/gfxstream/guest/vulkan_enc/VkEncoder.cpp
index 2b1604e0b55..7756d815b34 100644
--- a/src/gfxstream/guest/vulkan_enc/VkEncoder.cpp
+++ b/src/gfxstream/guest/vulkan_enc/VkEncoder.cpp
@@ -27705,6 +27705,47 @@ VkResult VkEncoder::vkGetSemaphoreGOOGLE(VkDevice device, VkSemaphore semaphore,
return vkGetSemaphoreGOOGLE_VkResult_return;
}
+void VkEncoder::vkTraceAsyncGOOGLE(uint64_t id, uint32_t doLock) {
+ (void)doLock;
+ bool queueSubmitWithCommandsEnabled =
+ sFeatureBits & VULKAN_STREAM_FEATURE_QUEUE_SUBMIT_WITH_COMMANDS_BIT;
+ if (!queueSubmitWithCommandsEnabled && doLock) this->lock();
+ auto stream = mImpl->stream();
+ auto pool = mImpl->pool();
+ uint64_t local_id;
+ local_id = id;
+ size_t count = 0;
+ size_t* countPtr = &count;
+ {
+ *countPtr += sizeof(uint64_t);
+ }
+ uint32_t packetSize_vkTraceAsyncGOOGLE =
+ 4 + 4 + (queueSubmitWithCommandsEnabled ? 4 : 0) + count;
+ uint8_t* streamPtr = stream->reserve(packetSize_vkTraceAsyncGOOGLE);
+ uint8_t* packetBeginPtr = streamPtr;
+ uint8_t** streamPtrPtr = &streamPtr;
+ uint32_t opcode_vkTraceAsyncGOOGLE = OP_vkTraceAsyncGOOGLE;
+ uint32_t seqno;
+ if (queueSubmitWithCommandsEnabled) seqno = ResourceTracker::nextSeqno();
+ memcpy(streamPtr, &opcode_vkTraceAsyncGOOGLE, sizeof(uint32_t));
+ streamPtr += sizeof(uint32_t);
+ memcpy(streamPtr, &packetSize_vkTraceAsyncGOOGLE, sizeof(uint32_t));
+ streamPtr += sizeof(uint32_t);
+ if (queueSubmitWithCommandsEnabled) {
+ memcpy(streamPtr, &seqno, sizeof(uint32_t));
+ streamPtr += sizeof(uint32_t);
+ }
+ memcpy(*streamPtrPtr, (uint64_t*)&local_id, sizeof(uint64_t));
+ *streamPtrPtr += sizeof(uint64_t);
+ stream->flush();
+ ++encodeCount;
+ if (0 == encodeCount % POOL_CLEAR_INTERVAL) {
+ pool->freeAll();
+ stream->clearPool();
+ }
+ if (!queueSubmitWithCommandsEnabled && doLock) this->unlock();
+}
+
#endif
} // namespace vk
} // namespace gfxstream
diff --git a/src/gfxstream/guest/vulkan_enc/VkEncoder.h b/src/gfxstream/guest/vulkan_enc/VkEncoder.h
index a69b165a073..4367e96bc05 100644
--- a/src/gfxstream/guest/vulkan_enc/VkEncoder.h
+++ b/src/gfxstream/guest/vulkan_enc/VkEncoder.h
@@ -1086,6 +1086,7 @@ class VkEncoder {
const VkSubmitInfo2* pSubmits, VkFence fence, uint32_t doLock);
VkResult vkGetSemaphoreGOOGLE(VkDevice device, VkSemaphore semaphore, uint64_t syncId,
uint32_t doLock);
+ void vkTraceAsyncGOOGLE(uint64_t id, uint32_t doLock);
#endif
private:
class Impl;
diff --git a/src/gfxstream/guest/vulkan_enc/func_table.cpp b/src/gfxstream/guest/vulkan_enc/func_table.cpp
index c91c63c00a4..b28b4fe10c3 100644
--- a/src/gfxstream/guest/vulkan_enc/func_table.cpp
+++ b/src/gfxstream/guest/vulkan_enc/func_table.cpp
@@ -5210,4 +5210,11 @@ VkResult gfxstream_vk_GetSemaphoreGOOGLE(VkDevice device, VkSemaphore semaphore,
}
return vkGetSemaphoreGOOGLE_VkResult_return;
}
+void gfxstream_vk_TraceAsyncGOOGLE(uint64_t id) {
+ MESA_TRACE_SCOPE("vkTraceAsyncGOOGLE");
+ {
+ auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+ vkEnc->vkTraceAsyncGOOGLE(id, true /* do lock */);
+ }
+}
#endif
diff --git a/src/gfxstream/guest/vulkan_enc/goldfish_vk_marshaling_guest.cpp b/src/gfxstream/guest/vulkan_enc/goldfish_vk_marshaling_guest.cpp
index d19954c0516..9b1d6b3ac49 100644
--- a/src/gfxstream/guest/vulkan_enc/goldfish_vk_marshaling_guest.cpp
+++ b/src/gfxstream/guest/vulkan_enc/goldfish_vk_marshaling_guest.cpp
@@ -18663,6 +18663,11 @@ const char* api_opcode_to_string(const uint32_t opcode) {
return "OP_vkCmdSetStencilTestEnableEXT";
}
#endif
+#ifdef VK_GOOGLE_gfxstream
+ case OP_vkTraceAsyncGOOGLE: {
+ return "OP_vkTraceAsyncGOOGLE";
+ }
+#endif
#ifdef VK_VERSION_1_3
case OP_vkCmdSetStencilTestEnable: {
return "OP_vkCmdSetStencilTestEnable";
diff --git a/src/gfxstream/guest/vulkan_enc/goldfish_vk_marshaling_guest.h b/src/gfxstream/guest/vulkan_enc/goldfish_vk_marshaling_guest.h
index 7b52407bedf..43c76cd131b 100644
--- a/src/gfxstream/guest/vulkan_enc/goldfish_vk_marshaling_guest.h
+++ b/src/gfxstream/guest/vulkan_enc/goldfish_vk_marshaling_guest.h
@@ -4170,6 +4170,7 @@ void unmarshal_VkCreateBlobGOOGLE(VulkanStreamGuest* vkStream, VkStructureType r
#define OP_vkUpdateDescriptorSetWithTemplateSized2GOOGLE 244782974
#define OP_vkQueueSubmitAsync2GOOGLE 292092830
#define OP_vkGetSemaphoreGOOGLE 20342
+#define OP_vkTraceAsyncGOOGLE 286553566
#endif
#ifdef VK_EXT_image_compression_control_swapchain
void marshal_VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT(
diff --git a/src/gfxstream/guest/vulkan_enc/vulkan_gfxstream.h b/src/gfxstream/guest/vulkan_enc/vulkan_gfxstream.h
index 82a90d458e8..e21042a4447 100644
--- a/src/gfxstream/guest/vulkan_enc/vulkan_gfxstream.h
+++ b/src/gfxstream/guest/vulkan_enc/vulkan_gfxstream.h
@@ -70,6 +70,7 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetBlobGOOGLE)(VkDevice device, VkDeviceMemor
typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplateSized2GOOGLE)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, uint32_t imageInfoCount, uint32_t bufferInfoCount, uint32_t bufferViewCount, uint32_t inlineUniformBlockCount, const uint32_t* pImageInfoEntryIndices, const uint32_t* pBufferInfoEntryIndices, const uint32_t* pBufferViewEntryIndices, const VkDescriptorImageInfo* pImageInfos, const VkDescriptorBufferInfo* pBufferInfos, const VkBufferView* pBufferViews, const uint8_t* pInlineUniformBlockData);
typedef void (VKAPI_PTR *PFN_vkQueueSubmitAsync2GOOGLE)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence);
typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreGOOGLE)(VkDevice device, VkSemaphore semaphore, uint64_t syncId);
+typedef void (VKAPI_PTR *PFN_vkTraceAsyncGOOGLE)(uint64_t id);
VKAPI_ATTR VkResult VKAPI_CALL vkMapMemoryIntoAddressSpaceGOOGLE(
VkDevice device,
@@ -233,6 +234,9 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreGOOGLE(
VkSemaphore semaphore,
uint64_t syncId);
+VKAPI_ATTR void VKAPI_CALL vkTraceAsyncGOOGLE(
+ uint64_t id);
+
#ifdef __cplusplus
}
#endif