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 "DeviceOpTracker.h" 31 #include "DisplayVk.h" 32 #include "FrameworkFormats.h" 33 #include "aemu/base/ManagedDescriptor.hpp" 34 #include "aemu/base/Optional.h" 35 #include "aemu/base/synchronization/Lock.h" 36 #include "gfxstream/host/BackendCallbacks.h" 37 #include "gfxstream/host/Features.h" 38 #include "goldfish_vk_private_defs.h" 39 #include "utils/GfxApiLogger.h" 40 #include "utils/RenderDoc.h" 41 42 #ifdef _WIN32 43 typedef void* HANDLE; 44 #endif 45 46 #if defined(_WIN32) 47 // External sync objects are HANDLE on Windows 48 typedef HANDLE VK_EXT_SYNC_HANDLE; 49 // corresponds to INVALID_HANDLE_VALUE 50 #define VK_EXT_SYNC_HANDLE_INVALID (VK_EXT_SYNC_HANDLE)(uintptr_t)(-1) 51 #else 52 // External sync objects are fd's on other POSIX systems 53 typedef int VK_EXT_SYNC_HANDLE; 54 #define VK_EXT_SYNC_HANDLE_INVALID (-1) 55 #endif 56 57 #if defined(_WIN32) 58 // External memory objects are HANDLE on Windows 59 typedef HANDLE VK_EXT_MEMORY_HANDLE; 60 // corresponds to INVALID_HANDLE_VALUE 61 #define VK_EXT_MEMORY_HANDLE_INVALID (VK_EXT_MEMORY_HANDLE)(uintptr_t)(-1) 62 #define VK_EXT_MEMORY_HANDLE_TYPE_BIT VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT 63 #elif defined(__QNX__) 64 #include <screen/screen.h> 65 // External memory objects are screen_buffer_t handles on QNX 66 typedef screen_buffer_t VK_EXT_MEMORY_HANDLE; 67 #define VK_EXT_MEMORY_HANDLE_INVALID (VK_EXT_MEMORY_HANDLE) nullptr 68 #define VK_EXT_MEMORY_HANDLE_TYPE_BIT VK_EXTERNAL_MEMORY_HANDLE_TYPE_SCREEN_BUFFER_BIT_QNX 69 #else 70 // External memory objects are fd's on other POSIX systems 71 typedef int VK_EXT_MEMORY_HANDLE; 72 #define VK_EXT_MEMORY_HANDLE_INVALID (-1) 73 #define VK_EXT_MEMORY_HANDLE_TYPE_BIT VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT 74 #endif 75 76 namespace gfxstream { 77 namespace vk { 78 79 struct VulkanDispatch; 80 81 // Returns a consistent answer for which memory type index is best for staging 82 // memory. This is not the simplest thing in the world because even if a memory 83 // type index is host visible, that doesn't mean a VkBuffer is allowed to be 84 // associated with it. 85 bool getStagingMemoryTypeIndex(VulkanDispatch* vk, VkDevice device, 86 const VkPhysicalDeviceMemoryProperties* memProps, 87 uint32_t* typeIndex); 88 89 VK_EXT_MEMORY_HANDLE dupExternalMemory(VK_EXT_MEMORY_HANDLE); 90 91 enum class AstcEmulationMode { 92 Disabled, // No ASTC emulation (ie: ASTC not supported unless the GPU supports it natively) 93 Cpu, // Decompress ASTC textures on the CPU 94 Gpu, // Decompress ASTC textures on the GPU 95 }; 96 97 // Global state that holds a global Vulkan instance along with globally 98 // exported memory allocations + images. This is in order to service things 99 // like AndroidHardwareBuffer/FuchsiaImagePipeHandle. Each such allocation is 100 // associated with a ColorBuffer handle, and depending on host-side support for 101 // GL_EXT_memory_object, also be able to zero-copy render into and readback 102 // with the traditional GL pipeline. 103 struct VkEmulation { 104 // Whether initialization succeeded. 105 bool live = false; 106 107 gfxstream::host::BackendCallbacks callbacks; 108 109 gfxstream::host::FeatureSet features; 110 111 // Whether to use deferred command submission. 112 bool useDeferredCommands = false; 113 114 // Whether to fuse memory requirements getting with resource creation. 115 bool useCreateResourcesWithRequirements = false; 116 117 // RenderDoc integration for guest VkInstances. 118 std::unique_ptr<emugl::RenderDocWithMultipleVkInstances> guestRenderDoc = nullptr; 119 120 // Whether to use ASTC emulation. Our current ASTC decoder implementation may lead to device 121 // lost on certain device on Windows. 122 AstcEmulationMode astcLdrEmulationMode = AstcEmulationMode::Disabled; 123 124 // Whether to use ETC2 emulation. 125 bool enableEtc2Emulation = false; 126 127 // Whether to use Ycbcr emulation. If this feature is turned on, Ycbcr request will always use 128 // the emulation path regardless of whether the host Vulkan driver actually supports Ycbcr 129 // conversion or not. 130 bool enableYcbcrEmulation = false; 131 132 bool guestVulkanOnly = false; 133 134 bool useDedicatedAllocations = false; 135 136 // Instance and device for creating the system-wide shareable objects. 137 VkInstance instance = VK_NULL_HANDLE; 138 VkPhysicalDevice physdev = VK_NULL_HANDLE; 139 VkDevice device = VK_NULL_HANDLE; 140 141 // Physical device index 142 uint32_t physicalDeviceIndex = 0; 143 144 // Global, instance and device dispatch tables. 145 VulkanDispatch* gvk = nullptr; 146 VulkanDispatch* ivk = nullptr; 147 VulkanDispatch* dvk = nullptr; 148 149 bool instanceSupportsPhysicalDeviceIDProperties = false; 150 bool instanceSupportsGetPhysicalDeviceProperties2 = false; 151 bool instanceSupportsExternalMemoryCapabilities = false; 152 bool instanceSupportsExternalSemaphoreCapabilities = false; 153 bool instanceSupportsExternalFenceCapabilities = false; 154 bool instanceSupportsSurface = false; 155 PFN_vkGetPhysicalDeviceImageFormatProperties2KHR getImageFormatProperties2Func = nullptr; 156 PFN_vkGetPhysicalDeviceProperties2KHR getPhysicalDeviceProperties2Func = nullptr; 157 PFN_vkGetPhysicalDeviceFeatures2 getPhysicalDeviceFeatures2Func = nullptr; 158 159 #if defined(__APPLE__) 160 bool instanceSupportsMoltenVK = false; 161 #else 162 static const bool instanceSupportsMoltenVK = false; 163 #endif 164 165 bool debugUtilsAvailableAndRequested = false; 166 DebugUtilsHelper debugUtilsHelper = DebugUtilsHelper::withUtilsDisabled(); 167 168 bool commandBufferCheckpointsSupportedAndRequested = false; 169 DeviceLostHelper deviceLostHelper{}; 170 171 // Queue, command pool, and command buffer 172 // for running commands to sync stuff system-wide. 173 // TODO(b/197362803): Encapsulate host side VkQueue and the lock. 174 VkQueue queue = VK_NULL_HANDLE; 175 std::shared_ptr<android::base::Lock> queueLock = nullptr; 176 uint32_t queueFamilyIndex = 0; 177 VkCommandPool commandPool = VK_NULL_HANDLE; 178 VkCommandBuffer commandBuffer = VK_NULL_HANDLE; 179 VkFence commandBufferFence = VK_NULL_HANDLE; 180 181 struct ImageSupportInfo { 182 // Input parameters 183 VkFormat format; 184 VkImageType type; 185 VkImageTiling tiling; 186 VkImageUsageFlags usageFlags; 187 VkImageCreateFlags createFlags; 188 189 // Output parameters 190 bool supported = false; 191 bool supportsExternalMemory = false; 192 bool requiresDedicatedAllocation = false; 193 194 // Keep the raw output around. 195 VkFormatProperties2 formatProps2; 196 VkImageFormatProperties2 imageFormatProps2; 197 VkExternalImageFormatProperties extFormatProps; 198 199 // Populated later when device is available. 200 uint32_t memoryTypeBits = 0; 201 bool memoryTypeBitsKnown = false; 202 }; 203 204 std::vector<ImageSupportInfo> imageSupportInfo; 205 206 struct DeviceSupportInfo { 207 bool hasGraphicsQueueFamily = false; 208 bool hasComputeQueueFamily = false; 209 bool supportsExternalMemoryImport = false; 210 bool supportsExternalMemoryExport = false; 211 bool supportsDmaBuf = false; 212 bool supportsDriverProperties = false; 213 bool supportsExternalMemoryHostProps = false; 214 bool hasSamplerYcbcrConversionExtension = false; 215 bool supportsSamplerYcbcrConversion = false; 216 bool glInteropSupported = false; 217 bool hasNvidiaDeviceDiagnosticCheckpointsExtension = false; 218 bool supportsNvidiaDeviceDiagnosticCheckpoints = false; 219 bool supportsPrivateData = false; 220 221 std::vector<VkExtensionProperties> extensions; 222 223 std::vector<uint32_t> graphicsQueueFamilyIndices; 224 std::vector<uint32_t> computeQueueFamilyIndices; 225 226 VkPhysicalDeviceProperties physdevProps; 227 VkPhysicalDeviceMemoryProperties memProps; 228 VkPhysicalDeviceIDPropertiesKHR idProps; 229 VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalMemoryHostProps; 230 231 std::string driverVendor; 232 std::string driverVersion; 233 234 PFN_vkGetImageMemoryRequirements2KHR getImageMemoryRequirements2Func = nullptr; 235 PFN_vkGetBufferMemoryRequirements2KHR getBufferMemoryRequirements2Func = nullptr; 236 237 #ifdef _WIN32 238 PFN_vkGetMemoryWin32HandleKHR getMemoryHandleFunc = nullptr; 239 #else 240 PFN_vkGetMemoryFdKHR getMemoryHandleFunc = nullptr; 241 #endif 242 }; 243 244 struct ExternalMemoryInfo { 245 // Input fields 246 VkDeviceSize size; 247 uint32_t typeIndex; 248 249 // Output fields 250 uint32_t id = 0; 251 VkDeviceMemory memory = VK_NULL_HANDLE; 252 253 // host-mapping fields 254 // host virtual address (hva). 255 void* mappedPtr = nullptr; 256 // host virtual address, aligned to 4KB page. 257 void* pageAlignedHva = nullptr; 258 // the offset of |mappedPtr| off its memory page. 259 uint32_t pageOffset = 0u; 260 // the offset set in |vkBindImageMemory| or |vkBindBufferMemory|. 261 uint32_t bindOffset = 0u; 262 // the size of all the pages the memory uses. 263 size_t sizeToPage = 0u; 264 // guest physical address. 265 uintptr_t gpa = 0u; 266 267 VK_EXT_MEMORY_HANDLE externalHandle = VK_EXT_MEMORY_HANDLE_INVALID; 268 #ifdef __APPLE__ 269 // This is used as an external handle when MoltenVK is enabled 270 MTLResource_id externalMetalHandle = nullptr; 271 #endif 272 uint32_t streamHandleType; 273 274 bool dedicatedAllocation = false; 275 }; 276 277 // 128 mb staging buffer (really, just a few 4K frames or one 4k HDR frame) 278 // ought to be big enough for anybody! 279 static constexpr VkDeviceSize kDefaultStagingBufferSize = 128ULL * 1048576ULL; 280 281 struct StagingBufferInfo { 282 // TODO: Don't actually use this as external memory until host visible 283 // external is supported on all platforms 284 ExternalMemoryInfo memory; 285 VkBuffer buffer = VK_NULL_HANDLE; 286 VkDeviceSize size = kDefaultStagingBufferSize; 287 }; 288 289 enum class VulkanMode { 290 // Default: ColorBuffers can still be used with the existing GL-based 291 // API. Synchronization with (if it exists) Vulkan images happens on 292 // every one of the GL-based API calls: 293 // 294 // rcReadColorBuffer 295 // rcUpdateColorBuffer 296 // rcBindTexture 297 // rcBindRenderbuffer 298 // rcFlushWindowColorBuffer 299 // 300 // either through explicit CPU copies or implicit in the host driver 301 // if OpenGL interop is supported. 302 // 303 // When images are posted (rcFBPost), 304 // eglSwapBuffers is used, even if that requires a CPU readback. 305 306 Default = 0, 307 308 // VulkanOnly: It is assumed that the guest interacts entirely with 309 // the underlying Vulkan image in the guest and does not use the 310 // GL-based API. This means we can assume those APIs are not called: 311 // 312 // rcReadColorBuffer 313 // rcUpdateColorBuffer 314 // rcBindTexture 315 // rcBindRenderbuffer 316 // rcFlushWindowColorBuffer 317 // 318 // and thus we skip a lot of GL/Vk synchronization. 319 // 320 // When images are posted, eglSwapBuffers is only used if OpenGL 321 // interop is supported. If OpenGL interop is not supported, then we 322 // use a host platform-specific Vulkan swapchain to display the 323 // results. 324 325 VulkanOnly = 1, 326 }; 327 struct ColorBufferInfo { 328 ExternalMemoryInfo memory; 329 330 uint32_t handle; 331 332 /* Set in create(), before initialize() */ 333 uint32_t width; 334 uint32_t height; 335 GLenum internalFormat; 336 uint32_t memoryProperty; 337 int frameworkFormat; 338 int frameworkStride; 339 bool initialized = false; 340 341 VkImage image = VK_NULL_HANDLE; 342 VkImageView imageView = VK_NULL_HANDLE; 343 VkSamplerYcbcrConversion ycbcrConversion = VK_NULL_HANDLE; 344 VkImageCreateInfo imageCreateInfoShallow = {}; 345 VkMemoryRequirements memReqs; 346 347 VkImageLayout currentLayout = VK_IMAGE_LAYOUT_UNDEFINED; 348 uint32_t currentQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL; 349 350 bool glExported = false; 351 bool externalMemoryCompatible = false; 352 353 VulkanMode vulkanMode = VulkanMode::Default; 354 355 std::optional<DeviceOpWaitable> latestUse; 356 DeviceOpTrackerPtr latestUseTracker = nullptr; 357 }; 358 359 struct BufferInfo { 360 ExternalMemoryInfo memory; 361 uint32_t handle; 362 363 VkDeviceSize size; 364 VkBufferCreateFlags createFlags; 365 VkBufferUsageFlags usageFlags; 366 VkSharingMode sharingMode; 367 368 VkBuffer buffer = VK_NULL_HANDLE; 369 VkMemoryRequirements memReqs; 370 371 bool glExported = false; 372 VulkanMode vulkanMode = VulkanMode::Default; 373 }; 374 375 // Track what is supported on whatever device was selected. 376 DeviceSupportInfo deviceInfo; 377 378 // Track additional vulkan diagnostics 379 uint32_t vulkanInstanceVersion; 380 std::vector<VkExtensionProperties> instanceExtensions; 381 382 // A single staging buffer to perform most transfers to/from OpenGL on the 383 // host. It is shareable across instances. The memory is shareable but the 384 // buffer is not; other users need to create buffers that 385 // bind to imported versions of the memory. 386 StagingBufferInfo staging; 387 388 // ColorBuffers are intended to back the guest's shareable images. 389 // For example: 390 // Android: gralloc 391 // Fuchsia: ImagePipeHandle 392 // Linux: dmabuf 393 std::unordered_map<uint32_t, ColorBufferInfo> colorBuffers; 394 395 // Buffers are intended to back the guest's shareable Vulkan buffers. 396 std::unordered_map<uint32_t, BufferInfo> buffers; 397 398 // In order to support VK_KHR_external_memory_(fd|win32) we need also to 399 // support the concept of plain external memories that are just memory and 400 // not necessarily images. These are then intended to pass through to the 401 // guest in some way, with 1:1 mapping between guest and host external 402 // memory handles. 403 std::unordered_map<uint32_t, ExternalMemoryInfo> externalMemories; 404 405 // The host keeps a set of occupied guest memory addresses to avoid a 406 // host memory address mapped to guest twice. 407 std::unordered_set<uint64_t> occupiedGpas; 408 409 // We can also consider using a single external memory object to back all 410 // host visible allocations in the guest. This would save memory, but we 411 // would also need to automatically add 412 // VkExternalMemory(Image|Buffer)CreateInfo, or if it is already there, OR 413 // it with the handle types on the host. 414 // A rough sketch: Some memories/images/buffers in the guest 415 // are backed by host visible memory: 416 // There is already a virtual memory type for those things in the current 417 // implementation. The guest doesn't know whether the pointer or the 418 // VkDeviceMemory object is backed by host external or non external. 419 // TODO: are all possible buffer / image usages compatible with 420 // external backing? 421 // TODO: try switching to this 422 ExternalMemoryInfo virtualHostVisibleHeap; 423 424 // Every command buffer in the pool is associated with a VkFence which is 425 // signaled only if the command buffer completes. 426 std::vector<std::tuple<VkCommandBuffer, VkFence>> transferQueueCommandBufferPool; 427 428 std::unique_ptr<CompositorVk> compositorVk; 429 430 // The implementation for Vulkan native swapchain. Only initialized in initVkEmulationFeatures 431 // if useVulkanNativeSwapchain is set. 432 std::unique_ptr<DisplayVk> displayVk; 433 434 struct RepresentativeColorBufferMemoryTypeInfo { 435 // The host memory type index used for Buffer/ColorBuffer allocations. 436 uint32_t hostMemoryTypeIndex; 437 438 // The guest memory type index that will be returned to guest processes querying 439 // the memory type index of host AHardwareBuffer/ColorBuffer allocations. This may 440 // point to an emulated memory type so that the host can control which memory flags are 441 // exposed to the guest (i.e. hide VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT from the guest). 442 uint32_t guestMemoryTypeIndex; 443 }; 444 std::optional<RepresentativeColorBufferMemoryTypeInfo> representativeColorBufferMemoryTypeInfo; 445 }; 446 447 VkEmulation* createGlobalVkEmulation(VulkanDispatch* vk, 448 gfxstream::host::BackendCallbacks callbacks, 449 gfxstream::host::FeatureSet features); 450 451 struct VkEmulationFeatures { 452 bool glInteropSupported = false; 453 bool deferredCommands = false; 454 bool createResourceWithRequirements = false; 455 bool useVulkanComposition = false; 456 bool useVulkanNativeSwapchain = false; 457 std::unique_ptr<emugl::RenderDocWithMultipleVkInstances> guestRenderDoc = nullptr; 458 AstcEmulationMode astcLdrEmulationMode = AstcEmulationMode::Disabled; 459 bool enableEtc2Emulation = false; 460 bool enableYcbcrEmulation = false; 461 bool guestVulkanOnly = false; 462 bool useDedicatedAllocations = false; 463 }; 464 void initVkEmulationFeatures(std::unique_ptr<VkEmulationFeatures>); 465 466 VkEmulation* getGlobalVkEmulation(); 467 void teardownGlobalVkEmulation(); 468 469 void onVkDeviceLost(); 470 471 std::unique_ptr<gfxstream::DisplaySurface> createDisplaySurface(FBNativeWindowType window, 472 uint32_t width, uint32_t height); 473 474 bool allocExternalMemory( 475 VulkanDispatch* vk, VkEmulation::ExternalMemoryInfo* info, bool actuallyExternal = true, 476 android::base::Optional<uint64_t> deviceAlignment = android::base::kNullopt, 477 android::base::Optional<VkBuffer> bufferForDedicatedAllocation = android::base::kNullopt, 478 android::base::Optional<VkImage> imageForDedicatedAllocation = android::base::kNullopt); 479 void freeExternalMemoryLocked(VulkanDispatch* vk, VkEmulation::ExternalMemoryInfo* info); 480 481 bool importExternalMemory(VulkanDispatch* vk, VkDevice targetDevice, 482 const VkEmulation::ExternalMemoryInfo* info, VkDeviceMemory* out); 483 bool importExternalMemoryDedicatedImage(VulkanDispatch* vk, VkDevice targetDevice, 484 const VkEmulation::ExternalMemoryInfo* info, VkImage image, 485 VkDeviceMemory* out); 486 487 // ColorBuffer operations 488 489 bool getColorBufferShareInfo(uint32_t colorBufferHandle, bool* glExported, 490 bool* externalMemoryCompatible); 491 492 bool getColorBufferAllocationInfo(uint32_t colorBufferHandle, VkDeviceSize* outSize, 493 uint32_t* outMemoryTypeIndex, bool* outMemoryIsDedicatedAlloc, 494 void** outMappedPtr); 495 496 std::unique_ptr<VkImageCreateInfo> generateColorBufferVkImageCreateInfo(VkFormat format, 497 uint32_t width, 498 uint32_t height, 499 VkImageTiling tiling); 500 501 bool isFormatSupported(GLenum format); 502 503 bool createVkColorBuffer(uint32_t width, uint32_t height, GLenum format, 504 FrameworkFormat frameworkFormat, uint32_t colorBufferHandle, 505 bool vulkanOnly, uint32_t memoryProperty); 506 507 bool teardownVkColorBuffer(uint32_t colorBufferHandle); 508 509 bool importExtMemoryHandleToVkColorBuffer(uint32_t colorBufferHandle, uint32_t type, 510 VK_EXT_MEMORY_HANDLE extMemHandle); 511 512 VkEmulation::ColorBufferInfo getColorBufferInfo(uint32_t colorBufferHandle); 513 VK_EXT_MEMORY_HANDLE getColorBufferExtMemoryHandle(uint32_t colorBufferHandle); 514 #ifdef __APPLE__ 515 MTLResource_id getColorBufferMetalMemoryHandle(uint32_t colorBufferHandle); 516 VkImage getColorBufferVkImage(uint32_t colorBufferHandle); 517 #endif 518 519 struct VkColorBufferMemoryExport { 520 android::base::ManagedDescriptor descriptor; 521 uint64_t size = 0; 522 uint32_t streamHandleType = 0; 523 bool linearTiling = false; 524 bool dedicatedAllocation = false; 525 }; 526 std::optional<VkColorBufferMemoryExport> exportColorBufferMemory(uint32_t colorBufferHandle); 527 528 bool setColorBufferVulkanMode(uint32_t colorBufferHandle, uint32_t vulkanMode); 529 int32_t mapGpaToBufferHandle(uint32_t bufferHandle, uint64_t gpa, uint64_t size = 0); 530 531 bool colorBufferNeedsUpdateBetweenGlAndVk(uint32_t colorBufferHandle); 532 533 bool readColorBufferToBytes(uint32_t colorBufferHandle, std::vector<uint8_t>* bytes); 534 bool readColorBufferToBytes(uint32_t colorBufferHandle, uint32_t x, uint32_t y, uint32_t w, 535 uint32_t h, void* outPixels, uint64_t outPixelsSize); 536 bool readColorBufferToBytesLocked(uint32_t colorBufferHandle, uint32_t x, uint32_t y, uint32_t w, 537 uint32_t h, void* outPixels, uint64_t outPixelsSize); 538 539 bool updateColorBufferFromBytes(uint32_t colorBufferHandle, const std::vector<uint8_t>& bytes); 540 bool updateColorBufferFromBytes(uint32_t colorBufferHandle, uint32_t x, uint32_t y, uint32_t w, 541 uint32_t h, const void* pixels); 542 543 // Data buffer operations 544 bool getBufferAllocationInfo(uint32_t bufferHandle, VkDeviceSize* outSize, 545 uint32_t* outMemoryTypeIndex, bool* outMemoryIsDedicatedAlloc); 546 547 bool setupVkBuffer(uint64_t size, uint32_t bufferHandle, bool vulkanOnly = false, 548 uint32_t memoryProperty = 0); 549 bool teardownVkBuffer(uint32_t bufferHandle); 550 551 VK_EXT_MEMORY_HANDLE getBufferExtMemoryHandle(uint32_t bufferHandle, uint32_t* outStreamHandleType); 552 #ifdef __APPLE__ 553 MTLResource_id getBufferMetalMemoryHandle(uint32_t bufferHandle); 554 #endif 555 556 bool readBufferToBytes(uint32_t bufferHandle, uint64_t offset, uint64_t size, void* outBytes); 557 bool updateBufferFromBytes(uint32_t bufferHandle, uint64_t offset, uint64_t size, 558 const void* bytes); 559 560 VkExternalMemoryHandleTypeFlags transformExternalMemoryHandleTypeFlags_tohost( 561 VkExternalMemoryHandleTypeFlags bits); 562 563 VkExternalMemoryHandleTypeFlags transformExternalMemoryHandleTypeFlags_fromhost( 564 VkExternalMemoryHandleTypeFlags hostBits, 565 VkExternalMemoryHandleTypeFlags wantedGuestHandleType); 566 567 VkExternalMemoryProperties transformExternalMemoryProperties_tohost( 568 VkExternalMemoryProperties props); 569 570 VkExternalMemoryProperties transformExternalMemoryProperties_fromhost( 571 VkExternalMemoryProperties props, VkExternalMemoryHandleTypeFlags wantedGuestHandleType); 572 573 void setColorBufferCurrentLayout(uint32_t colorBufferHandle, VkImageLayout); 574 575 VkImageLayout getColorBufferCurrentLayout(uint32_t colorBufferHandle); 576 577 void setColorBufferLatestUse(uint32_t colorBufferHandle, DeviceOpWaitable waitable, 578 DeviceOpTrackerPtr tracker); 579 580 int waitSyncVkColorBuffer(uint32_t colorBufferHandle); 581 582 void releaseColorBufferForGuestUse(uint32_t colorBufferHandle); 583 584 std::unique_ptr<BorrowedImageInfoVk> borrowColorBufferForComposition(uint32_t colorBufferHandle, 585 bool colorBufferIsTarget); 586 std::unique_ptr<BorrowedImageInfoVk> borrowColorBufferForDisplay(uint32_t colorBufferHandle); 587 588 } // namespace vk 589 } // namespace gfxstream 590