[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_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index a26ed5b..a723a72 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -584,6 +584,11 @@
return mHostVisibleMemoryVirtInfo.virtualizationSupported;
}
+ bool supportsDeferredCommands() const {
+ if (!mFeatureInfo) return false;
+ return mFeatureInfo->hasDeferredVulkanCommands;
+ }
+
int getHostInstanceExtensionIndex(const std::string& extName) const {
int i = 0;
for (const auto& prop : mHostInstanceExtensions) {
@@ -3075,6 +3080,53 @@
physicalDevice, pImageFormatInfo, pImageFormatProperties);
}
+ VkResult on_vkBeginCommandBuffer(
+ void* context, VkResult input_result,
+ VkCommandBuffer commandBuffer,
+ const VkCommandBufferBeginInfo* pBeginInfo) {
+
+ VkEncoder* enc = (VkEncoder*)context;
+ (void)input_result;
+
+ if (!supportsDeferredCommands()) {
+ return enc->vkBeginCommandBuffer(commandBuffer, pBeginInfo);
+ }
+
+ enc->vkBeginCommandBufferAsyncGOOGLE(commandBuffer, pBeginInfo);
+ return VK_SUCCESS;
+ }
+
+ VkResult on_vkEndCommandBuffer(
+ void* context, VkResult input_result,
+ VkCommandBuffer commandBuffer) {
+
+ VkEncoder* enc = (VkEncoder*)context;
+ (void)input_result;
+
+ if (!supportsDeferredCommands()) {
+ return enc->vkEndCommandBuffer(commandBuffer);
+ }
+
+ enc->vkEndCommandBufferAsyncGOOGLE(commandBuffer);
+ return VK_SUCCESS;
+ }
+
+ VkResult on_vkResetCommandBuffer(
+ void* context, VkResult input_result,
+ VkCommandBuffer commandBuffer,
+ VkCommandBufferResetFlags flags) {
+
+ VkEncoder* enc = (VkEncoder*)context;
+ (void)input_result;
+
+ if (!supportsDeferredCommands()) {
+ return enc->vkResetCommandBuffer(commandBuffer, flags);
+ }
+
+ enc->vkResetCommandBufferAsyncGOOGLE(commandBuffer, flags);
+ return VK_SUCCESS;
+ }
+
uint32_t getApiVersionFromInstance(VkInstance instance) const {
AutoLock lock(mLock);
uint32_t api = kMinApiVersion;
@@ -3693,6 +3745,29 @@
pImageFormatProperties);
}
+VkResult ResourceTracker::on_vkBeginCommandBuffer(
+ void* context, VkResult input_result,
+ VkCommandBuffer commandBuffer,
+ const VkCommandBufferBeginInfo* pBeginInfo) {
+ return mImpl->on_vkBeginCommandBuffer(
+ context, input_result, commandBuffer, pBeginInfo);
+}
+
+VkResult ResourceTracker::on_vkEndCommandBuffer(
+ void* context, VkResult input_result,
+ VkCommandBuffer commandBuffer) {
+ return mImpl->on_vkEndCommandBuffer(
+ context, input_result, commandBuffer);
+}
+
+VkResult ResourceTracker::on_vkResetCommandBuffer(
+ void* context, VkResult input_result,
+ VkCommandBuffer commandBuffer,
+ VkCommandBufferResetFlags flags) {
+ return mImpl->on_vkResetCommandBuffer(
+ context, input_result, commandBuffer, flags);
+}
+
void ResourceTracker::deviceMemoryTransform_tohost(
VkDeviceMemory* memory, uint32_t memoryCount,
VkDeviceSize* offset, uint32_t offsetCount,