• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <GLES2/gl2.h>
17 #include <vulkan/vulkan.h>
18 
19 #include <atomic>
20 #include <functional>
21 #include <memory>
22 #include <unordered_map>
23 #include <unordered_set>
24 #include <vector>
25 
26 #include "BorrowedImageVk.h"
27 #include "CompositorVk.h"
28 #include "DebugUtilsHelper.h"
29 #include "DeviceLostHelper.h"
30 #include "DisplayVk.h"
31 #include "ExternalObjectManager.h"
32 #include "FrameworkFormats.h"
33 #include "aemu/base/Optional.h"
34 #include "aemu/base/ThreadAnnotations.h"
35 #include "gfxstream/host/BackendCallbacks.h"
36 #include "gfxstream/host/Features.h"
37 #include "goldfish_vk_private_defs.h"
38 #include "utils/GfxApiLogger.h"
39 #include "utils/RenderDoc.h"
40 
41 #if defined(_WIN32)
42 typedef void* HANDLE;
43 // External sync objects are HANDLE on Windows
44 typedef HANDLE VK_EXT_SYNC_HANDLE;
45 // corresponds to INVALID_HANDLE_VALUE
46 #define VK_EXT_SYNC_HANDLE_INVALID (VK_EXT_SYNC_HANDLE)(uintptr_t)(-1)
47 #else
48 // External sync objects are fd's on other POSIX systems
49 typedef int VK_EXT_SYNC_HANDLE;
50 #define VK_EXT_SYNC_HANDLE_INVALID (-1)
51 #endif
52 
53 namespace gfxstream {
54 namespace vk {
55 
56 struct VulkanDispatch;
57 
58 // Returns a consistent answer for which memory type index is best for staging
59 // memory. This is not the simplest thing in the world because even if a memory
60 // type index is host visible, that doesn't mean a VkBuffer is allowed to be
61 // associated with it.
62 bool getStagingMemoryTypeIndex(VulkanDispatch* vk, VkDevice device,
63                                const VkPhysicalDeviceMemoryProperties* memProps,
64                                uint32_t* typeIndex);
65 
66 enum class AstcEmulationMode {
67     Disabled,  // No ASTC emulation (ie: ASTC not supported unless the GPU supports it natively)
68     Cpu,       // Decompress ASTC textures on the CPU
69     Gpu,       // Decompress ASTC textures on the GPU
70 };
71 
72 // Global state that holds a global Vulkan instance along with globally
73 // exported memory allocations + images. This is in order to service things
74 // like AndroidHardwareBuffer/FuchsiaImagePipeHandle. Each such allocation is
75 // associated with a ColorBuffer handle, and depending on host-side support for
76 // GL_EXT_memory_object, also be able to zero-copy render into and readback
77 // with the traditional GL pipeline.
78 class VkEmulation {
79    public:
80     ~VkEmulation();
81 
82     static std::unique_ptr<VkEmulation> create(VulkanDispatch* vk,
83                                                gfxstream::host::BackendCallbacks callbacks,
84                                                gfxstream::host::FeatureSet features);
85 
86     struct Features {
87         bool glInteropSupported = false;
88         bool deferredCommands = false;
89         bool createResourceWithRequirements = false;
90         bool useVulkanComposition = false;
91         bool useVulkanNativeSwapchain = false;
92         std::unique_ptr<emugl::RenderDocWithMultipleVkInstances> guestRenderDoc = nullptr;
93         AstcEmulationMode astcLdrEmulationMode = AstcEmulationMode::Disabled;
94         bool enableEtc2Emulation = false;
95         bool enableYcbcrEmulation = false;
96         bool guestVulkanOnly = false;
97         bool useDedicatedAllocations = false;
98     };
99     void initFeatures(Features features);
100 
101     bool isYcbcrEmulationEnabled() const;
102 
103     bool isEtc2EmulationEnabled() const;
104 
105     bool deferredCommandsEnabled() const;
106     bool createResourcesWithRequirementsEnabled() const;
107 
108     bool supportsExternalMemoryCapabilities() const;
109     bool supportsExternalSemaphoreCapabilities() const;
110     bool supportsExternalFenceCapabilities() const;
111     bool supportsSurfaces() const;
112     bool supportsMoltenVk() const;
113 
114     bool supportsGetPhysicalDeviceProperties2() const;
115 
116     bool supportsPhysicalDeviceIDProperties() const;
117 
118     std::optional<std::array<uint8_t, VK_UUID_SIZE>> getDeviceUuid();
119     std::optional<std::array<uint8_t, VK_UUID_SIZE>> getDriverUuid();
120 
121     bool supportsPrivateData() const;
122 
123     bool supportsExternalMemoryImport() const;
124 
125     bool supportsDmaBuf() const;
126 
127     bool supportsExternalMemoryHostProperties() const;
128 
129     std::optional<VkPhysicalDeviceRobustness2FeaturesEXT> getRobustness2Features() const;
130 
131     VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalMemoryHostProperties() const;
132 
133     bool isGuestVulkanOnly() const;
134 
135     bool commandBufferCheckpointsEnabled() const;
136 
137     bool supportsSamplerYcbcrConversion() const;
138 
139     bool debugUtilsEnabled() const;
140 
141     DebugUtilsHelper& getDebugUtilsHelper();
142 
143     DeviceLostHelper& getDeviceLostHelper();
144 
145     const gfxstream::host::FeatureSet& getFeatures() const;
146 
147     const gfxstream::host::BackendCallbacks& getCallbacks() const;
148 
149     AstcEmulationMode getAstcLdrEmulationMode() const;
150 
151     emugl::RenderDocWithMultipleVkInstances* getRenderDoc();
152 
153     Compositor* getCompositor();
154 
155     DisplayVk* getDisplay();
156 
157     VkInstance getInstance();
158 
159     std::string getGpuVendor() const;
160     std::string getGpuName() const;
161     std::string getGpuVersionString() const;
162     std::string getInstanceExtensionsString() const;
163     std::string getDeviceExtensionsString() const;
164 
165     const VkPhysicalDeviceProperties getPhysicalDeviceProperties() const;
166 
167     struct RepresentativeColorBufferMemoryTypeInfo {
168         // The host memory type index used for Buffer/ColorBuffer allocations.
169         uint32_t hostMemoryTypeIndex;
170 
171         // The guest memory type index that will be returned to guest processes querying
172         // the memory type index of host AHardwareBuffer/ColorBuffer allocations. This may
173         // point to an emulated memory type so that the host can control which memory flags are
174         // exposed to the guest (i.e. hide VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT from the guest).
175         uint32_t guestMemoryTypeIndex;
176     };
177     RepresentativeColorBufferMemoryTypeInfo getRepresentativeColorBufferMemoryTypeInfo() const;
178 
179     void onVkDeviceLost();
180 
181     VkExternalMemoryHandleTypeFlagBits getDefaultExternalMemoryHandleType();
182 
183     std::unique_ptr<gfxstream::DisplaySurface> createDisplaySurface(FBNativeWindowType window,
184                                                                     uint32_t width,
185                                                                     uint32_t height);
186 
187     // ColorBuffer operations
188 
189     bool getColorBufferShareInfo(uint32_t colorBufferHandle, bool* glExported,
190                                  bool* externalMemoryCompatible);
191 
192     bool getColorBufferAllocationInfo(uint32_t colorBufferHandle, VkDeviceSize* outSize,
193                                       uint32_t* outMemoryTypeIndex, bool* outMemoryIsDedicatedAlloc,
194                                       void** outMappedPtr);
195 
196     std::unique_ptr<VkImageCreateInfo> generateColorBufferVkImageCreateInfo(VkFormat format,
197                                                                             uint32_t width,
198                                                                             uint32_t height,
199                                                                             VkImageTiling tiling);
200 
201     bool isFormatSupported(GLenum format);
202 
203     bool createVkColorBuffer(uint32_t width, uint32_t height, GLenum format,
204                              FrameworkFormat frameworkFormat, uint32_t colorBufferHandle,
205                              bool vulkanOnly, uint32_t memoryProperty);
206 
207     bool teardownVkColorBuffer(uint32_t colorBufferHandle);
208 
209     struct ExternalMemoryInfo {
210         // Input fields
211         VkDeviceSize size;
212         uint32_t typeIndex;
213 
214         // Output fields
215         uint32_t id = 0;
216         VkDeviceMemory memory = VK_NULL_HANDLE;
217 
218         // host-mapping fields
219         // host virtual address (hva).
220         void* mappedPtr = nullptr;
221         // host virtual address, aligned to 4KB page.
222         void* pageAlignedHva = nullptr;
223         // the offset of |mappedPtr| off its memory page.
224         uint32_t pageOffset = 0u;
225         // the offset set in |vkBindImageMemory| or |vkBindBufferMemory|.
226         uint32_t bindOffset = 0u;
227         // the size of all the pages the memory uses.
228         size_t sizeToPage = 0u;
229         // guest physical address.
230         uintptr_t gpa = 0u;
231 
232         std::optional<ExternalHandleInfo> handleInfo = std::nullopt;
233 #ifdef __APPLE__
234         // This is used as an external handle when MoltenVK is enabled
235         MTLResource_id externalMetalHandle = nullptr;
236 #endif
237 
238         bool dedicatedAllocation = false;
239     };
240 
241     bool allocExternalMemory(
242         VulkanDispatch* vk, ExternalMemoryInfo* info, bool actuallyExternal = true,
243         android::base::Optional<uint64_t> deviceAlignment = android::base::kNullopt,
244         android::base::Optional<VkBuffer> bufferForDedicatedAllocation = android::base::kNullopt,
245         android::base::Optional<VkImage> imageForDedicatedAllocation = android::base::kNullopt);
246 
247     bool importExternalMemory(VulkanDispatch* vk, VkDevice targetDevice,
248                               const ExternalMemoryInfo* info,
249                               VkMemoryDedicatedAllocateInfo* dedicatedAllocInfo,
250                               VkDeviceMemory* out);
251 
252     enum class VulkanMode {
253         // Default: ColorBuffers can still be used with the existing GL-based
254         // API.  Synchronization with (if it exists) Vulkan images happens on
255         // every one of the GL-based API calls:
256         //
257         // rcReadColorBuffer
258         // rcUpdateColorBuffer
259         // rcBindTexture
260         // rcBindRenderbuffer
261         // rcFlushWindowColorBuffer
262         //
263         // either through explicit CPU copies or implicit in the host driver
264         // if OpenGL interop is supported.
265         //
266         // When images are posted (rcFBPost),
267         // eglSwapBuffers is used, even if that requires a CPU readback.
268 
269         Default = 0,
270 
271         // VulkanOnly: It is assumed that the guest interacts entirely with
272         // the underlying Vulkan image in the guest and does not use the
273         // GL-based API.  This means we can assume those APIs are not called:
274         //
275         // rcReadColorBuffer
276         // rcUpdateColorBuffer
277         // rcBindTexture
278         // rcBindRenderbuffer
279         // rcFlushWindowColorBuffer
280         //
281         // and thus we skip a lot of GL/Vk synchronization.
282         //
283         // When images are posted, eglSwapBuffers is only used if OpenGL
284         // interop is supported. If OpenGL interop is not supported, then we
285         // use a host platform-specific Vulkan swapchain to display the
286         // results.
287 
288         VulkanOnly = 1,
289     };
290 
291     struct ColorBufferInfo {
292         ExternalMemoryInfo memory;
293 
294         uint32_t handle;
295 
296         /* Set in create(), before initialize() */
297         uint32_t width;
298         uint32_t height;
299         GLenum internalFormat;
300         uint32_t memoryProperty;
301         int frameworkFormat;
302         int frameworkStride;
303         bool initialized = false;
304 
305         VkImage image = VK_NULL_HANDLE;
306         VkImageView imageView = VK_NULL_HANDLE;
307         VkSamplerYcbcrConversion ycbcrConversion = VK_NULL_HANDLE;
308         VkImageCreateInfo imageCreateInfoShallow = {};
309 
310         VkImageLayout currentLayout = VK_IMAGE_LAYOUT_UNDEFINED;
311         uint32_t currentQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL;
312 
313         bool glExported = false;
314         bool externalMemoryCompatible = false;
315 
316         VulkanMode vulkanMode = VulkanMode::Default;
317     };
318     std::optional<VkEmulation::ColorBufferInfo> getColorBufferInfo(uint32_t colorBufferHandle);
319 
320     struct BufferInfo {
321         ExternalMemoryInfo memory;
322         uint32_t handle;
323 
324         VkDeviceSize size;
325         VkBufferCreateFlags createFlags;
326         VkBufferUsageFlags usageFlags;
327         VkSharingMode sharingMode;
328 
329         VkBuffer buffer = VK_NULL_HANDLE;
330 
331         bool glExported = false;
332         VulkanMode vulkanMode = VulkanMode::Default;
333     };
334 
335     std::optional<ExternalHandleInfo> dupColorBufferExtMemoryHandle(uint32_t colorBufferHandle);
336 #ifdef __APPLE__
337     MTLResource_id getColorBufferMetalMemoryHandle(uint32_t colorBufferHandle);
338     VkImage getColorBufferVkImage(uint32_t colorBufferHandle);
339 #endif
340 
341     struct VkColorBufferMemoryExport {
342         ExternalHandleInfo handleInfo;
343         uint64_t size = 0;
344         bool linearTiling = false;
345         bool dedicatedAllocation = false;
346     };
347     std::optional<VkColorBufferMemoryExport> exportColorBufferMemory(uint32_t colorBufferHandle);
348 
349     bool setColorBufferVulkanMode(uint32_t colorBufferHandle, uint32_t vulkanMode);
350     int32_t mapGpaToBufferHandle(uint32_t bufferHandle, uint64_t gpa, uint64_t size = 0);
351 
352     bool colorBufferNeedsUpdateBetweenGlAndVk(uint32_t colorBufferHandle);
353 
354     bool readColorBufferToBytes(uint32_t colorBufferHandle, std::vector<uint8_t>* bytes);
355     bool readColorBufferToBytes(uint32_t colorBufferHandle, uint32_t x, uint32_t y, uint32_t w,
356                                 uint32_t h, void* outPixels, uint64_t outPixelsSize);
357 
358     bool updateColorBufferFromBytes(uint32_t colorBufferHandle, const std::vector<uint8_t>& bytes);
359     bool updateColorBufferFromBytes(uint32_t colorBufferHandle, uint32_t x, uint32_t y, uint32_t w,
360                                     uint32_t h, const void* pixels);
361 
362     // Data buffer operations
363     bool getBufferAllocationInfo(uint32_t bufferHandle, VkDeviceSize* outSize,
364                                  uint32_t* outMemoryTypeIndex, bool* outMemoryIsDedicatedAlloc);
365 
366     bool setupVkBuffer(uint64_t size, uint32_t bufferHandle, bool vulkanOnly = false,
367                        uint32_t memoryProperty = 0);
368     bool teardownVkBuffer(uint32_t bufferHandle);
369 
370     std::optional<GenericDescriptorInfo> exportMemoryHandle(VkDevice device, VkDeviceMemory memory);
371     std::optional<ExternalHandleInfo> dupBufferExtMemoryHandle(uint32_t bufferHandle);
372 #ifdef __APPLE__
373     MTLResource_id getBufferMetalMemoryHandle(uint32_t bufferHandle);
374     MTLResource_id getMtlResourceFromVkDeviceMemory(VulkanDispatch* vk, VkDeviceMemory memory);
375 #endif
376 
377     bool readBufferToBytes(uint32_t bufferHandle, uint64_t offset, uint64_t size, void* outBytes);
378     bool updateBufferFromBytes(uint32_t bufferHandle, uint64_t offset, uint64_t size,
379                                const void* bytes);
380 
381     VkExternalMemoryHandleTypeFlags transformExternalMemoryHandleTypeFlags_tohost(
382         VkExternalMemoryHandleTypeFlags bits);
383 
384     VkExternalMemoryHandleTypeFlags transformExternalMemoryHandleTypeFlags_fromhost(
385         VkExternalMemoryHandleTypeFlags hostBits,
386         VkExternalMemoryHandleTypeFlags wantedGuestHandleType);
387 
388     VkExternalMemoryProperties transformExternalMemoryProperties_tohost(
389         VkExternalMemoryProperties props);
390 
391     VkExternalMemoryProperties transformExternalMemoryProperties_fromhost(
392         VkExternalMemoryProperties props, VkExternalMemoryHandleTypeFlags wantedGuestHandleType);
393 
394     void setColorBufferCurrentLayout(uint32_t colorBufferHandle, VkImageLayout);
395 
396     VkImageLayout getColorBufferCurrentLayout(uint32_t colorBufferHandle);
397 
398     void releaseColorBufferForGuestUse(uint32_t colorBufferHandle);
399 
400     std::unique_ptr<BorrowedImageInfoVk> borrowColorBufferForComposition(uint32_t colorBufferHandle,
401                                                                          bool colorBufferIsTarget);
402     std::unique_ptr<BorrowedImageInfoVk> borrowColorBufferForDisplay(uint32_t colorBufferHandle);
403 
404    private:
405     VkEmulation() = default;
406 
407     std::optional<RepresentativeColorBufferMemoryTypeInfo>
408     findRepresentativeColorBufferMemoryTypeIndexLocked() REQUIRES(mMutex);
409 
410     struct ImageSupportInfo {
411         // Input parameters
412         VkFormat format;
413         VkImageType type;
414         VkImageTiling tiling;
415         VkImageUsageFlags usageFlags;
416         VkImageCreateFlags createFlags;
417 
418         // Output parameters
419         bool supported = false;
420         bool supportsExternalMemory = false;
421         bool requiresDedicatedAllocation = false;
422 
423         // Keep the raw output around.
424         VkFormatProperties2 formatProps2;
425         VkImageFormatProperties2 imageFormatProps2;
426         VkExternalImageFormatProperties extFormatProps;
427     };
428 
429     static std::vector<VkEmulation::ImageSupportInfo> getBasicImageSupportList();
430 
431     // For a given ImageSupportInfo, populates usageWithExternalHandles and
432     // requiresDedicatedAllocation. memoryTypeBits are populated later once the
433     // device is created, because that needs a test image to be created.
434     // If we don't support external memory, it's assumed dedicated allocations are
435     // not needed.
436     // Precondition: sVkEmulation instance has been created and ext memory caps known.
437     // Returns false if the query failed.
438     bool populateImageFormatExternalMemorySupportInfo(VulkanDispatch* vk, VkPhysicalDevice physdev,
439                                                       ImageSupportInfo* info);
440 
441     struct DeviceSupportInfo {
442         bool hasGraphicsQueueFamily = false;
443         bool hasComputeQueueFamily = false;
444         bool supportsExternalMemoryImport = false;
445         bool supportsExternalMemoryExport = false;
446         bool supportsDmaBuf = false;
447         bool supportsDriverProperties = false;
448         bool supportsExternalMemoryHostProps = false;
449         bool hasSamplerYcbcrConversionExtension = false;
450         bool supportsSamplerYcbcrConversion = false;
451         bool glInteropSupported = false;
452         bool hasNvidiaDeviceDiagnosticCheckpointsExtension = false;
453         bool supportsNvidiaDeviceDiagnosticCheckpoints = false;
454         bool supportsPrivateData = false;
455 
456         std::vector<VkExtensionProperties> extensions;
457 
458         std::vector<uint32_t> graphicsQueueFamilyIndices;
459         std::vector<uint32_t> computeQueueFamilyIndices;
460 
461         VkPhysicalDeviceProperties physdevProps;
462         VkPhysicalDeviceMemoryProperties memProps;
463         VkPhysicalDeviceIDPropertiesKHR idProps;
464         VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalMemoryHostProps;
465 
466         std::string driverVendor;
467         std::string driverVersion;
468 
469         PFN_vkGetImageMemoryRequirements2KHR getImageMemoryRequirements2Func = nullptr;
470         PFN_vkGetBufferMemoryRequirements2KHR getBufferMemoryRequirements2Func = nullptr;
471 
472 #ifdef _WIN32
473         PFN_vkGetMemoryWin32HandleKHR getMemoryHandleFunc = nullptr;
474 #else
475         PFN_vkGetMemoryFdKHR getMemoryHandleFunc = nullptr;
476 #endif
477 
478         // Set only if requested and supported
479         std::optional<VkPhysicalDeviceRobustness2FeaturesEXT> robustness2Features;
480     };
481 
482     uint32_t getValidMemoryTypeIndex(uint32_t requiredMemoryTypeBits,
483                                      VkMemoryPropertyFlags memoryProperty = 0);
484 
485     int getSelectedGpuIndex(const std::vector<DeviceSupportInfo>& deviceInfos);
486 
487     bool isFormatVulkanCompatible(GLenum internalFormat);
488 
489     bool getColorBufferAllocationInfoLocked(uint32_t colorBufferHandle, VkDeviceSize* outSize,
490                                             uint32_t* outMemoryTypeIndex,
491                                             bool* outMemoryIsDedicatedAlloc, void** outMappedPtr) REQUIRES(mMutex);
492 
493     std::unique_ptr<VkImageCreateInfo> generateColorBufferVkImageCreateInfoLocked(
494         VkFormat format, uint32_t width, uint32_t height, VkImageTiling tiling) REQUIRES(mMutex);
495 
496     bool createVkColorBufferLocked(uint32_t width, uint32_t height, GLenum internalFormat,
497                                    FrameworkFormat frameworkFormat, uint32_t colorBufferHandle,
498                                    bool vulkanOnly, uint32_t memoryProperty) REQUIRES(mMutex);
499 
500     bool teardownVkColorBufferLocked(uint32_t colorBufferHandle) REQUIRES(mMutex);
501 
502     bool colorBufferNeedsUpdateBetweenGlAndVk(const VkEmulation::ColorBufferInfo& colorBufferInfo);
503 
504     bool readColorBufferToBytesLocked(uint32_t colorBufferHandle, uint32_t x, uint32_t y,
505                                       uint32_t w, uint32_t h, void* outPixels,
506                                       uint64_t outPixelsSize) REQUIRES(mMutex);
507 
508     bool updateColorBufferFromBytesLocked(uint32_t colorBufferHandle, uint32_t x, uint32_t y,
509                                           uint32_t w, uint32_t h, const void* pixels,
510                                           size_t inputPixelsSize) REQUIRES(mMutex);
511 
512     bool updateMemReqsForExtMem(std::optional<ExternalHandleInfo> extMemHandleInfo,
513                                 VkMemoryRequirements* pMemReqs);
514 
515     std::tuple<VkCommandBuffer, VkFence> allocateQueueTransferCommandBufferLocked() REQUIRES(mMutex);
516 
517     void freeExternalMemoryLocked(VulkanDispatch* vk, ExternalMemoryInfo* info) REQUIRES(mMutex);
518 
519     std::mutex mMutex;
520 
521     gfxstream::host::BackendCallbacks mCallbacks;
522 
523     gfxstream::host::FeatureSet mFeatures;
524 
525     RepresentativeColorBufferMemoryTypeInfo mRepresentativeColorBufferMemoryTypeInfo;
526 
527     // Whether to use deferred command submission.
528     bool mUseDeferredCommands = false;
529 
530     // Whether to fuse memory requirements getting with resource creation.
531     bool mUseCreateResourcesWithRequirements = false;
532 
533     // RenderDoc integration for guest VkInstances.
534     std::unique_ptr<emugl::RenderDocWithMultipleVkInstances> mGuestRenderDoc;
535 
536     // Whether to use ASTC emulation. Our current ASTC decoder implementation may lead to device
537     // lost on certain device on Windows.
538     AstcEmulationMode mAstcLdrEmulationMode = AstcEmulationMode::Disabled;
539 
540     // Whether to use ETC2 emulation.
541     bool mEnableEtc2Emulation = false;
542 
543     // Whether to use Ycbcr emulation. If this feature is turned on, Ycbcr request will always use
544     // the emulation path regardless of whether the host Vulkan driver actually supports Ycbcr
545     // conversion or not.
546     bool mEnableYcbcrEmulation = false;
547 
548     bool mGuestVulkanOnly = false;
549 
550     bool mUseDedicatedAllocations = false;
551 
552     // Instance and device for creating the system-wide shareable objects.
553     VkInstance mInstance = VK_NULL_HANDLE;
554     uint32_t mVulkanInstanceVersion = 0;
555     std::vector<VkExtensionProperties> mInstanceExtensions;
556 
557     uint32_t mPhysicalDeviceIndex = 0;
558     VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE;
559 
560     VkDevice mDevice = VK_NULL_HANDLE;
561 
562     // Global, instance and device dispatch tables.
563     VulkanDispatch* mGvk = nullptr;
564     VulkanDispatch* mIvk = nullptr;
565     VulkanDispatch* mDvk = nullptr;
566 
567     bool mInstanceSupportsPhysicalDeviceIDProperties = false;
568     bool mInstanceSupportsGetPhysicalDeviceProperties2 = false;
569     bool mInstanceSupportsExternalMemoryCapabilities = false;
570     bool mInstanceSupportsExternalSemaphoreCapabilities = false;
571     bool mInstanceSupportsExternalFenceCapabilities = false;
572     bool mInstanceSupportsSurface = false;
573 #if defined(__APPLE__)
574     bool mInstanceSupportsMoltenVK = false;
575 #else
576     static const bool mInstanceSupportsMoltenVK = false;
577 #endif
578 
579     PFN_vkGetPhysicalDeviceImageFormatProperties2KHR mGetImageFormatProperties2Func = nullptr;
580     PFN_vkGetPhysicalDeviceProperties2KHR mGetPhysicalDeviceProperties2Func = nullptr;
581     PFN_vkGetPhysicalDeviceFeatures2 mGetPhysicalDeviceFeatures2Func = nullptr;
582 
583     bool mDebugUtilsAvailableAndRequested = false;
584     DebugUtilsHelper mDebugUtilsHelper = DebugUtilsHelper::withUtilsDisabled();
585 
586     bool mCommandBufferCheckpointsSupportedAndRequested = false;
587     DeviceLostHelper mDeviceLostHelper{};
588 
589     // Queue, command pool, and command buffer
590     // for running commands to sync stuff system-wide.
591     // TODO(b/197362803): Encapsulate host side VkQueue and the lock.
592     VkQueue mQueue = VK_NULL_HANDLE;
593     std::shared_ptr<android::base::Lock> mQueueLock = nullptr;
594     uint32_t mQueueFamilyIndex = 0;
595 
596     VkCommandPool mCommandPool = VK_NULL_HANDLE;
597     VkCommandBuffer mCommandBuffer = VK_NULL_HANDLE;
598     VkFence mCommandBufferFence = VK_NULL_HANDLE;
599 
600     std::vector<ImageSupportInfo> mImageSupportInfo;
601 
602     // 128 mb staging buffer (really, just a few 4K frames or one 4k HDR frame)
603     // ought to be big enough for anybody!
604     static constexpr VkDeviceSize kDefaultStagingBufferSize = 128ULL * 1048576ULL;
605 
606     struct StagingBufferInfo {
607         // TODO: Don't actually use this as external memory until host visible
608         // external is supported on all platforms
609         ExternalMemoryInfo memory;
610         VkBuffer buffer = VK_NULL_HANDLE;
611         VkDeviceSize size = kDefaultStagingBufferSize;
612     };
613 
614     // Track what is supported on whatever device was selected.
615     DeviceSupportInfo mDeviceInfo;
616 
617     // A single staging buffer to perform most transfers to/from OpenGL on the
618     // host. It is shareable across instances. The memory is shareable but the
619     // buffer is not; other users need to create buffers that
620     // bind to imported versions of the memory.
621     StagingBufferInfo mStaging GUARDED_BY(mMutex);
622 
623     // ColorBuffers are intended to back the guest's shareable images.
624     // For example:
625     // Android: gralloc
626     // Fuchsia: ImagePipeHandle
627     // Linux: dmabuf
628     std::unordered_map<uint32_t, ColorBufferInfo> mColorBuffers GUARDED_BY(mMutex);
629 
630     // Buffers are intended to back the guest's shareable Vulkan buffers.
631     std::unordered_map<uint32_t, BufferInfo> mBuffers GUARDED_BY(mMutex);
632 
633     // In order to support VK_KHR_external_memory_(fd|win32) we need also to
634     // support the concept of plain external memories that are just memory and
635     // not necessarily images. These are then intended to pass through to the
636     // guest in some way, with 1:1 mapping between guest and host external
637     // memory handles.
638     std::unordered_map<uint32_t, ExternalMemoryInfo> mExternalMemories GUARDED_BY(mMutex);
639 
640     // The host keeps a set of occupied guest memory addresses to avoid a
641     // host memory address mapped to guest twice.
642     std::unordered_set<uint64_t> mOccupiedGpas GUARDED_BY(mMutex);
643 
644     // We can also consider using a single external memory object to back all
645     // host visible allocations in the guest. This would save memory, but we
646     // would also need to automatically add
647     // VkExternalMemory(Image|Buffer)CreateInfo, or if it is already there, OR
648     // it with the handle types on the host.
649     // A rough sketch: Some memories/images/buffers in the guest
650     // are backed by host visible memory:
651     // There is already a virtual memory type for those things in the current
652     // implementation. The guest doesn't know whether the pointer or the
653     // VkDeviceMemory object is backed by host external or non external.
654     // TODO: are all possible buffer / image usages compatible with
655     // external backing?
656     // TODO: try switching to this
657     ExternalMemoryInfo mVirtualHostVisibleHeap;
658 
659     // Every command buffer in the pool is associated with a VkFence which is
660     // signaled only if the command buffer completes.
661     std::vector<std::tuple<VkCommandBuffer, VkFence>> mTransferQueueCommandBufferPool GUARDED_BY(mMutex);
662 
663     std::unique_ptr<CompositorVk> mCompositorVk;
664 
665     // The implementation for Vulkan native swapchain. Only initialized in initVkEmulationFeatures
666     // if useVulkanNativeSwapchain is set.
667     std::unique_ptr<DisplayVk> mDisplayVk;
668 };
669 
670 }  // namespace vk
671 }  // namespace gfxstream
672