[vulkan] deferred command buffers (guest)
bug: 111137294
When we get "ANDROID_EMU_deferred_vulkan_commands" in the
renderControl string from the host, enable
deferred command buffer recording, where we
avoid a round trip + immediate recording on
vkBegin/End/ResetCommandBuffer; this has the effect of
delaying command submission to the next round trip, which
is no later than when these commands are submitted.
To the guest, command recording will feel much faster.
It is true that we will end up delaying command buffer submission
on host until the next vkQueueSubmit; however, it may work out,
because we can record + submit on the host with possibly less
scheduling overhead than before.
Test: glmark2 ANGLE score rose from high 400s-500s to 600s
Change-Id: Ib76be4de05c768d395135ad2c9525d3e156daf31
diff --git a/system/vulkan/func_table.cpp b/system/vulkan/func_table.cpp
index 3248d76..14c8c32 100644
--- a/system/vulkan/func_table.cpp
+++ b/system/vulkan/func_table.cpp
@@ -1021,7 +1021,8 @@
AEMU_SCOPED_TRACE("vkBeginCommandBuffer");
auto vkEnc = HostConnection::get()->vkEncoder();
VkResult vkBeginCommandBuffer_VkResult_return = (VkResult)0;
- vkBeginCommandBuffer_VkResult_return = vkEnc->vkBeginCommandBuffer(commandBuffer, pBeginInfo);
+ auto resources = ResourceTracker::get();
+ vkBeginCommandBuffer_VkResult_return = resources->on_vkBeginCommandBuffer(vkEnc, VK_SUCCESS, commandBuffer, pBeginInfo);
return vkBeginCommandBuffer_VkResult_return;
}
static VkResult entry_vkEndCommandBuffer(
@@ -1030,7 +1031,8 @@
AEMU_SCOPED_TRACE("vkEndCommandBuffer");
auto vkEnc = HostConnection::get()->vkEncoder();
VkResult vkEndCommandBuffer_VkResult_return = (VkResult)0;
- vkEndCommandBuffer_VkResult_return = vkEnc->vkEndCommandBuffer(commandBuffer);
+ auto resources = ResourceTracker::get();
+ vkEndCommandBuffer_VkResult_return = resources->on_vkEndCommandBuffer(vkEnc, VK_SUCCESS, commandBuffer);
return vkEndCommandBuffer_VkResult_return;
}
static VkResult entry_vkResetCommandBuffer(
@@ -1040,7 +1042,8 @@
AEMU_SCOPED_TRACE("vkResetCommandBuffer");
auto vkEnc = HostConnection::get()->vkEncoder();
VkResult vkResetCommandBuffer_VkResult_return = (VkResult)0;
- vkResetCommandBuffer_VkResult_return = vkEnc->vkResetCommandBuffer(commandBuffer, flags);
+ auto resources = ResourceTracker::get();
+ vkResetCommandBuffer_VkResult_return = resources->on_vkResetCommandBuffer(vkEnc, VK_SUCCESS, commandBuffer, flags);
return vkResetCommandBuffer_VkResult_return;
}
static void entry_vkCmdBindPipeline(
@@ -3727,6 +3730,31 @@
vkEnc->vkUpdateDescriptorSetWithTemplateSizedGOOGLE(device, descriptorSet, descriptorUpdateTemplate, imageInfoCount, bufferInfoCount, bufferViewCount, pImageInfoEntryIndices, pBufferInfoEntryIndices, pBufferViewEntryIndices, pImageInfos, pBufferInfos, pBufferViews);
}
#endif
+#ifdef VK_GOOGLE_async_command_buffers
+static void entry_vkBeginCommandBufferAsyncGOOGLE(
+ VkCommandBuffer commandBuffer,
+ const VkCommandBufferBeginInfo* pBeginInfo)
+{
+ AEMU_SCOPED_TRACE("vkBeginCommandBufferAsyncGOOGLE");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkBeginCommandBufferAsyncGOOGLE(commandBuffer, pBeginInfo);
+}
+static void entry_vkEndCommandBufferAsyncGOOGLE(
+ VkCommandBuffer commandBuffer)
+{
+ AEMU_SCOPED_TRACE("vkEndCommandBufferAsyncGOOGLE");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkEndCommandBufferAsyncGOOGLE(commandBuffer);
+}
+static void entry_vkResetCommandBufferAsyncGOOGLE(
+ VkCommandBuffer commandBuffer,
+ VkCommandBufferResetFlags flags)
+{
+ AEMU_SCOPED_TRACE("vkResetCommandBufferAsyncGOOGLE");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkResetCommandBufferAsyncGOOGLE(commandBuffer, flags);
+}
+#endif
void* goldfish_vulkan_get_proc_address(const char* name){
#ifdef VK_VERSION_1_0
if (!strcmp(name, "vkCreateInstance"))
@@ -5144,6 +5172,20 @@
return nullptr;
}
#endif
+#ifdef VK_GOOGLE_async_command_buffers
+ if (!strcmp(name, "vkBeginCommandBufferAsyncGOOGLE"))
+ {
+ return nullptr;
+ }
+ if (!strcmp(name, "vkEndCommandBufferAsyncGOOGLE"))
+ {
+ return nullptr;
+ }
+ if (!strcmp(name, "vkResetCommandBufferAsyncGOOGLE"))
+ {
+ return nullptr;
+ }
+#endif
return nullptr;
}
void* goldfish_vulkan_get_instance_proc_address(VkInstance instance, const char* name){
@@ -6721,6 +6763,23 @@
return hasExt ? (void*)entry_vkUpdateDescriptorSetWithTemplateSizedGOOGLE : nullptr;
}
#endif
+#ifdef VK_GOOGLE_async_command_buffers
+ if (!strcmp(name, "vkBeginCommandBufferAsyncGOOGLE"))
+ {
+ bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_async_command_buffers");
+ return hasExt ? (void*)entry_vkBeginCommandBufferAsyncGOOGLE : nullptr;
+ }
+ if (!strcmp(name, "vkEndCommandBufferAsyncGOOGLE"))
+ {
+ bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_async_command_buffers");
+ return hasExt ? (void*)entry_vkEndCommandBufferAsyncGOOGLE : nullptr;
+ }
+ if (!strcmp(name, "vkResetCommandBufferAsyncGOOGLE"))
+ {
+ bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_async_command_buffers");
+ return hasExt ? (void*)entry_vkResetCommandBufferAsyncGOOGLE : nullptr;
+ }
+#endif
return nullptr;
}
void* goldfish_vulkan_get_device_proc_address(VkDevice device, const char* name){
@@ -8298,6 +8357,23 @@
return hasExt ? (void*)entry_vkUpdateDescriptorSetWithTemplateSizedGOOGLE : nullptr;
}
#endif
+#ifdef VK_GOOGLE_async_command_buffers
+ if (!strcmp(name, "vkBeginCommandBufferAsyncGOOGLE"))
+ {
+ bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_async_command_buffers");
+ return hasExt ? (void*)entry_vkBeginCommandBufferAsyncGOOGLE : nullptr;
+ }
+ if (!strcmp(name, "vkEndCommandBufferAsyncGOOGLE"))
+ {
+ bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_async_command_buffers");
+ return hasExt ? (void*)entry_vkEndCommandBufferAsyncGOOGLE : nullptr;
+ }
+ if (!strcmp(name, "vkResetCommandBufferAsyncGOOGLE"))
+ {
+ bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_async_command_buffers");
+ return hasExt ? (void*)entry_vkResetCommandBufferAsyncGOOGLE : nullptr;
+ }
+#endif
return nullptr;
}