1 // Copyright 2018 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expresso or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 #pragma once 15 16 #include <vulkan/vulkan.h> 17 18 #include <atomic> 19 #include <deque> 20 #include <memory> 21 #include <unordered_set> 22 #include <vector> 23 24 #include "VkCommonOperations.h" 25 #include "VkQsriTimeline.h" 26 #include "aemu/base/BumpPool.h" 27 #include "aemu/base/synchronization/ConditionVariable.h" 28 #include "aemu/base/synchronization/Lock.h" 29 #include "goldfish_vk_private_defs.h" 30 31 namespace gfxstream { 32 namespace vk { 33 34 struct AndroidNativeBufferInfo; 35 struct VulkanDispatch; 36 37 // This class provides methods to create and query information about Android 38 // native buffers in the context of creating Android swapchain images that have 39 // Android native buffer backing. 40 41 // This is to be refactored to move to external memory only once we get that 42 // working. 43 44 void teardownAndroidNativeBufferImage(VulkanDispatch* vk, AndroidNativeBufferInfo* anbInfo); 45 46 struct AndroidNativeBufferInfo { ~AndroidNativeBufferInfoAndroidNativeBufferInfo47 ~AndroidNativeBufferInfo() { 48 if (vk) { 49 teardownAndroidNativeBufferImage(vk, this); 50 } 51 } 52 53 VulkanDispatch* vk = nullptr; 54 VkDevice device = VK_NULL_HANDLE; 55 VkFormat vkFormat; 56 VkExtent3D extent; 57 VkImageUsageFlags usage; 58 std::vector<uint32_t> queueFamilyIndices; 59 60 int format; 61 int stride; 62 uint32_t colorBufferHandle; 63 bool externallyBacked = false; 64 bool useVulkanNativeImage = false; 65 66 // We will be using separate allocations for image versus staging memory, 67 // because not all host Vulkan drivers will support directly rendering to 68 // host visible memory in a layout that glTexSubImage2D can consume. 69 70 // If we are using external memory, these memories are imported 71 // to the current instance. 72 VkDeviceMemory imageMemory = VK_NULL_HANDLE; 73 VkDeviceMemory stagingMemory = VK_NULL_HANDLE; 74 75 VkBuffer stagingBuffer = VK_NULL_HANDLE; 76 77 uint32_t imageMemoryTypeIndex; 78 uint32_t stagingMemoryTypeIndex; 79 80 uint8_t* mappedStagingPtr = nullptr; 81 82 // To be populated later as we go. 83 VkImage image = VK_NULL_HANDLE; 84 VkMemoryRequirements memReqs; 85 86 // The queue over which we send the buffer/image copy commands depends on 87 // the queue over which vkQueueSignalReleaseImageANDROID happens. 88 // It is assumed that the VkImage object has been created by Android swapchain layer 89 // with all the relevant queue family indices for sharing set properly. 90 struct QueueState { 91 VkQueue queue = VK_NULL_HANDLE; 92 VkCommandPool pool = VK_NULL_HANDLE; 93 VkCommandBuffer cb = VK_NULL_HANDLE; 94 VkCommandBuffer cb2 = VK_NULL_HANDLE; 95 VkFence fence = VK_NULL_HANDLE; 96 android::base::Lock* lock = nullptr; 97 uint32_t queueFamilyIndex = 0; 98 void setup(VulkanDispatch* vk, VkDevice device, VkQueue queue, uint32_t queueFamilyIndex, 99 android::base::Lock* queueLock); 100 void teardown(VulkanDispatch* vk, VkDevice device); 101 }; 102 // We keep one QueueState for each queue family index used by the guest 103 // in vkQueuePresentKHR. 104 std::vector<QueueState> queueStates; 105 106 // Did we ever sync the Vulkan image with a ColorBuffer? 107 // If so, set everSynced along with the queue family index 108 // used to do that. 109 // If the swapchain image was created with exclusive sharing 110 // mode (reflected in this struct's |sharingMode| field), 111 // this part doesn't really matter. 112 bool everSynced = false; 113 uint32_t lastUsedQueueFamilyIndex; 114 115 // On first acquire, we might use a different queue family 116 // to initially set the semaphore/fence to be signaled. 117 // Track that here. 118 bool everAcquired = false; 119 QueueState acquireQueueState; 120 121 // State that is of interest when interacting with sync fds and SyncThread. 122 // Protected by this lock and condition variable. 123 class QsriWaitFencePool { 124 public: 125 QsriWaitFencePool(VulkanDispatch*, VkDevice); 126 ~QsriWaitFencePool(); 127 VkFence getFenceFromPool(); 128 void returnFence(VkFence fence); 129 130 private: 131 android::base::Lock mLock; 132 133 VulkanDispatch* mVk; 134 VkDevice mDevice; 135 136 // A pool of vkFences for waiting (optimization so we don't keep recreating them every 137 // time). 138 std::vector<VkFence> mAvailableFences; 139 std::unordered_set<VkFence> mUsedFences; 140 }; 141 142 std::unique_ptr<QsriWaitFencePool> qsriWaitFencePool = nullptr; 143 std::unique_ptr<VkQsriTimeline> qsriTimeline = nullptr; 144 }; 145 146 VkResult prepareAndroidNativeBufferImage(VulkanDispatch* vk, VkDevice device, 147 android::base::BumpPool& allocator, 148 const VkImageCreateInfo* pCreateInfo, 149 const VkNativeBufferANDROID* nativeBufferANDROID, 150 const VkAllocationCallbacks* pAllocator, 151 const VkPhysicalDeviceMemoryProperties* memProps, 152 AndroidNativeBufferInfo* out); 153 154 void getGralloc0Usage(VkFormat format, VkImageUsageFlags imageUsage, int* usage_out); 155 void getGralloc1Usage(VkFormat format, VkImageUsageFlags imageUsage, 156 VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, 157 uint64_t* consumerUsage_out, uint64_t* producerUsage_out); 158 159 VkResult setAndroidNativeImageSemaphoreSignaled(VulkanDispatch* vk, VkDevice device, 160 VkQueue defaultQueue, 161 uint32_t defaultQueueFamilyIndex, 162 android::base::Lock* defaultQueueLock, 163 VkSemaphore semaphore, VkFence fence, 164 AndroidNativeBufferInfo* anbInfo); 165 166 VkResult syncImageToColorBuffer(VulkanDispatch* vk, uint32_t queueFamilyIndex, VkQueue queue, 167 android::base::Lock* queueLock, uint32_t waitSemaphoreCount, 168 const VkSemaphore* pWaitSemaphores, int* pNativeFenceFd, 169 std::shared_ptr<AndroidNativeBufferInfo> anbInfo); 170 171 } // namespace vk 172 } // namespace gfxstream 173