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 "base/ConditionVariable.h" 27 #include "base/Lock.h" 28 #include "cereal/common/goldfish_vk_private_defs.h" 29 30 namespace goldfish_vk { 31 32 struct AndroidNativeBufferInfo; 33 struct VulkanDispatch; 34 35 // This class provides methods to create and query information about Android 36 // native buffers in the context of creating Android swapchain images that have 37 // Android native buffer backing. 38 39 // This is to be refactored to move to external memory only once we get that 40 // working. 41 42 void teardownAndroidNativeBufferImage( 43 VulkanDispatch* vk, 44 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( 99 VulkanDispatch* vk, 100 VkDevice device, 101 VkQueue queue, 102 uint32_t queueFamilyIndex, 103 android::base::Lock* queueLock); 104 void teardown(VulkanDispatch* vk, VkDevice device); 105 }; 106 // We keep one QueueState for each queue family index used by the guest 107 // in vkQueuePresentKHR. 108 std::vector<QueueState> queueStates; 109 110 // Did we ever sync the Vulkan image with a ColorBuffer? 111 // If so, set everSynced along with the queue family index 112 // used to do that. 113 // If the swapchain image was created with exclusive sharing 114 // mode (reflected in this struct's |sharingMode| field), 115 // this part doesn't really matter. 116 bool everSynced = false; 117 uint32_t lastUsedQueueFamilyIndex; 118 119 // On first acquire, we might use a different queue family 120 // to initially set the semaphore/fence to be signaled. 121 // Track that here. 122 bool everAcquired = false; 123 QueueState acquireQueueState; 124 125 // State that is of interest when interacting with sync fds and SyncThread. 126 // Protected by this lock and condition variable. 127 class QsriWaitFencePool { 128 public: 129 QsriWaitFencePool(VulkanDispatch*, VkDevice); 130 ~QsriWaitFencePool(); 131 VkFence getFenceFromPool(); 132 void returnFence(VkFence fence); 133 134 private: 135 android::base::Lock mLock; 136 137 VulkanDispatch* mVk; 138 VkDevice mDevice; 139 140 // A pool of vkFences for waiting (optimization so we don't keep recreating them every 141 // time). 142 std::vector<VkFence> mAvailableFences; 143 std::unordered_set<VkFence> mUsedFences; 144 }; 145 146 std::unique_ptr<QsriWaitFencePool> qsriWaitFencePool = nullptr; 147 std::unique_ptr<VkQsriTimeline> qsriTimeline = nullptr; 148 }; 149 150 VkResult prepareAndroidNativeBufferImage( 151 VulkanDispatch* vk, 152 VkDevice device, 153 const VkImageCreateInfo* pCreateInfo, 154 const VkNativeBufferANDROID* nativeBufferANDROID, 155 const VkAllocationCallbacks* pAllocator, 156 const VkPhysicalDeviceMemoryProperties* memProps, 157 AndroidNativeBufferInfo* out); 158 159 void getGralloc0Usage(VkFormat format, VkImageUsageFlags imageUsage, 160 int* usage_out); 161 void getGralloc1Usage(VkFormat format, VkImageUsageFlags imageUsage, 162 VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, 163 uint64_t* consumerUsage_out, 164 uint64_t* producerUsage_out); 165 166 VkResult setAndroidNativeImageSemaphoreSignaled( 167 VulkanDispatch* vk, 168 VkDevice device, 169 VkQueue defaultQueue, 170 uint32_t defaultQueueFamilyIndex, 171 android::base::Lock* defaultQueueLock, 172 VkSemaphore semaphore, 173 VkFence fence, 174 AndroidNativeBufferInfo* anbInfo); 175 176 VkResult syncImageToColorBuffer( 177 VulkanDispatch* vk, 178 uint32_t queueFamilyIndex, 179 VkQueue queue, 180 android::base::Lock* queueLock, 181 uint32_t waitSemaphoreCount, 182 const VkSemaphore* pWaitSemaphores, 183 int* pNativeFenceFd, 184 std::shared_ptr<AndroidNativeBufferInfo> anbInfo); 185 186 } // namespace goldfish_vk 187