[vulkan] Maintain order of begin/end command buffer in deferred mode
bug: 135464985
If we record command buffers in async mode (no return from
vkBegin/EndCommandBuffer) in several guest threads,
it's possible the commands end up out of order when they arrive on the
host, leading to cool bugs.
To ensure the order when async mode is active, we use a special command
vkCommandBufferHostSyncGOOGLE
when the guest thread used to record to a command buffer switches.
Two issues of vkCommandBufferHostSyncGOOGLE are done:
1. The previous encoder issues vkCommandBufferHostSyncGOOGLE with the
previous sequence number.
2. The current encoder issues vkCommandBufferHostSyncGOOGLE with the
incremented sequence number along with a flag to wait on the host for
the vkCommandBufferHostSyncGOOGLE with the previous sequence number.
3. If the previous encoder is destroyed, we register a cleanup callback
that updates the pointer accordingly, so that we dont perform a stale
access.
By introducing this new command, we can then record command buffers
completely async and avoid having to add sequence numbers
to every command buffer recording API.
Note: We previously explored a solution where all command buffer
recording to be in one pipe, to implicitly accomplish ordering of
command buffer APIs. However, that turned out to be extremely difficult
to synchronize with other Vulkan APIs that were not concerned with
command buffer recording, as they could and sometimes need to run in
their separate threads.
Change-Id: I093be0a1600f22e0a355536d1671acdce3852541
diff --git a/system/vulkan/func_table.cpp b/system/vulkan/func_table.cpp
index f5b380e..f0ed982 100644
--- a/system/vulkan/func_table.cpp
+++ b/system/vulkan/func_table.cpp
@@ -1021,6 +1021,7 @@
{
AEMU_SCOPED_TRACE("vkBeginCommandBuffer");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
VkResult vkBeginCommandBuffer_VkResult_return = (VkResult)0;
auto resources = ResourceTracker::get();
vkBeginCommandBuffer_VkResult_return = resources->on_vkBeginCommandBuffer(vkEnc, VK_SUCCESS, commandBuffer, pBeginInfo);
@@ -1031,6 +1032,7 @@
{
AEMU_SCOPED_TRACE("vkEndCommandBuffer");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
VkResult vkEndCommandBuffer_VkResult_return = (VkResult)0;
auto resources = ResourceTracker::get();
vkEndCommandBuffer_VkResult_return = resources->on_vkEndCommandBuffer(vkEnc, VK_SUCCESS, commandBuffer);
@@ -1042,6 +1044,7 @@
{
AEMU_SCOPED_TRACE("vkResetCommandBuffer");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
VkResult vkResetCommandBuffer_VkResult_return = (VkResult)0;
auto resources = ResourceTracker::get();
vkResetCommandBuffer_VkResult_return = resources->on_vkResetCommandBuffer(vkEnc, VK_SUCCESS, commandBuffer, flags);
@@ -1054,6 +1057,7 @@
{
AEMU_SCOPED_TRACE("vkCmdBindPipeline");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
}
static void entry_vkCmdSetViewport(
@@ -1064,6 +1068,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetViewport");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
}
static void entry_vkCmdSetScissor(
@@ -1074,6 +1079,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetScissor");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
}
static void entry_vkCmdSetLineWidth(
@@ -1082,6 +1088,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetLineWidth");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetLineWidth(commandBuffer, lineWidth);
}
static void entry_vkCmdSetDepthBias(
@@ -1092,6 +1099,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetDepthBias");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
}
static void entry_vkCmdSetBlendConstants(
@@ -1100,6 +1108,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetBlendConstants");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetBlendConstants(commandBuffer, blendConstants);
}
static void entry_vkCmdSetDepthBounds(
@@ -1109,6 +1118,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetDepthBounds");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds);
}
static void entry_vkCmdSetStencilCompareMask(
@@ -1118,6 +1128,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetStencilCompareMask");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetStencilCompareMask(commandBuffer, faceMask, compareMask);
}
static void entry_vkCmdSetStencilWriteMask(
@@ -1127,6 +1138,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetStencilWriteMask");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetStencilWriteMask(commandBuffer, faceMask, writeMask);
}
static void entry_vkCmdSetStencilReference(
@@ -1136,6 +1148,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetStencilReference");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetStencilReference(commandBuffer, faceMask, reference);
}
static void entry_vkCmdBindDescriptorSets(
@@ -1150,6 +1163,7 @@
{
AEMU_SCOPED_TRACE("vkCmdBindDescriptorSets");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
}
static void entry_vkCmdBindIndexBuffer(
@@ -1160,6 +1174,7 @@
{
AEMU_SCOPED_TRACE("vkCmdBindIndexBuffer");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdBindIndexBuffer(commandBuffer, buffer, offset, indexType);
}
static void entry_vkCmdBindVertexBuffers(
@@ -1171,6 +1186,7 @@
{
AEMU_SCOPED_TRACE("vkCmdBindVertexBuffers");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
}
static void entry_vkCmdDraw(
@@ -1182,6 +1198,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDraw");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
}
static void entry_vkCmdDrawIndexed(
@@ -1194,6 +1211,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDrawIndexed");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
}
static void entry_vkCmdDrawIndirect(
@@ -1205,6 +1223,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDrawIndirect");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDrawIndirect(commandBuffer, buffer, offset, drawCount, stride);
}
static void entry_vkCmdDrawIndexedIndirect(
@@ -1216,6 +1235,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDrawIndexedIndirect");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDrawIndexedIndirect(commandBuffer, buffer, offset, drawCount, stride);
}
static void entry_vkCmdDispatch(
@@ -1226,6 +1246,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDispatch");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDispatch(commandBuffer, groupCountX, groupCountY, groupCountZ);
}
static void entry_vkCmdDispatchIndirect(
@@ -1235,6 +1256,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDispatchIndirect");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDispatchIndirect(commandBuffer, buffer, offset);
}
static void entry_vkCmdCopyBuffer(
@@ -1246,6 +1268,7 @@
{
AEMU_SCOPED_TRACE("vkCmdCopyBuffer");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
}
static void entry_vkCmdCopyImage(
@@ -1259,6 +1282,7 @@
{
AEMU_SCOPED_TRACE("vkCmdCopyImage");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
}
static void entry_vkCmdBlitImage(
@@ -1273,6 +1297,7 @@
{
AEMU_SCOPED_TRACE("vkCmdBlitImage");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
}
static void entry_vkCmdCopyBufferToImage(
@@ -1285,6 +1310,7 @@
{
AEMU_SCOPED_TRACE("vkCmdCopyBufferToImage");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
}
static void entry_vkCmdCopyImageToBuffer(
@@ -1297,6 +1323,7 @@
{
AEMU_SCOPED_TRACE("vkCmdCopyImageToBuffer");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
}
static void entry_vkCmdUpdateBuffer(
@@ -1308,6 +1335,7 @@
{
AEMU_SCOPED_TRACE("vkCmdUpdateBuffer");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
}
static void entry_vkCmdFillBuffer(
@@ -1319,6 +1347,7 @@
{
AEMU_SCOPED_TRACE("vkCmdFillBuffer");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
}
static void entry_vkCmdClearColorImage(
@@ -1331,6 +1360,7 @@
{
AEMU_SCOPED_TRACE("vkCmdClearColorImage");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
}
static void entry_vkCmdClearDepthStencilImage(
@@ -1343,6 +1373,7 @@
{
AEMU_SCOPED_TRACE("vkCmdClearDepthStencilImage");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
}
static void entry_vkCmdClearAttachments(
@@ -1354,6 +1385,7 @@
{
AEMU_SCOPED_TRACE("vkCmdClearAttachments");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects);
}
static void entry_vkCmdResolveImage(
@@ -1367,6 +1399,7 @@
{
AEMU_SCOPED_TRACE("vkCmdResolveImage");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
}
static void entry_vkCmdSetEvent(
@@ -1376,6 +1409,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetEvent");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetEvent(commandBuffer, event, stageMask);
}
static void entry_vkCmdResetEvent(
@@ -1385,6 +1419,7 @@
{
AEMU_SCOPED_TRACE("vkCmdResetEvent");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdResetEvent(commandBuffer, event, stageMask);
}
static void entry_vkCmdWaitEvents(
@@ -1402,6 +1437,7 @@
{
AEMU_SCOPED_TRACE("vkCmdWaitEvents");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdWaitEvents(commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
}
static void entry_vkCmdPipelineBarrier(
@@ -1418,6 +1454,7 @@
{
AEMU_SCOPED_TRACE("vkCmdPipelineBarrier");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
}
static void entry_vkCmdBeginQuery(
@@ -1428,6 +1465,7 @@
{
AEMU_SCOPED_TRACE("vkCmdBeginQuery");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdBeginQuery(commandBuffer, queryPool, query, flags);
}
static void entry_vkCmdEndQuery(
@@ -1437,6 +1475,7 @@
{
AEMU_SCOPED_TRACE("vkCmdEndQuery");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdEndQuery(commandBuffer, queryPool, query);
}
static void entry_vkCmdResetQueryPool(
@@ -1447,6 +1486,7 @@
{
AEMU_SCOPED_TRACE("vkCmdResetQueryPool");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount);
}
static void entry_vkCmdWriteTimestamp(
@@ -1457,6 +1497,7 @@
{
AEMU_SCOPED_TRACE("vkCmdWriteTimestamp");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, query);
}
static void entry_vkCmdCopyQueryPoolResults(
@@ -1471,6 +1512,7 @@
{
AEMU_SCOPED_TRACE("vkCmdCopyQueryPoolResults");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
}
static void entry_vkCmdPushConstants(
@@ -1483,6 +1525,7 @@
{
AEMU_SCOPED_TRACE("vkCmdPushConstants");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues);
}
static void entry_vkCmdBeginRenderPass(
@@ -1492,6 +1535,7 @@
{
AEMU_SCOPED_TRACE("vkCmdBeginRenderPass");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
}
static void entry_vkCmdNextSubpass(
@@ -1500,6 +1544,7 @@
{
AEMU_SCOPED_TRACE("vkCmdNextSubpass");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdNextSubpass(commandBuffer, contents);
}
static void entry_vkCmdEndRenderPass(
@@ -1507,6 +1552,7 @@
{
AEMU_SCOPED_TRACE("vkCmdEndRenderPass");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdEndRenderPass(commandBuffer);
}
static void entry_vkCmdExecuteCommands(
@@ -1516,6 +1562,7 @@
{
AEMU_SCOPED_TRACE("vkCmdExecuteCommands");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdExecuteCommands(commandBuffer, commandBufferCount, pCommandBuffers);
}
#endif
@@ -1570,6 +1617,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetDeviceMask");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetDeviceMask(commandBuffer, deviceMask);
}
static void entry_vkCmdDispatchBase(
@@ -1583,6 +1631,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDispatchBase");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
}
static VkResult entry_vkEnumeratePhysicalDeviceGroups(
@@ -2288,6 +2337,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetDeviceMaskKHR");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetDeviceMaskKHR(commandBuffer, deviceMask);
}
static void entry_vkCmdDispatchBaseKHR(
@@ -2301,6 +2351,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDispatchBaseKHR");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
}
#endif
@@ -2467,6 +2518,7 @@
{
AEMU_SCOPED_TRACE("vkCmdPushDescriptorSetKHR");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdPushDescriptorSetKHR(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount, pDescriptorWrites);
}
static void entry_vkCmdPushDescriptorSetWithTemplateKHR(
@@ -2478,6 +2530,7 @@
{
AEMU_SCOPED_TRACE("vkCmdPushDescriptorSetWithTemplateKHR");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set, pData);
}
#endif
@@ -2538,6 +2591,7 @@
{
AEMU_SCOPED_TRACE("vkCmdBeginRenderPass2KHR");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdBeginRenderPass2KHR(commandBuffer, pRenderPassBegin, pSubpassBeginInfo);
}
static void entry_vkCmdNextSubpass2KHR(
@@ -2547,6 +2601,7 @@
{
AEMU_SCOPED_TRACE("vkCmdNextSubpass2KHR");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdNextSubpass2KHR(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo);
}
static void entry_vkCmdEndRenderPass2KHR(
@@ -2555,6 +2610,7 @@
{
AEMU_SCOPED_TRACE("vkCmdEndRenderPass2KHR");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdEndRenderPass2KHR(commandBuffer, pSubpassEndInfo);
}
#endif
@@ -2818,6 +2874,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDrawIndirectCountKHR");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
}
static void entry_vkCmdDrawIndexedIndirectCountKHR(
@@ -2831,6 +2888,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDrawIndexedIndirectCountKHR");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
}
#endif
@@ -2952,6 +3010,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDebugMarkerBeginEXT");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDebugMarkerBeginEXT(commandBuffer, pMarkerInfo);
}
static void entry_vkCmdDebugMarkerEndEXT(
@@ -2959,6 +3018,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDebugMarkerEndEXT");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDebugMarkerEndEXT(commandBuffer);
}
static void entry_vkCmdDebugMarkerInsertEXT(
@@ -2967,6 +3027,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDebugMarkerInsertEXT");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDebugMarkerInsertEXT(commandBuffer, pMarkerInfo);
}
#endif
@@ -2986,6 +3047,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDrawIndirectCountAMD");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDrawIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
}
static void entry_vkCmdDrawIndexedIndirectCountAMD(
@@ -2999,6 +3061,7 @@
{
AEMU_SCOPED_TRACE("vkCmdDrawIndexedIndirectCountAMD");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdDrawIndexedIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
}
#endif
@@ -3093,6 +3156,7 @@
{
AEMU_SCOPED_TRACE("vkCmdBeginConditionalRenderingEXT");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdBeginConditionalRenderingEXT(commandBuffer, pConditionalRenderingBegin);
}
static void entry_vkCmdEndConditionalRenderingEXT(
@@ -3100,6 +3164,7 @@
{
AEMU_SCOPED_TRACE("vkCmdEndConditionalRenderingEXT");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdEndConditionalRenderingEXT(commandBuffer);
}
#endif
@@ -3110,6 +3175,7 @@
{
AEMU_SCOPED_TRACE("vkCmdProcessCommandsNVX");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdProcessCommandsNVX(commandBuffer, pProcessCommandsInfo);
}
static void entry_vkCmdReserveSpaceForCommandsNVX(
@@ -3118,6 +3184,7 @@
{
AEMU_SCOPED_TRACE("vkCmdReserveSpaceForCommandsNVX");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdReserveSpaceForCommandsNVX(commandBuffer, pReserveSpaceInfo);
}
static VkResult entry_vkCreateIndirectCommandsLayoutNVX(
@@ -3207,6 +3274,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetViewportWScalingNV");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetViewportWScalingNV(commandBuffer, firstViewport, viewportCount, pViewportWScalings);
}
#endif
@@ -3354,6 +3422,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetDiscardRectangleEXT");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetDiscardRectangleEXT(commandBuffer, firstDiscardRectangle, discardRectangleCount, pDiscardRectangles);
}
#endif
@@ -3455,6 +3524,7 @@
{
AEMU_SCOPED_TRACE("vkCmdBeginDebugUtilsLabelEXT");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdBeginDebugUtilsLabelEXT(commandBuffer, pLabelInfo);
}
static void entry_vkCmdEndDebugUtilsLabelEXT(
@@ -3462,6 +3532,7 @@
{
AEMU_SCOPED_TRACE("vkCmdEndDebugUtilsLabelEXT");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdEndDebugUtilsLabelEXT(commandBuffer);
}
static void entry_vkCmdInsertDebugUtilsLabelEXT(
@@ -3470,6 +3541,7 @@
{
AEMU_SCOPED_TRACE("vkCmdInsertDebugUtilsLabelEXT");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdInsertDebugUtilsLabelEXT(commandBuffer, pLabelInfo);
}
static VkResult entry_vkCreateDebugUtilsMessengerEXT(
@@ -3547,6 +3619,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetSampleLocationsEXT");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetSampleLocationsEXT(commandBuffer, pSampleLocationsInfo);
}
static void entry_vkGetPhysicalDeviceMultisamplePropertiesEXT(
@@ -3646,6 +3719,7 @@
{
AEMU_SCOPED_TRACE("vkCmdWriteBufferMarkerAMD");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdWriteBufferMarkerAMD(commandBuffer, pipelineStage, dstBuffer, dstOffset, marker);
}
#endif
@@ -3662,6 +3736,7 @@
{
AEMU_SCOPED_TRACE("vkCmdSetCheckpointNV");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkCmdSetCheckpointNV(commandBuffer, pCheckpointMarker);
}
static void entry_vkGetQueueCheckpointDataNV(
@@ -3738,6 +3813,7 @@
{
AEMU_SCOPED_TRACE("vkBeginCommandBufferAsyncGOOGLE");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkBeginCommandBufferAsyncGOOGLE(commandBuffer, pBeginInfo);
}
static void entry_vkEndCommandBufferAsyncGOOGLE(
@@ -3745,6 +3821,7 @@
{
AEMU_SCOPED_TRACE("vkEndCommandBufferAsyncGOOGLE");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkEndCommandBufferAsyncGOOGLE(commandBuffer);
}
static void entry_vkResetCommandBufferAsyncGOOGLE(
@@ -3753,8 +3830,19 @@
{
AEMU_SCOPED_TRACE("vkResetCommandBufferAsyncGOOGLE");
auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
vkEnc->vkResetCommandBufferAsyncGOOGLE(commandBuffer, flags);
}
+static void entry_vkCommandBufferHostSyncGOOGLE(
+ VkCommandBuffer commandBuffer,
+ uint32_t needHostSync,
+ uint32_t sequenceNumber)
+{
+ AEMU_SCOPED_TRACE("vkCommandBufferHostSyncGOOGLE");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, vkEnc);
+ vkEnc->vkCommandBufferHostSyncGOOGLE(commandBuffer, needHostSync, sequenceNumber);
+}
#endif
void* goldfish_vulkan_get_proc_address(const char* name){
#ifdef VK_VERSION_1_0
@@ -5186,6 +5274,10 @@
{
return nullptr;
}
+ if (!strcmp(name, "vkCommandBufferHostSyncGOOGLE"))
+ {
+ return nullptr;
+ }
#endif
return nullptr;
}
@@ -6780,6 +6872,11 @@
bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_async_command_buffers");
return hasExt ? (void*)entry_vkResetCommandBufferAsyncGOOGLE : nullptr;
}
+ if (!strcmp(name, "vkCommandBufferHostSyncGOOGLE"))
+ {
+ bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_async_command_buffers");
+ return hasExt ? (void*)entry_vkCommandBufferHostSyncGOOGLE : nullptr;
+ }
#endif
return nullptr;
}
@@ -8374,6 +8471,11 @@
bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_async_command_buffers");
return hasExt ? (void*)entry_vkResetCommandBufferAsyncGOOGLE : nullptr;
}
+ if (!strcmp(name, "vkCommandBufferHostSyncGOOGLE"))
+ {
+ bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_async_command_buffers");
+ return hasExt ? (void*)entry_vkCommandBufferHostSyncGOOGLE : nullptr;
+ }
#endif
return nullptr;
}
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index d3bd3ff..9cd8a79 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -251,6 +251,11 @@
zx_handle_t vmoHandle = ZX_HANDLE_INVALID;
};
+ struct VkCommandBuffer_Info {
+ VkEncoder** lastUsedEncoderPtr = nullptr;
+ uint32_t sequenceNumber = 0;
+ };
+
// custom guest-side structs for images/buffers because of AHardwareBuffer :((
struct VkImage_Info {
VkDevice device;
@@ -326,6 +331,24 @@
lock.unlock();
}
+ void unregister_VkCommandBuffer(VkCommandBuffer commandBuffer) {
+ AutoLock lock(mLock);
+
+ auto it = info_VkCommandBuffer.find(commandBuffer);
+ if (it == info_VkCommandBuffer.end()) return;
+ auto& info = it->second;
+ auto lastUsedEncoder =
+ info.lastUsedEncoderPtr ?
+ *(info.lastUsedEncoderPtr) : nullptr;
+
+ if (lastUsedEncoder) {
+ lastUsedEncoder->unregisterCleanupCallback(commandBuffer);
+ delete info.lastUsedEncoderPtr;
+ }
+
+ info_VkCommandBuffer.erase(commandBuffer);
+ }
+
void unregister_VkDeviceMemory(VkDeviceMemory mem) {
AutoLock lock(mLock);
@@ -3058,6 +3081,48 @@
physicalDevice, pImageFormatInfo, pImageFormatProperties);
}
+ uint32_t syncEncodersForCommandBuffer(VkCommandBuffer commandBuffer, VkEncoder* currentEncoder) {
+ AutoLock lock(mLock);
+
+ auto it = info_VkCommandBuffer.find(commandBuffer);
+ if (it == info_VkCommandBuffer.end()) return 0;
+
+ auto& info = it->second;
+
+ if (!info.lastUsedEncoderPtr) {
+ info.lastUsedEncoderPtr = new VkEncoder*;
+ *(info.lastUsedEncoderPtr) = currentEncoder;
+ }
+
+ auto lastUsedEncoderPtr = info.lastUsedEncoderPtr;
+
+ auto lastEncoder = *(lastUsedEncoderPtr);
+
+ // We always make lastUsedEncoderPtr track
+ // the current encoder, even if the last encoder
+ // is null.
+ *(lastUsedEncoderPtr) = currentEncoder;
+
+ if (!lastEncoder) return 0;
+ if (lastEncoder == currentEncoder) return 0;
+
+ info.sequenceNumber++;
+ lastEncoder->vkCommandBufferHostSyncGOOGLE(commandBuffer, false, info.sequenceNumber);
+ lastEncoder->flush();
+ info.sequenceNumber++;
+ currentEncoder->vkCommandBufferHostSyncGOOGLE(commandBuffer, true, info.sequenceNumber);
+
+ lastEncoder->unregisterCleanupCallback(commandBuffer);
+
+ currentEncoder->registerCleanupCallback(commandBuffer, [currentEncoder, lastUsedEncoderPtr]() {
+ if (*(lastUsedEncoderPtr) == currentEncoder) {
+ *(lastUsedEncoderPtr) = nullptr;
+ }
+ });
+
+ return 1;
+ }
+
VkResult on_vkBeginCommandBuffer(
void* context, VkResult input_result,
VkCommandBuffer commandBuffer,
@@ -3071,6 +3136,7 @@
}
enc->vkBeginCommandBufferAsyncGOOGLE(commandBuffer, pBeginInfo);
+
return VK_SUCCESS;
}
@@ -3086,6 +3152,7 @@
}
enc->vkEndCommandBufferAsyncGOOGLE(commandBuffer);
+
return VK_SUCCESS;
}
@@ -3754,6 +3821,10 @@
pImageFormatProperties);
}
+uint32_t ResourceTracker::syncEncodersForCommandBuffer(VkCommandBuffer commandBuffer, VkEncoder* current) {
+ return mImpl->syncEncodersForCommandBuffer(commandBuffer, current);
+}
+
VkResult ResourceTracker::on_vkBeginCommandBuffer(
void* context, VkResult input_result,
VkCommandBuffer commandBuffer,
diff --git a/system/vulkan_enc/ResourceTracker.h b/system/vulkan_enc/ResourceTracker.h
index 0f26c46..8daf979 100644
--- a/system/vulkan_enc/ResourceTracker.h
+++ b/system/vulkan_enc/ResourceTracker.h
@@ -28,6 +28,8 @@
namespace goldfish_vk {
+class VkEncoder;
+
class ResourceTracker {
public:
ResourceTracker();
@@ -322,6 +324,8 @@
const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
VkImageFormatProperties2* pImageFormatProperties);
+ uint32_t syncEncodersForCommandBuffer(VkCommandBuffer commandBuffer, VkEncoder* current);
+
VkResult on_vkBeginCommandBuffer(
void* context, VkResult input_result,
VkCommandBuffer commandBuffer,
diff --git a/system/vulkan_enc/VkEncoder.cpp b/system/vulkan_enc/VkEncoder.cpp
index 2299823..732bd21 100644
--- a/system/vulkan_enc/VkEncoder.cpp
+++ b/system/vulkan_enc/VkEncoder.cpp
@@ -43,6 +43,9 @@
#include "goldfish_vk_private_defs.h"
#include "goldfish_vk_transform_guest.h"
+#include <unordered_map>
+
+
namespace goldfish_vk {
@@ -65,6 +68,14 @@
m_logEncodes = atoi(encodeProp) > 0;
}
}
+
+ ~Impl() {
+ for (auto it : mCleanupCallbacks) {
+ fprintf(stderr, "%s: run cleanup callback for %p\n", __func__, it.first);
+ it.second();
+ }
+ }
+
VulkanCountingStream* countingStream() { return &m_countingStream; }
VulkanStreamGuest* stream() { return &m_stream; }
Pool* pool() { return &m_pool; }
@@ -81,6 +92,15 @@
m_stream.flush();
}
+ // Assume the lock for the current encoder is held.
+ void registerCleanupCallback(void* handle, VkEncoder::CleanupCallback cb) {
+ mCleanupCallbacks.insert({handle, cb});
+ }
+
+ void unregisterCleanupCallback(void* handle) {
+ mCleanupCallbacks.erase(handle);
+ }
+
Lock lock;
private:
@@ -90,6 +110,8 @@
Validation m_validation;
bool m_logEncodes;
+
+ std::unordered_map<void*, VkEncoder::CleanupCallback> mCleanupCallbacks;
};
VkEncoder::VkEncoder(IOStream *stream) :
@@ -99,6 +121,14 @@
mImpl->flush();
}
+void VkEncoder::registerCleanupCallback(void* handle, VkEncoder::CleanupCallback cb) {
+ mImpl->registerCleanupCallback(handle, cb);
+}
+
+void VkEncoder::unregisterCleanupCallback(void* handle) {
+ mImpl->unregisterCleanupCallback(handle);
+}
+
#define VALIDATE_RET(retType, success, validate) \
retType goldfish_vk_validateResult = validate; \
if (goldfish_vk_validateResult != success) return goldfish_vk_validateResult; \
@@ -23023,6 +23053,48 @@
mImpl->log("finish vkResetCommandBufferAsyncGOOGLE");;
}
+void VkEncoder::vkCommandBufferHostSyncGOOGLE(
+ VkCommandBuffer commandBuffer,
+ uint32_t needHostSync,
+ uint32_t sequenceNumber)
+{
+ AutoLock encoderLock(mImpl->lock);
+ AEMU_SCOPED_TRACE("vkCommandBufferHostSyncGOOGLE encode");
+ mImpl->log("start vkCommandBufferHostSyncGOOGLE");
+ auto stream = mImpl->stream();
+ auto countingStream = mImpl->countingStream();
+ auto resources = mImpl->resources();
+ auto pool = mImpl->pool();
+ stream->setHandleMapping(resources->unwrapMapping());
+ VkCommandBuffer local_commandBuffer;
+ uint32_t local_needHostSync;
+ uint32_t local_sequenceNumber;
+ local_commandBuffer = commandBuffer;
+ local_needHostSync = needHostSync;
+ local_sequenceNumber = sequenceNumber;
+ countingStream->rewind();
+ {
+ uint64_t cgen_var_1518;
+ countingStream->handleMapping()->mapHandles_VkCommandBuffer_u64(&local_commandBuffer, &cgen_var_1518, 1);
+ countingStream->write((uint64_t*)&cgen_var_1518, 1 * 8);
+ countingStream->write((uint32_t*)&local_needHostSync, sizeof(uint32_t));
+ countingStream->write((uint32_t*)&local_sequenceNumber, sizeof(uint32_t));
+ }
+ uint32_t packetSize_vkCommandBufferHostSyncGOOGLE = 4 + 4 + (uint32_t)countingStream->bytesWritten();
+ countingStream->rewind();
+ uint32_t opcode_vkCommandBufferHostSyncGOOGLE = OP_vkCommandBufferHostSyncGOOGLE;
+ stream->write(&opcode_vkCommandBufferHostSyncGOOGLE, sizeof(uint32_t));
+ stream->write(&packetSize_vkCommandBufferHostSyncGOOGLE, sizeof(uint32_t));
+ uint64_t cgen_var_1519;
+ stream->handleMapping()->mapHandles_VkCommandBuffer_u64(&local_commandBuffer, &cgen_var_1519, 1);
+ stream->write((uint64_t*)&cgen_var_1519, 1 * 8);
+ stream->write((uint32_t*)&local_needHostSync, sizeof(uint32_t));
+ stream->write((uint32_t*)&local_sequenceNumber, sizeof(uint32_t));
+ AEMU_SCOPED_TRACE("vkCommandBufferHostSyncGOOGLE readParams");
+ AEMU_SCOPED_TRACE("vkCommandBufferHostSyncGOOGLE returnUnmarshal");
+ mImpl->log("finish vkCommandBufferHostSyncGOOGLE");;
+}
+
#endif
} // namespace goldfish_vk
diff --git a/system/vulkan_enc/VkEncoder.h b/system/vulkan_enc/VkEncoder.h
index daf015d..65debda 100644
--- a/system/vulkan_enc/VkEncoder.h
+++ b/system/vulkan_enc/VkEncoder.h
@@ -28,6 +28,7 @@
#include "goldfish_vk_private_defs.h"
+#include <functional>
#include <memory>
class IOStream;
@@ -40,7 +41,11 @@
VkEncoder(IOStream* stream);
~VkEncoder();
- void flush(); // Cross-thread flushing!!!111
+ void flush();
+
+ using CleanupCallback = std::function<void()>;
+ void registerCleanupCallback(void* handle, CleanupCallback cb);
+ void unregisterCleanupCallback(void* handle);
#ifdef VK_VERSION_1_0
VkResult vkCreateInstance(
const VkInstanceCreateInfo* pCreateInfo,
@@ -1783,6 +1788,10 @@
void vkResetCommandBufferAsyncGOOGLE(
VkCommandBuffer commandBuffer,
VkCommandBufferResetFlags flags);
+ void vkCommandBufferHostSyncGOOGLE(
+ VkCommandBuffer commandBuffer,
+ uint32_t needHostSync,
+ uint32_t sequenceNumber);
#endif
private:
diff --git a/system/vulkan_enc/VulkanHandles.h b/system/vulkan_enc/VulkanHandles.h
index 481e601..ea926d8 100644
--- a/system/vulkan_enc/VulkanHandles.h
+++ b/system/vulkan_enc/VulkanHandles.h
@@ -19,11 +19,11 @@
#define GOLDFISH_VK_LIST_TRIVIAL_DISPATCHABLE_HANDLE_TYPES(f) \
f(VkPhysicalDevice) \
f(VkQueue) \
- f(VkCommandBuffer) \
#define GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(f) \
f(VkInstance) \
f(VkDevice) \
+ f(VkCommandBuffer) \
GOLDFISH_VK_LIST_TRIVIAL_DISPATCHABLE_HANDLE_TYPES(f)
#define GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f) \
diff --git a/system/vulkan_enc/goldfish_vk_marshaling_guest.cpp b/system/vulkan_enc/goldfish_vk_marshaling_guest.cpp
index 80afa5f..96efd31 100644
--- a/system/vulkan_enc/goldfish_vk_marshaling_guest.cpp
+++ b/system/vulkan_enc/goldfish_vk_marshaling_guest.cpp
@@ -16213,6 +16213,10 @@
{
return "OP_vkResetCommandBufferAsyncGOOGLE";
}
+ case OP_vkCommandBufferHostSyncGOOGLE:
+ {
+ return "OP_vkCommandBufferHostSyncGOOGLE";
+ }
#endif
default:
{
diff --git a/system/vulkan_enc/goldfish_vk_marshaling_guest.h b/system/vulkan_enc/goldfish_vk_marshaling_guest.h
index 612c5d5..154b7de 100644
--- a/system/vulkan_enc/goldfish_vk_marshaling_guest.h
+++ b/system/vulkan_enc/goldfish_vk_marshaling_guest.h
@@ -3388,6 +3388,7 @@
#define OP_vkBeginCommandBufferAsyncGOOGLE 20321
#define OP_vkEndCommandBufferAsyncGOOGLE 20322
#define OP_vkResetCommandBufferAsyncGOOGLE 20323
+#define OP_vkCommandBufferHostSyncGOOGLE 20324
#endif
const char* api_opcode_to_string(
const uint32_t opcode);
diff --git a/system/vulkan_enc/goldfish_vk_private_defs.h b/system/vulkan_enc/goldfish_vk_private_defs.h
index 3607967..662b8f0 100644
--- a/system/vulkan_enc/goldfish_vk_private_defs.h
+++ b/system/vulkan_enc/goldfish_vk_private_defs.h
@@ -424,6 +424,10 @@
typedef void (VKAPI_PTR *PFN_vkResetCommandBufferAsyncGOOGLE)(
VkCommandBuffer commandBuffer,
VkCommandBufferResetFlags flags);
+typedef void (VKAPI_PTR *PFN_vkCommandBufferHostSyncGOOGLE)(
+ VkCommandBuffer commandBuffer,
+ uint32_t needHostSync,
+ uint32_t sequenceNumber);
#ifndef VK_FUCHSIA_buffer_collection
#define VK_FUCHSIA_buffer_collection 1