diff options
author | Lingfeng Yang <lfy@google.com> | 2021-07-15 16:50:37 -0700 |
---|---|---|
committer | Lingfeng Yang <lfy@google.com> | 2021-07-21 13:51:54 -0700 |
commit | 9e750257b11b42bf7a49059db8533c935d3cc2db (patch) | |
tree | 8179a6d305432e3d07b9960a22ed3ef84ad085ef /stream-servers/vulkan/VkAndroidNativeBuffer.cpp | |
parent | af686801c2caaade06e2adeccae04fa77043b4d9 (diff) | |
download | vulkan-cereal-9e750257b11b42bf7a49059db8533c935d3cc2db.tar.gz |
vulkan: wait sync fd for vkQSRI
Bug: 193809913
This CL adds the async vkQSRI functionality, and enables the feature
flag (if fence contexts are available).
Change-Id: I5e67167618b318a74bfb55528951ca95007df614
Diffstat (limited to 'stream-servers/vulkan/VkAndroidNativeBuffer.cpp')
-rw-r--r-- | stream-servers/vulkan/VkAndroidNativeBuffer.cpp | 120 |
1 files changed, 114 insertions, 6 deletions
diff --git a/stream-servers/vulkan/VkAndroidNativeBuffer.cpp b/stream-servers/vulkan/VkAndroidNativeBuffer.cpp index 7cbfb5a2..a47bb4d0 100644 --- a/stream-servers/vulkan/VkAndroidNativeBuffer.cpp +++ b/stream-servers/vulkan/VkAndroidNativeBuffer.cpp @@ -19,13 +19,61 @@ #include "GrallocDefs.h" #include "VkCommonOperations.h" #include "VulkanDispatch.h" +#include "SyncThread.h" #include <string.h> #define VK_ANB_ERR(fmt,...) fprintf(stderr, "%s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__); +#define VK_ANB_DEBUG 0 + +#if VK_ANB_DEBUG +#define VK_ANB_DEBUG(fmt,...) fprintf(stderr, "vk-anb-debug: %s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__); +#define VK_ANB_DEBUG_OBJ(obj, fmt,...) fprintf(stderr, "vk-anb-debug: %s:%d:%p " fmt "\n", __func__, __LINE__, obj, ##__VA_ARGS__); +#else +#define VK_ANB_DEBUG(fmt,...) +#define VK_ANB_DEBUG_OBJ(obj, fmt,...) +#endif + +using android::base::AutoLock; +using android::base::Lock; + namespace goldfish_vk { +VkFence AndroidNativeBufferInfo::QsriWaitInfo::getFenceFromPoolLocked() { + VK_ANB_DEBUG("enter"); + + if (!vk) return VK_NULL_HANDLE; + + if (fencePool.empty()) { + VkFence fence; + VkFenceCreateInfo fenceCreateInfo = { + VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, 0, 0, + }; + vk->vkCreateFence(device, &fenceCreateInfo, nullptr, &fence); + VK_ANB_DEBUG("no fences in pool, created %p", fence); + return fence; + } else { + VkFence res = fencePool.back(); + fencePool.pop_back(); + vk->vkResetFences(device, 1, &res); + VK_ANB_DEBUG("existing fence in pool: %p. also reset the fence", res); + return res; + } +} + +AndroidNativeBufferInfo::QsriWaitInfo::~QsriWaitInfo() { + VK_ANB_DEBUG("enter"); + if (!vk) return; + if (!device) return; + // Nothing in the fence pool is unsignaled + for (auto fence : fencePool) { + VK_ANB_DEBUG("destroy fence %p", fence); + vk->vkDestroyFence(device, fence, nullptr); + } + VK_ANB_DEBUG("exit"); +} + bool parseAndroidNativeBufferInfo( const VkImageCreateInfo* pCreateInfo, AndroidNativeBufferInfo* info_out) { @@ -48,8 +96,7 @@ VkResult prepareAndroidNativeBufferImage( const VkPhysicalDeviceMemoryProperties* memProps, AndroidNativeBufferInfo* out) { - *out = {}; - + out->vk = vk; out->device = device; out->vkFormat = pCreateInfo->format; out->extent = pCreateInfo->extent; @@ -273,11 +320,22 @@ void teardownAndroidNativeBufferImage( for (auto queueState : anbInfo->queueStates) { queueState.teardown(vk, device); } + anbInfo->queueStates.clear(); anbInfo->acquireQueueState.teardown(vk, device); - *anbInfo = {}; + anbInfo->vk = nullptr; + anbInfo->device = VK_NULL_HANDLE; + anbInfo->image = VK_NULL_HANDLE; + anbInfo->imageMemory = VK_NULL_HANDLE; + anbInfo->stagingBuffer = VK_NULL_HANDLE; + anbInfo->mappedStagingPtr = nullptr; + anbInfo->stagingMemory = VK_NULL_HANDLE; + + AutoLock lock(anbInfo->qsriWaitInfo.lock); + anbInfo->qsriWaitInfo.presentCount = 0; + anbInfo->qsriWaitInfo.requestedPresentCount = 0; } void getGralloc0Usage(VkFormat format, VkImageUsageFlags imageUsage, @@ -505,6 +563,8 @@ VkResult setAndroidNativeImageSemaphoreSignaled( return VK_SUCCESS; } +static constexpr uint64_t kTimeoutNs = 3ULL * 1000000000ULL; + VkResult syncImageToColorBuffer( VulkanDispatch* vk, uint32_t queueFamilyIndex, @@ -512,7 +572,14 @@ VkResult syncImageToColorBuffer( uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, int* pNativeFenceFd, - AndroidNativeBufferInfo* anbInfo) { + std::shared_ptr<AndroidNativeBufferInfo> anbInfo) { + + auto anbInfoPtr = anbInfo.get(); + { + AutoLock lock(anbInfo->qsriWaitInfo.lock); + VK_ANB_DEBUG_OBJ(anbInfoPtr, "ensure dispatch %p device %p", vk, anbInfo->device); + anbInfo->qsriWaitInfo.ensureDispatchAndDevice(vk, anbInfo->device); + } auto fb = FrameBuffer::getFB(); fb->lock(); @@ -662,13 +729,46 @@ VkResult syncImageToColorBuffer( }; // TODO(kaiyili): initiate ownership transfer to DisplayVk here. - vk->vkQueueSubmit(queueState.queue, 1, &submitInfo, VK_NULL_HANDLE); - + VkFence qsriFence = VK_NULL_HANDLE; + { + VK_ANB_DEBUG_OBJ(anbInfoPtr, "trying to get qsri fence"); + AutoLock lock(anbInfo->qsriWaitInfo.lock); + VK_ANB_DEBUG_OBJ(anbInfoPtr, "trying to get qsri fence (got lock)"); + qsriFence = anbInfo->qsriWaitInfo.getFenceFromPoolLocked(); + VK_ANB_DEBUG_OBJ(anbInfoPtr, "got qsri fence %p", qsriFence); + } + vk->vkQueueSubmit(queueState.queue, 1, &submitInfo, qsriFence); fb->unlock(); if (anbInfo->useVulkanNativeImage) { + VK_ANB_DEBUG_OBJ(anbInfoPtr, "using native image, so use sync thread to wait"); fb->setColorBufferInUse(anbInfo->colorBufferHandle, false); + VkDevice device = anbInfo->device; + // Queue wait to sync thread with completion callback + // Pass anbInfo by value to get a ref + SyncThread::get()->triggerGeneral([anbInfoPtr, anbInfo, vk, device, qsriFence] { + VK_ANB_DEBUG_OBJ(anbInfoPtr, "wait callback: enter"); + if (qsriFence) { + VK_ANB_DEBUG_OBJ(anbInfoPtr, "wait callback: wait for fence %p...", qsriFence); + vk->vkWaitForFences(device, 1, &qsriFence, VK_FALSE, kTimeoutNs); + VK_ANB_DEBUG_OBJ(anbInfoPtr, "wait callback: wait for fence %p...(done)", qsriFence); + } + AutoLock lock(anbInfo->qsriWaitInfo.lock); + VK_ANB_DEBUG_OBJ(anbInfoPtr, "wait callback: return fence and signal"); + if (qsriFence) { + anbInfo->qsriWaitInfo.returnFenceLocked(qsriFence); + } + ++anbInfo->qsriWaitInfo.presentCount; + VK_ANB_DEBUG_OBJ(anbInfoPtr, "wait callback: done, present count is now %llu", (unsigned long long)anbInfo->qsriWaitInfo.presentCount); + anbInfo->qsriWaitInfo.cv.signal(); + VK_ANB_DEBUG_OBJ(anbInfoPtr, "wait callback: exit"); + }); } else { + VK_ANB_DEBUG_OBJ(anbInfoPtr, "not using native image, so wait right away"); + if (qsriFence) { + vk->vkWaitForFences(anbInfo->device, 1, &qsriFence, VK_FALSE, kTimeoutNs); + } + VkMappedMemoryRange toInvalidate = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0, anbInfo->stagingMemory, @@ -701,6 +801,14 @@ VkResult syncImageToColorBuffer( colorBufferHandle, anbInfo->mappedStagingPtr, bpp * anbInfo->extent.width * anbInfo->extent.height); + + AutoLock lock(anbInfo->qsriWaitInfo.lock); + ++anbInfo->qsriWaitInfo.presentCount; + VK_ANB_DEBUG_OBJ(anbInfoPtr, "done, present count is now %llu", (unsigned long long)anbInfo->qsriWaitInfo.presentCount); + anbInfo->qsriWaitInfo.cv.signal(); + if (qsriFence) { + anbInfo->qsriWaitInfo.returnFenceLocked(qsriFence); + } } return VK_SUCCESS; |