• 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 #include "VkDecoderGlobalState.h"
15 
16 #include <algorithm>
17 #include <functional>
18 #include <list>
19 #include <memory>
20 #include <mutex>
21 #include <unordered_map>
22 #include <vector>
23 
24 #include "FrameBuffer.h"
25 #include "GraphicsDriverLock.h"
26 #include "RenderThreadInfoVk.h"
27 #include "TrivialStream.h"
28 #include "VkAndroidNativeBuffer.h"
29 #include "VkCommonOperations.h"
30 #include "VkDecoderContext.h"
31 #include "VkDecoderInternalStructs.h"
32 #include "VkDecoderSnapshot.h"
33 #include "VkDecoderSnapshotUtils.h"
34 #include "VkEmulatedPhysicalDeviceMemory.h"
35 #include "VkEmulatedPhysicalDeviceQueue.h"
36 #include "VulkanBoxedHandles.h"
37 #include "VulkanDispatch.h"
38 #include "VulkanStream.h"
39 #include "aemu/base/Optional.h"
40 #include "aemu/base/ThreadAnnotations.h"
41 #include "aemu/base/containers/Lookup.h"
42 #include "aemu/base/files/Stream.h"
43 #include "aemu/base/memory/SharedMemory.h"
44 #include "aemu/base/synchronization/Lock.h"
45 #include "aemu/base/system/System.h"
46 #include "common/goldfish_vk_deepcopy.h"
47 #include "common/goldfish_vk_dispatch.h"
48 #include "common/goldfish_vk_marshaling.h"
49 #include "common/goldfish_vk_reserved_marshaling.h"
50 #include "compressedTextureFormats/AstcCpuDecompressor.h"
51 #include "gfxstream/host/Tracing.h"
52 #include "host-common/GfxstreamFatalError.h"
53 #include "host-common/HostmemIdMapping.h"
54 #include "host-common/address_space_device_control_ops.h"
55 #include "host-common/emugl_vm_operations.h"
56 #include "host-common/vm_operations.h"
57 #include "utils/RenderDoc.h"
58 #include "vk_util.h"
59 #include "vulkan/VkFormatUtils.h"
60 #include "vulkan/emulated_textures/AstcTexture.h"
61 #include "vulkan/emulated_textures/CompressedImageInfo.h"
62 #include "vulkan/emulated_textures/GpuDecompressionPipeline.h"
63 #include "vulkan/vk_enum_string_helper.h"
64 #include "vulkan/vulkan_core.h"
65 
66 #ifndef _WIN32
67 #include <unistd.h>
68 #endif
69 
70 #ifdef __APPLE__
71 #include <CoreFoundation/CoreFoundation.h>
72 #include <vulkan/vulkan_beta.h> // for MoltenVK portability extensions
73 #endif
74 
75 #ifndef VERBOSE
76 #define VERBOSE(fmt, ...)                    \
77     if (android::base::isVerboseLogging()) { \
78         INFO(fmt, ##__VA_ARGS__);            \
79     }
80 #endif
81 
82 // Verbose logging only when ANDROID_EMU_VK_LOG_CALLS is set
83 #define LOG_CALLS_VERBOSE(fmt, ...)  \
84     if (mLogging) {                  \
85         VERBOSE(fmt, ##__VA_ARGS__); \
86     }
87 
88 #include <climits>
89 
90 namespace gfxstream {
91 namespace vk {
92 
93 using android::base::AutoLock;
94 using android::base::DescriptorType;
95 using android::base::Lock;
96 using android::base::MetricEventBadPacketLength;
97 using android::base::MetricEventDuplicateSequenceNum;
98 using android::base::MetricEventVulkanOutOfMemory;
99 using android::base::Optional;
100 using android::base::SharedMemory;
101 using android::base::StaticLock;
102 using emugl::ABORT_REASON_OTHER;
103 using emugl::FatalError;
104 using emugl::GfxApiLogger;
105 using gfxstream::ExternalObjectManager;
106 using gfxstream::VulkanInfo;
107 
108 // TODO(b/261477138): Move to a shared aemu definition
109 #define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
110 #define __ALIGN(x, a) __ALIGN_MASK(x, (__typeof__(x))(a)-1)
111 
112 #define VKDGS_DEBUG 0
113 
114 #if VKDGS_DEBUG
115 #define VKDGS_LOG(fmt, ...) INFO
116 #else
117 #define VKDGS_LOG(fmt, ...)
118 #endif
119 
120 // Blob mem
121 #define STREAM_BLOB_MEM_GUEST 1
122 #define STREAM_BLOB_MEM_HOST3D 2
123 #define STREAM_BLOB_MEM_HOST3D_GUEST 3
124 
125 // Blob flags
126 #define STREAM_BLOB_FLAG_USE_MAPPABLE 1
127 #define STREAM_BLOB_FLAG_USE_SHAREABLE 2
128 #define STREAM_BLOB_FLAG_USE_CROSS_DEVICE 4
129 #define STREAM_BLOB_FLAG_CREATE_GUEST_HANDLE 8
130 
131 #define VALIDATE_REQUIRED_HANDLE(parameter) \
132     validateRequiredHandle(__FUNCTION__, #parameter, parameter)
133 
134 template <typename T>
validateRequiredHandle(const char * api_name,const char * parameter_name,T value)135 void validateRequiredHandle(const char* api_name, const char* parameter_name, T value) {
136     if (value == VK_NULL_HANDLE) {
137         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << api_name << ":" << parameter_name;
138     }
139 }
140 
141 #define VALIDATE_NEW_HANDLE_INFO_ENTRY(objectMap, newEntry) \
142     validateNewHandleInfoEntry(objectMap, newEntry, #objectMap)
143 
144 template <typename T, typename K>
validateNewHandleInfoEntry(const std::unordered_map<T,K> & vkObjectMap,const T & newEntry,const char * typeName)145 void validateNewHandleInfoEntry(const std::unordered_map<T, K>& vkObjectMap, const T& newEntry,
146                                 const char* typeName) {
147     if (vkObjectMap.find(newEntry) != vkObjectMap.end()) {
148         ERR("Found duplicate in %s (%p)!", typeName, newEntry);
149     }
150 }
151 
dupExternalSync(VK_EXT_SYNC_HANDLE h)152 VK_EXT_SYNC_HANDLE dupExternalSync(VK_EXT_SYNC_HANDLE h) {
153 #ifdef _WIN32
154     auto myProcessHandle = GetCurrentProcess();
155     VK_EXT_SYNC_HANDLE res;
156     DuplicateHandle(myProcessHandle, h,     // source process and handle
157                     myProcessHandle, &res,  // target process and pointer to handle
158                     0 /* desired access (ignored) */, true /* inherit */,
159                     DUPLICATE_SAME_ACCESS /* same access option */);
160     return res;
161 #else
162     return dup(h);
163 #endif
164 }
165 
166 // A list of device extensions that should not be passed to the host driver.
167 // These will mainly include Vulkan features that we emulate ourselves.
168 static constexpr const char* const kEmulatedDeviceExtensions[] = {
169     "VK_ANDROID_external_memory_android_hardware_buffer",
170     "VK_ANDROID_native_buffer",
171     "VK_FUCHSIA_buffer_collection",
172     "VK_FUCHSIA_external_memory",
173     "VK_FUCHSIA_external_semaphore",
174     VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME,
175     VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME,
176     VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
177     VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
178     VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
179     VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME,
180     VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME,
181     VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME,
182 #if defined(__QNX__)
183     VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
184     VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME,
185 #endif
186 };
187 
188 // A list of instance extensions that should not be passed to the host driver.
189 // On older pre-1.1 Vulkan platforms, gfxstream emulates these features.
190 static constexpr const char* const kEmulatedInstanceExtensions[] = {
191     VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME,
192     VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
193     VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
194 };
195 
196 static constexpr uint32_t kMaxSafeVersion = VK_MAKE_VERSION(1, 3, 0);
197 static constexpr uint32_t kMinVersion = VK_MAKE_VERSION(1, 0, 0);
198 
199 static constexpr uint64_t kPageSizeforBlob = 4096;
200 static constexpr uint64_t kPageMaskForBlob = ~(0xfff);
201 
202 static std::atomic<uint64_t> sNextHostBlobId{1};
203 
204 class VkDecoderGlobalState::Impl {
205    public:
Impl(VkEmulation * emulation)206     Impl(VkEmulation* emulation)
207         : m_vk(vkDispatch()),
208           m_vkEmulation(emulation),
209           mRenderDocWithMultipleVkInstances(m_vkEmulation->getRenderDoc()) {
210         mSnapshotsEnabled = m_vkEmulation->getFeatures().VulkanSnapshots.enabled;
211         mBatchedDescriptorSetUpdateEnabled =
212             m_vkEmulation->getFeatures().VulkanBatchedDescriptorSetUpdate.enabled;
213         mVkCleanupEnabled =
214             android::base::getEnvironmentVariable("ANDROID_EMU_VK_NO_CLEANUP") != "1";
215         mLogging = android::base::getEnvironmentVariable("ANDROID_EMU_VK_LOG_CALLS") == "1";
216         mVerbosePrints = android::base::getEnvironmentVariable("ANDROID_EMUGL_VERBOSE") == "1";
217 
218         if (get_emugl_address_space_device_control_ops().control_get_hw_funcs &&
219             get_emugl_address_space_device_control_ops().control_get_hw_funcs()) {
220             mUseOldMemoryCleanupPath = 0 == get_emugl_address_space_device_control_ops()
221                                                 .control_get_hw_funcs()
222                                                 ->getPhysAddrStartLocked();
223         }
224     }
225 
226     ~Impl() = default;
227 
228     // Resets all internal tracking info.
229     // Assumes that the heavyweight cleanup operations have already happened.
clearLocked()230     void clearLocked() REQUIRES(mMutex) {
231         mInstanceInfo.clear();
232         mPhysdevInfo.clear();
233         mDeviceInfo.clear();
234         mImageInfo.clear();
235         mImageViewInfo.clear();
236         mSamplerInfo.clear();
237         mCommandBufferInfo.clear();
238         mCommandPoolInfo.clear();
239         mDeviceToPhysicalDevice.clear();
240         mPhysicalDeviceToInstance.clear();
241         mQueueInfo.clear();
242         mBufferInfo.clear();
243         mMemoryInfo.clear();
244         mShaderModuleInfo.clear();
245         mPipelineCacheInfo.clear();
246         mPipelineLayoutInfo.clear();
247         mPipelineInfo.clear();
248         mRenderPassInfo.clear();
249         mFramebufferInfo.clear();
250         mSemaphoreInfo.clear();
251         mFenceInfo.clear();
252 #ifdef _WIN32
253         mSemaphoreId = 1;
254         mExternalSemaphoresById.clear();
255 #endif
256         mDescriptorUpdateTemplateInfo.clear();
257 
258         sBoxedHandleManager.clear();
259 
260         mSnapshot.clear();
261     }
262 
snapshotsEnabled() const263     bool snapshotsEnabled() const { return mSnapshotsEnabled; }
264 
batchedDescriptorSetUpdateEnabled() const265     bool batchedDescriptorSetUpdateEnabled() const { return mBatchedDescriptorSetUpdateEnabled; }
266 
vkCleanupEnabled() const267     bool vkCleanupEnabled() const { return mVkCleanupEnabled; }
268 
getFeatures() const269     const gfxstream::host::FeatureSet& getFeatures() const { return m_vkEmulation->getFeatures(); }
270 
createSnapshotStateBlock(VkDevice unboxed_device)271     StateBlock createSnapshotStateBlock(VkDevice unboxed_device) REQUIRES(mMutex) {
272         const auto& device = unboxed_device;
273         const auto& deviceInfo = android::base::find(mDeviceInfo, device);
274         const auto physicalDevice = deviceInfo->physicalDevice;
275         const auto& physicalDeviceInfo = android::base::find(mPhysdevInfo, physicalDevice);
276         const auto& instanceInfo = android::base::find(mInstanceInfo, physicalDeviceInfo->instance);
277 
278         VulkanDispatch* ivk = dispatch_VkInstance(instanceInfo->boxed);
279         VulkanDispatch* dvk = dispatch_VkDevice(deviceInfo->boxed);
280 
281         StateBlock stateBlock{
282             .physicalDevice = physicalDevice,
283             .physicalDeviceInfo = physicalDeviceInfo,
284             .device = device,
285             .deviceDispatch = dvk,
286             .queue = VK_NULL_HANDLE,
287             .commandPool = VK_NULL_HANDLE,
288         };
289 
290         uint32_t queueFamilyCount = 0;
291         ivk->vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, nullptr);
292         std::vector<VkQueueFamilyProperties> queueFamilyProps(queueFamilyCount);
293         ivk->vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount,
294                                                       queueFamilyProps.data());
295         uint32_t queueFamilyIndex = 0;
296         for (auto queue : deviceInfo->queues) {
297             int idx = queue.first;
298             if ((queueFamilyProps[idx].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0) {
299                 continue;
300             }
301             stateBlock.queue = queue.second[0];
302             queueFamilyIndex = idx;
303             break;
304         }
305 
306         VkCommandPoolCreateInfo commandPoolCi = {
307             VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
308             0,
309             VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
310             queueFamilyIndex,
311         };
312         dvk->vkCreateCommandPool(device, &commandPoolCi, nullptr, &stateBlock.commandPool);
313         return stateBlock;
314     }
315 
releaseSnapshotStateBlock(const StateBlock * stateBlock)316     void releaseSnapshotStateBlock(const StateBlock* stateBlock) {
317         stateBlock->deviceDispatch->vkDestroyCommandPool(stateBlock->device, stateBlock->commandPool, nullptr);
318     }
319 
save(android::base::Stream * stream)320     void save(android::base::Stream* stream) {
321         VERBOSE("VulkanSnapshots save (begin)");
322         std::lock_guard<std::mutex> lock(mMutex);
323 
324         mSnapshotState = SnapshotState::Saving;
325 
326 #ifdef CONFIG_AEMU
327         if (!mInstanceInfo.empty()) {
328             get_emugl_vm_operations().setStatSnapshotUseVulkan();
329         }
330 #endif
331 
332         VERBOSE("snapshot save: setup internal structures");
333         {
334             std::unordered_map<VkDevice, uint32_t> deviceToContextId;
335             for (const auto& [device, deviceInfo] : mDeviceInfo) {
336                 if (!deviceInfo.virtioGpuContextId) {
337                     GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
338                         << "VkDevice" << device << " missing context id.";
339                 }
340                 deviceToContextId[deviceInfo.boxed] = *deviceInfo.virtioGpuContextId;
341             }
342             stream->putBe64(static_cast<uint64_t>(deviceToContextId.size()));
343             for (const auto [device, contextId] : deviceToContextId) {
344                 stream->putBe64(reinterpret_cast<uint64_t>(device));
345                 stream->putBe32(contextId);
346             }
347         }
348 
349         VERBOSE("snapshot save: replay command stream");
350         snapshot()->saveReplayBuffers(stream);
351 
352         // Save mapped memory
353         uint32_t memoryCount = 0;
354         for (const auto& it : mMemoryInfo) {
355             if (it.second.ptr) {
356                 memoryCount++;
357             }
358         }
359         VERBOSE("snapshot save: mapped memory");
360         stream->putBe32(memoryCount);
361         for (const auto& it : mMemoryInfo) {
362             if (!it.second.ptr) {
363                 continue;
364             }
365             stream->putBe64(reinterpret_cast<uint64_t>(
366                 unboxed_to_boxed_non_dispatchable_VkDeviceMemory(it.first)));
367             stream->putBe64(it.second.size);
368             stream->write(it.second.ptr, it.second.size);
369         }
370 
371         // Set up VK structs to snapshot other Vulkan objects
372         // TODO(b/323064243): group all images from the same device and reuse queue / command pool
373 
374         VERBOSE("snapshot save: image content");
375         std::vector<VkImage> sortedBoxedImages;
376         for (const auto& imageIte : mImageInfo) {
377             sortedBoxedImages.push_back(unboxed_to_boxed_non_dispatchable_VkImage(imageIte.first));
378         }
379         // Image contents need to be saved and loaded in the same order.
380         // So sort them (by boxed handles) first.
381         std::sort(sortedBoxedImages.begin(), sortedBoxedImages.end());
382         for (const auto& boxedImage : sortedBoxedImages) {
383             auto unboxedImage = try_unbox_VkImage(boxedImage);
384             if (unboxedImage == VK_NULL_HANDLE) {
385                 // TODO(b/294277842): should return an error here.
386                 continue;
387             }
388             const ImageInfo& imageInfo = mImageInfo[unboxedImage];
389             if (imageInfo.memory == VK_NULL_HANDLE) {
390                 continue;
391             }
392             // Vulkan command playback doesn't recover image layout. We need to do it here.
393             stream->putBe32(imageInfo.layout);
394 
395             StateBlock stateBlock = createSnapshotStateBlock(imageInfo.device);
396             // TODO(b/294277842): make sure the queue is empty before using.
397             saveImageContent(stream, &stateBlock, unboxedImage, &imageInfo);
398             releaseSnapshotStateBlock(&stateBlock);
399         }
400 
401         // snapshot buffers
402         VERBOSE("snapshot save: buffers");
403         std::vector<VkBuffer> sortedBoxedBuffers;
404         for (const auto& bufferIte : mBufferInfo) {
405             sortedBoxedBuffers.push_back(
406                 unboxed_to_boxed_non_dispatchable_VkBuffer(bufferIte.first));
407         }
408         sort(sortedBoxedBuffers.begin(), sortedBoxedBuffers.end());
409         for (const auto& boxedBuffer : sortedBoxedBuffers) {
410             auto unboxedBuffer = try_unbox_VkBuffer(boxedBuffer);
411             if (unboxedBuffer == VK_NULL_HANDLE) {
412                 // TODO(b/294277842): should return an error here.
413                 continue;
414             }
415             const BufferInfo& bufferInfo = mBufferInfo[unboxedBuffer];
416             if (bufferInfo.memory == VK_NULL_HANDLE) {
417                 continue;
418             }
419             // TODO: add a special case for host mapped memory
420             StateBlock stateBlock = createSnapshotStateBlock(bufferInfo.device);
421 
422             // TODO(b/294277842): make sure the queue is empty before using.
423             saveBufferContent(stream, &stateBlock, unboxedBuffer, &bufferInfo);
424             releaseSnapshotStateBlock(&stateBlock);
425         }
426 
427         // snapshot descriptors
428         VERBOSE("snapshot save: descriptors");
429         std::vector<VkDescriptorPool> sortedBoxedDescriptorPools;
430         for (const auto& descriptorPoolIte : mDescriptorPoolInfo) {
431             auto boxed =
432                 unboxed_to_boxed_non_dispatchable_VkDescriptorPool(descriptorPoolIte.first);
433             sortedBoxedDescriptorPools.push_back(boxed);
434         }
435         std::sort(sortedBoxedDescriptorPools.begin(), sortedBoxedDescriptorPools.end());
436         for (const auto& boxedDescriptorPool : sortedBoxedDescriptorPools) {
437             auto unboxedDescriptorPool = unbox_VkDescriptorPool(boxedDescriptorPool);
438             const DescriptorPoolInfo& poolInfo = mDescriptorPoolInfo[unboxedDescriptorPool];
439 
440             for (uint64_t poolId : poolInfo.poolIds) {
441                 BoxedHandleInfo* setHandleInfo = sBoxedHandleManager.get(poolId);
442                 bool allocated = setHandleInfo->underlying != 0;
443                 stream->putByte(allocated);
444                 if (!allocated) {
445                     continue;
446                 }
447 
448                 const DescriptorSetInfo& descriptorSetInfo =
449                     mDescriptorSetInfo[(VkDescriptorSet)setHandleInfo->underlying];
450                 VkDescriptorSetLayout boxedLayout =
451                     unboxed_to_boxed_non_dispatchable_VkDescriptorSetLayout(
452                         descriptorSetInfo.unboxedLayout);
453                 stream->putBe64((uint64_t)boxedLayout);
454                 // Count all valid descriptors.
455                 //
456                 // There is a use case where user can create an image, write it to a descriptor,
457                 // read/write the image by committing a command, then delete the image without
458                 // unbinding the descriptor. For example:
459                 //
460                 // T1: create "vkimage1" (original)
461                 // T2: update binding1 of vkdescriptorset1 with vkimage1
462                 // T3: draw
463                 // T4: delete "vkimage1" (original)
464                 // T5: create "vkimage1" (recycled)
465                 // T6: snapshot load
466                 //
467                 // At the point of the snapshot, the original vk image has been invalidated,
468                 // thus we cannot call vkUpdateDescriptorSets for it, and need to remove it
469                 // from the snapshot.
470                 //
471                 // The current implementation bases on smart pointers. A descriptor set info
472                 // holds weak pointers to their underlying resources (image, image view, buffer).
473                 // On snapshot load, we check if any of the smart pointers are invalidated.
474                 //
475                 // An alternative approach has been discussed by, instead of using smart
476                 // pointers, checking valid handles on snapshot save. This approach has the
477                 // advantage that it reduces number of smart pointer allocations. After discussion
478                 // we concluded that there is at least one corner case that will break the
479                 // alternative approach. That is when the user deletes a bound vkimage and creates
480                 // a new vkimage. The driver is free to reuse released handles, thus we might
481                 // end up having a new vkimage with the same handle as the old one (see T5 in the
482                 // example), and think the binding is still valid. And if we bind the new image
483                 // regardless, we might hit a Vulkan validation error because the new image might
484                 // have the "usage" flag that is unsuitable to bind to descriptors.
485                 std::vector<std::pair<int, int>> validWriteIndices;
486                 for (int bindingIdx = 0; bindingIdx < (int)descriptorSetInfo.allWrites.size();
487                      bindingIdx++) {
488                     for (int bindingElemIdx = 0;
489                          bindingElemIdx < (int)descriptorSetInfo.allWrites[bindingIdx].size();
490                          bindingElemIdx++) {
491                         const auto& entry = descriptorSetInfo.allWrites[bindingIdx][bindingElemIdx];
492                         if (entry.writeType == DescriptorSetInfo::DescriptorWriteType::Empty) {
493                             continue;
494                         }
495                         int dependencyObjCount =
496                             descriptorDependencyObjectCount(entry.descriptorType);
497                         if ((int)entry.alives.size() < dependencyObjCount) {
498                             continue;
499                         }
500                         bool isValid = true;
501                         for (const auto& alive : entry.alives) {
502                             isValid &= !alive.expired();
503                             if (!isValid) {
504                                 break;
505                             }
506                         }
507                         if (!isValid) {
508                             continue;
509                         }
510                         validWriteIndices.push_back(std::make_pair(bindingIdx, bindingElemIdx));
511                     }
512                 }
513                 stream->putBe64(validWriteIndices.size());
514                 // Save all valid descriptors
515                 for (const auto& idx : validWriteIndices) {
516                     const auto& entry = descriptorSetInfo.allWrites[idx.first][idx.second];
517                     stream->putBe32(idx.first);
518                     stream->putBe32(idx.second);
519                     stream->putBe32(entry.writeType);
520                     // entry.descriptorType might be redundant.
521                     stream->putBe32(entry.descriptorType);
522                     switch (entry.writeType) {
523                         case DescriptorSetInfo::DescriptorWriteType::ImageInfo: {
524                             VkDescriptorImageInfo imageInfo = entry.imageInfo;
525                             // Get the unboxed version
526                             imageInfo.imageView =
527                                 descriptorTypeContainsImage(entry.descriptorType)
528                                     ? unboxed_to_boxed_non_dispatchable_VkImageView(
529                                           imageInfo.imageView)
530                                     : VK_NULL_HANDLE;
531                             imageInfo.sampler =
532                                 descriptorTypeContainsSampler(entry.descriptorType)
533                                     ? unboxed_to_boxed_non_dispatchable_VkSampler(imageInfo.sampler)
534                                     : VK_NULL_HANDLE;
535                             stream->write(&imageInfo, sizeof(imageInfo));
536                         } break;
537                         case DescriptorSetInfo::DescriptorWriteType::BufferInfo: {
538                             VkDescriptorBufferInfo bufferInfo = entry.bufferInfo;
539                             // Get the unboxed version
540                             bufferInfo.buffer =
541                                 unboxed_to_boxed_non_dispatchable_VkBuffer(bufferInfo.buffer);
542                             stream->write(&bufferInfo, sizeof(bufferInfo));
543                         } break;
544                         case DescriptorSetInfo::DescriptorWriteType::BufferView: {
545                             // Get the unboxed version
546                             VkBufferView bufferView =
547                                 unboxed_to_boxed_non_dispatchable_VkBufferView(entry.bufferView);
548                             stream->write(&bufferView, sizeof(bufferView));
549                         } break;
550                         case DescriptorSetInfo::DescriptorWriteType::InlineUniformBlock:
551                         case DescriptorSetInfo::DescriptorWriteType::AccelerationStructure:
552                             // TODO
553                             GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
554                                 << "Encountered pending inline uniform block or acceleration "
555                                    "structure "
556                                    "desc write, abort (NYI)";
557                         default:
558                             break;
559                     }
560                 }
561             }
562         }
563 
564         // Fences
565         VERBOSE("snapshot save: fences");
566         std::vector<VkFence> unsignaledFencesBoxed;
567         for (const auto& fence : mFenceInfo) {
568             if (!fence.second.boxed) {
569                 continue;
570             }
571             const auto& device = fence.second.device;
572             const auto& deviceInfo = android::base::find(mDeviceInfo, device);
573             VulkanDispatch* dvk = dispatch_VkDevice(deviceInfo->boxed);
574             if (VK_NOT_READY == dvk->vkGetFenceStatus(device, fence.first)) {
575                 unsignaledFencesBoxed.push_back(fence.second.boxed);
576             }
577         }
578         stream->putBe64(unsignaledFencesBoxed.size());
579         stream->write(unsignaledFencesBoxed.data(), unsignaledFencesBoxed.size() * sizeof(VkFence));
580         mSnapshotState = SnapshotState::Normal;
581         VERBOSE("VulkanSnapshots save (end)");
582     }
583 
load(android::base::Stream * stream,GfxApiLogger & gfxLogger,HealthMonitor<> * healthMonitor)584     void load(android::base::Stream* stream, GfxApiLogger& gfxLogger,
585               HealthMonitor<>* healthMonitor) {
586         // assume that we already destroyed all instances
587         // from FrameBuffer's onLoad method.
588         VERBOSE("VulkanSnapshots load (begin)");
589 
590         // destroy all current internal data structures
591         VERBOSE("snapshot load: setup internal structures");
592         {
593             std::lock_guard<std::mutex> lock(mMutex);
594 
595             clearLocked();
596 
597             mSnapshotState = SnapshotState::Loading;
598 
599             // This needs to happen before the replay in the decoder so that virtio gpu context ids
600             // are available for operations involving `ExternalObjectManager`.
601             mSnapshotLoadVkDeviceToVirtioCpuContextId.emplace();
602             const uint64_t count = stream->getBe64();
603             for (uint64_t i = 0; i < count; i++) {
604                 const uint64_t device = stream->getBe64();
605                 const uint32_t contextId = stream->getBe32();
606                 (*mSnapshotLoadVkDeviceToVirtioCpuContextId)[reinterpret_cast<VkDevice>(device)] =
607                     contextId;
608             }
609         }
610 
611         // Replay command stream:
612         VERBOSE("snapshot load: replay command stream");
613         {
614             std::vector<uint64_t> handleReplayBuffer;
615             std::vector<uint8_t> decoderReplayBuffer;
616             VkDecoderSnapshot::loadReplayBuffers(stream, &handleReplayBuffer, &decoderReplayBuffer);
617 
618             sBoxedHandleManager.replayHandles(handleReplayBuffer);
619 
620             VkDecoder decoderForLoading;
621             // A decoder that is set for snapshot load will load up the created handles first,
622             // if any, allowing us to 'catch' the results as they are decoded.
623             decoderForLoading.setForSnapshotLoad(true);
624             TrivialStream trivialStream;
625 
626             // TODO: This needs to be the puid seqno ptr
627             auto resources = ProcessResources::create();
628             VkDecoderContext context = {
629                 .processName = nullptr,
630                 .gfxApiLogger = &gfxLogger,
631                 .healthMonitor = healthMonitor,
632             };
633             decoderForLoading.decode(decoderReplayBuffer.data(), decoderReplayBuffer.size(),
634                                      &trivialStream, resources.get(), context);
635         }
636 
637         {
638             std::lock_guard<std::mutex> lock(mMutex);
639 
640             // load mapped memory
641             VERBOSE("snapshot load: mapped memory");
642             uint32_t memoryCount = stream->getBe32();
643             for (uint32_t i = 0; i < memoryCount; i++) {
644                 VkDeviceMemory boxedMemory = reinterpret_cast<VkDeviceMemory>(stream->getBe64());
645                 VkDeviceMemory unboxedMemory = unbox_VkDeviceMemory(boxedMemory);
646                 auto it = mMemoryInfo.find(unboxedMemory);
647                 if (it == mMemoryInfo.end()) {
648                     GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
649                         << "Snapshot load failure: cannot find memory handle for " << boxedMemory;
650                 }
651                 VkDeviceSize size = stream->getBe64();
652                 if (size != it->second.size || !it->second.ptr) {
653                     GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
654                         << "Snapshot load failure: memory size does not match for " << boxedMemory;
655                 }
656                 stream->read(it->second.ptr, size);
657             }
658             // Set up VK structs to snapshot other Vulkan objects
659             // TODO(b/323064243): group all images from the same device and reuse queue / command
660             // pool
661 
662             VERBOSE("snapshot load: image content");
663             std::vector<VkImage> sortedBoxedImages;
664             for (const auto& imageIte : mImageInfo) {
665                 sortedBoxedImages.push_back(
666                     unboxed_to_boxed_non_dispatchable_VkImage(imageIte.first));
667             }
668             sort(sortedBoxedImages.begin(), sortedBoxedImages.end());
669             for (const auto& boxedImage : sortedBoxedImages) {
670                 auto unboxedImage = unbox_VkImage(boxedImage);
671                 ImageInfo& imageInfo = mImageInfo[unboxedImage];
672                 if (imageInfo.memory == VK_NULL_HANDLE) {
673                     continue;
674                 }
675                 // Playback doesn't recover image layout. We need to do it here.
676                 //
677                 // Layout transform was done by vkCmdPipelineBarrier but we don't record such
678                 // command directly. Instead, we memorize the current layout and add our own
679                 // vkCmdPipelineBarrier after load.
680                 //
681                 // We do the layout transform in loadImageContent. There are still use cases where
682                 // it should recover the layout but does not.
683                 //
684                 // TODO(b/323059453): fix corner cases when image contents cannot be properly
685                 // loaded.
686                 imageInfo.layout = static_cast<VkImageLayout>(stream->getBe32());
687                 StateBlock stateBlock = createSnapshotStateBlock(imageInfo.device);
688                 // TODO(b/294277842): make sure the queue is empty before using.
689                 loadImageContent(stream, &stateBlock, unboxedImage, &imageInfo);
690                 releaseSnapshotStateBlock(&stateBlock);
691             }
692 
693             // snapshot buffers
694             VERBOSE("snapshot load: buffers");
695             std::vector<VkBuffer> sortedBoxedBuffers;
696             for (const auto& bufferIte : mBufferInfo) {
697                 sortedBoxedBuffers.push_back(
698                     unboxed_to_boxed_non_dispatchable_VkBuffer(bufferIte.first));
699             }
700             sort(sortedBoxedBuffers.begin(), sortedBoxedBuffers.end());
701             for (const auto& boxedBuffer : sortedBoxedBuffers) {
702                 auto unboxedBuffer = unbox_VkBuffer(boxedBuffer);
703                 const BufferInfo& bufferInfo = mBufferInfo[unboxedBuffer];
704                 if (bufferInfo.memory == VK_NULL_HANDLE) {
705                     continue;
706                 }
707                 // TODO: add a special case for host mapped memory
708                 StateBlock stateBlock = createSnapshotStateBlock(bufferInfo.device);
709                 // TODO(b/294277842): make sure the queue is empty before using.
710                 loadBufferContent(stream, &stateBlock, unboxedBuffer, &bufferInfo);
711                 releaseSnapshotStateBlock(&stateBlock);
712             }
713 
714             // snapshot descriptors
715             VERBOSE("snapshot load: descriptors");
716             android::base::BumpPool bumpPool;
717             std::vector<VkDescriptorPool> sortedBoxedDescriptorPools;
718             for (const auto& descriptorPoolIte : mDescriptorPoolInfo) {
719                 auto boxed =
720                     unboxed_to_boxed_non_dispatchable_VkDescriptorPool(descriptorPoolIte.first);
721                 sortedBoxedDescriptorPools.push_back(boxed);
722             }
723             sort(sortedBoxedDescriptorPools.begin(), sortedBoxedDescriptorPools.end());
724             for (const auto& boxedDescriptorPool : sortedBoxedDescriptorPools) {
725                 auto unboxedDescriptorPool = unbox_VkDescriptorPool(boxedDescriptorPool);
726                 const DescriptorPoolInfo& poolInfo = mDescriptorPoolInfo[unboxedDescriptorPool];
727 
728                 std::vector<VkDescriptorSetLayout> layouts;
729                 std::vector<uint64_t> poolIds;
730                 std::vector<VkWriteDescriptorSet> writeDescriptorSets;
731                 std::vector<uint32_t> writeStartingIndices;
732 
733                 // Temporary structures for the pointers in VkWriteDescriptorSet.
734                 // Use unique_ptr so that the pointers don't change when vector resizes.
735                 std::vector<std::unique_ptr<VkDescriptorImageInfo>> tmpImageInfos;
736                 std::vector<std::unique_ptr<VkDescriptorBufferInfo>> tmpBufferInfos;
737                 std::vector<std::unique_ptr<VkBufferView>> tmpBufferViews;
738 
739                 for (uint64_t poolId : poolInfo.poolIds) {
740                     bool allocated = stream->getByte();
741                     if (!allocated) {
742                         continue;
743                     }
744                     poolIds.push_back(poolId);
745                     writeStartingIndices.push_back(writeDescriptorSets.size());
746                     VkDescriptorSetLayout boxedLayout = (VkDescriptorSetLayout)stream->getBe64();
747                     layouts.push_back(unbox_VkDescriptorSetLayout(boxedLayout));
748                     uint64_t validWriteCount = stream->getBe64();
749                     for (uint64_t write = 0; write < validWriteCount; write++) {
750                         uint32_t binding = stream->getBe32();
751                         uint32_t arrayElement = stream->getBe32();
752                         DescriptorSetInfo::DescriptorWriteType writeType =
753                             static_cast<DescriptorSetInfo::DescriptorWriteType>(stream->getBe32());
754                         VkDescriptorType descriptorType =
755                             static_cast<VkDescriptorType>(stream->getBe32());
756                         VkWriteDescriptorSet writeDescriptorSet = {
757                             .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
758                             .dstSet = (VkDescriptorSet)poolId,
759                             .dstBinding = binding,
760                             .dstArrayElement = arrayElement,
761                             .descriptorCount = 1,
762                             .descriptorType = descriptorType,
763                         };
764                         switch (writeType) {
765                             case DescriptorSetInfo::DescriptorWriteType::ImageInfo: {
766                                 tmpImageInfos.push_back(std::make_unique<VkDescriptorImageInfo>());
767                                 writeDescriptorSet.pImageInfo = tmpImageInfos.back().get();
768                                 VkDescriptorImageInfo& imageInfo = *tmpImageInfos.back();
769                                 stream->read(&imageInfo, sizeof(imageInfo));
770                                 imageInfo.imageView = descriptorTypeContainsImage(descriptorType)
771                                                           ? unbox_VkImageView(imageInfo.imageView)
772                                                           : 0;
773                                 imageInfo.sampler = descriptorTypeContainsSampler(descriptorType)
774                                                         ? unbox_VkSampler(imageInfo.sampler)
775                                                         : 0;
776                             } break;
777                             case DescriptorSetInfo::DescriptorWriteType::BufferInfo: {
778                                 tmpBufferInfos.push_back(
779                                     std::make_unique<VkDescriptorBufferInfo>());
780                                 writeDescriptorSet.pBufferInfo = tmpBufferInfos.back().get();
781                                 VkDescriptorBufferInfo& bufferInfo = *tmpBufferInfos.back();
782                                 stream->read(&bufferInfo, sizeof(bufferInfo));
783                                 bufferInfo.buffer = unbox_VkBuffer(bufferInfo.buffer);
784                             } break;
785                             case DescriptorSetInfo::DescriptorWriteType::BufferView: {
786                                 tmpBufferViews.push_back(std::make_unique<VkBufferView>());
787                                 writeDescriptorSet.pTexelBufferView = tmpBufferViews.back().get();
788                                 VkBufferView& bufferView = *tmpBufferViews.back();
789                                 stream->read(&bufferView, sizeof(bufferView));
790                                 bufferView = unbox_VkBufferView(bufferView);
791                             } break;
792                             case DescriptorSetInfo::DescriptorWriteType::InlineUniformBlock:
793                             case DescriptorSetInfo::DescriptorWriteType::AccelerationStructure:
794                                 // TODO
795                                 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
796                                     << "Encountered pending inline uniform block or acceleration "
797                                        "structure "
798                                        "desc write, abort (NYI)";
799                             default:
800                                 break;
801                         }
802                         writeDescriptorSets.push_back(writeDescriptorSet);
803                     }
804                 }
805                 std::vector<uint32_t> whichPool(poolIds.size(), 0);
806                 std::vector<uint32_t> pendingAlloc(poolIds.size(), true);
807 
808                 const auto& device = poolInfo.device;
809                 const auto& deviceInfo = android::base::find(mDeviceInfo, device);
810                 VulkanDispatch* dvk = dispatch_VkDevice(deviceInfo->boxed);
811                 on_vkQueueCommitDescriptorSetUpdatesGOOGLELocked(
812                     &bumpPool, nullptr, dvk, device, 1, &unboxedDescriptorPool, poolIds.size(),
813                     layouts.data(), poolIds.data(), whichPool.data(), pendingAlloc.data(),
814                     writeStartingIndices.data(), writeDescriptorSets.size(),
815                     writeDescriptorSets.data());
816             }
817 
818             // Fences
819             VERBOSE("snapshot load: fences");
820             uint64_t fenceCount = stream->getBe64();
821             std::vector<VkFence> unsignaledFencesBoxed(fenceCount);
822             stream->read(unsignaledFencesBoxed.data(), fenceCount * sizeof(VkFence));
823             for (VkFence boxedFence : unsignaledFencesBoxed) {
824                 VkFence unboxedFence = unbox_VkFence(boxedFence);
825                 auto it = mFenceInfo.find(unboxedFence);
826                 if (it == mFenceInfo.end()) {
827                     GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
828                         << "Snapshot load failure: unrecognized VkFence";
829                 }
830                 const auto& device = it->second.device;
831                 const auto& deviceInfo = android::base::find(mDeviceInfo, device);
832                 VulkanDispatch* dvk = dispatch_VkDevice(deviceInfo->boxed);
833                 dvk->vkResetFences(device, 1, &unboxedFence);
834             }
835 #ifdef CONFIG_AEMU
836             if (!mInstanceInfo.empty()) {
837                 get_emugl_vm_operations().setStatSnapshotUseVulkan();
838             }
839 #endif
840 
841             mSnapshotState = SnapshotState::Normal;
842         }
843         VERBOSE("VulkanSnapshots load (end)");
844     }
845 
getContextIdForDeviceLocked(VkDevice device)846     std::optional<uint32_t> getContextIdForDeviceLocked(VkDevice device) REQUIRES(mMutex) {
847         auto deviceInfoIt = mDeviceInfo.find(device);
848         if (deviceInfoIt == mDeviceInfo.end()) {
849             return std::nullopt;
850         }
851         auto& deviceInfo = deviceInfoIt->second;
852         if (!deviceInfo.virtioGpuContextId) {
853             return std::nullopt;
854         }
855         return *deviceInfo.virtioGpuContextId;
856     }
857 
on_vkEnumerateInstanceVersion(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,uint32_t * pApiVersion)858     VkResult on_vkEnumerateInstanceVersion(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
859                                            uint32_t* pApiVersion) {
860         if (m_vk->vkEnumerateInstanceVersion) {
861             VkResult res = m_vk->vkEnumerateInstanceVersion(pApiVersion);
862 
863             if (*pApiVersion > kMaxSafeVersion) {
864                 *pApiVersion = kMaxSafeVersion;
865             }
866 
867             return res;
868         }
869         *pApiVersion = kMinVersion;
870         return VK_SUCCESS;
871     }
872 
on_vkEnumerateInstanceExtensionProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)873     VkResult on_vkEnumerateInstanceExtensionProperties(android::base::BumpPool* pool,
874                                                    VkSnapshotApiCallInfo*, const char* pLayerName,
875                                                    uint32_t* pPropertyCount,
876                                                    VkExtensionProperties* pProperties) {
877 #if defined(__linux__)
878         // TODO(b/401005629) always lock before the call on linux
879         std::lock_guard<std::mutex> lock(mMutex);
880 #endif
881         return m_vk->vkEnumerateInstanceExtensionProperties(pLayerName, pPropertyCount, pProperties);
882     }
883 
on_vkCreateInstance(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)884     VkResult on_vkCreateInstance(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
885                                  const VkInstanceCreateInfo* pCreateInfo,
886                                  const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
887         std::vector<const char*> finalExts = filteredInstanceExtensionNames(
888             pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
889 
890         // Create higher version instance whenever it is possible.
891         uint32_t apiVersion = VK_MAKE_VERSION(1, 0, 0);
892         if (pCreateInfo->pApplicationInfo) {
893             apiVersion = pCreateInfo->pApplicationInfo->apiVersion;
894         }
895         if (m_vk->vkEnumerateInstanceVersion) {
896             uint32_t instanceVersion;
897             VkResult result = m_vk->vkEnumerateInstanceVersion(&instanceVersion);
898             if (result == VK_SUCCESS && instanceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
899                 apiVersion = instanceVersion;
900             }
901         }
902 
903         VkInstanceCreateInfo createInfoFiltered;
904         VkApplicationInfo appInfo = {};
905         deepcopy_VkInstanceCreateInfo(pool, VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, pCreateInfo,
906                                       &createInfoFiltered);
907 
908         createInfoFiltered.enabledExtensionCount = static_cast<uint32_t>(finalExts.size());
909         createInfoFiltered.ppEnabledExtensionNames = finalExts.data();
910         if (createInfoFiltered.pApplicationInfo != nullptr) {
911             const_cast<VkApplicationInfo*>(createInfoFiltered.pApplicationInfo)->apiVersion =
912                 apiVersion;
913             appInfo = *createInfoFiltered.pApplicationInfo;
914         }
915 
916         // remove VkDebugReportCallbackCreateInfoEXT and
917         // VkDebugUtilsMessengerCreateInfoEXT from the chain.
918         auto* curr = reinterpret_cast<vk_struct_common*>(&createInfoFiltered);
919         while (curr != nullptr) {
920             if (curr->pNext != nullptr &&
921                 (curr->pNext->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT ||
922                  curr->pNext->sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT)) {
923                 curr->pNext = curr->pNext->pNext;
924             }
925             curr = curr->pNext;
926         }
927 
928 #if defined(__APPLE__)
929         if (m_vkEmulation->supportsMoltenVk()) {
930             createInfoFiltered.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
931         }
932 #endif
933 
934 #if defined(__linux__)
935         // TODO(b/401005629) always lock before the call on linux
936         const bool doLockEarly = true;
937 #else
938         const bool swiftshader =
939             (android::base::getEnvironmentVariable("ANDROID_EMU_VK_ICD").compare("swiftshader") ==
940              0);
941         // b/155795731: swiftshader needs to lock early.
942         const bool doLockEarly = swiftshader;
943 #endif
944         VkResult res = VK_SUCCESS;
945         if (!doLockEarly) {
946             res = m_vk->vkCreateInstance(&createInfoFiltered, pAllocator, pInstance);
947         }
948         std::lock_guard<std::mutex> lock(mMutex);
949         if (doLockEarly) {
950             res = m_vk->vkCreateInstance(&createInfoFiltered, pAllocator, pInstance);
951         }
952         if (res != VK_SUCCESS) {
953             WARN("Failed to create Vulkan instance: %s.", string_VkResult(res));
954             return res;
955         }
956 
957         InstanceInfo info;
958         info.apiVersion = apiVersion;
959         if (pCreateInfo->pApplicationInfo) {
960             if (pCreateInfo->pApplicationInfo->pApplicationName) {
961                 info.applicationName = pCreateInfo->pApplicationInfo->pApplicationName;
962             }
963             if (pCreateInfo->pApplicationInfo->pEngineName) {
964                 info.engineName = pCreateInfo->pApplicationInfo->pEngineName;
965             }
966         }
967         for (uint32_t i = 0; i < createInfoFiltered.enabledExtensionCount; ++i) {
968             info.enabledExtensionNames.push_back(createInfoFiltered.ppEnabledExtensionNames[i]);
969         }
970 
971         INFO("Created VkInstance:%p for application:%s engine:%s.", *pInstance,
972              info.applicationName.c_str(), info.engineName.c_str());
973 
974 #ifdef CONFIG_AEMU
975         m_vkEmulation->getCallbacks().registerVulkanInstance((uint64_t)*pInstance,
976                                                              info.applicationName.c_str());
977 #endif
978         // Box it up
979         VkInstance boxed = new_boxed_VkInstance(*pInstance, nullptr, true /* own dispatch */);
980         init_vulkan_dispatch_from_instance(m_vk, *pInstance, dispatch_VkInstance(boxed));
981         info.boxed = boxed;
982 
983         std::string_view engineName = appInfo.pEngineName ? appInfo.pEngineName : "";
984         info.isAngle = (engineName == "ANGLE");
985 
986         VALIDATE_NEW_HANDLE_INFO_ENTRY(mInstanceInfo, *pInstance);
987         mInstanceInfo[*pInstance] = info;
988 
989         *pInstance = (VkInstance)info.boxed;
990 
991         if (vkCleanupEnabled()) {
992             m_vkEmulation->getCallbacks().registerProcessCleanupCallback(
993                 unbox_VkInstance(boxed), [this, boxed] {
994                     if (snapshotsEnabled()) {
995                         snapshot()->vkDestroyInstance(nullptr, nullptr, nullptr, 0, boxed, nullptr);
996                     }
997                     vkDestroyInstanceImpl(unbox_VkInstance(boxed), nullptr);
998                 });
999         }
1000 
1001         return VK_SUCCESS;
1002     }
1003 
processDelayedRemovesForDevice(VkDevice device)1004     void processDelayedRemovesForDevice(VkDevice device) EXCLUDES(mMutex) {
1005         sBoxedHandleManager.processDelayedRemoves(device);
1006     }
1007 
vkDestroyInstanceImpl(VkInstance instance,const VkAllocationCallbacks * pAllocator)1008     void vkDestroyInstanceImpl(VkInstance instance, const VkAllocationCallbacks* pAllocator) {
1009         std::vector<VkDevice> devicesToDestroy;
1010 
1011         // Get the list of devices to destroy inside the lock ...
1012         {
1013             std::lock_guard<std::mutex> lock(mMutex);
1014 
1015             for (auto it : mDeviceToPhysicalDevice) {
1016                 auto* otherInstance = android::base::find(mPhysicalDeviceToInstance, it.second);
1017                 if (!otherInstance) continue;
1018                 if (instance == *otherInstance) {
1019                     devicesToDestroy.push_back(it.first);
1020                 }
1021             }
1022         }
1023 
1024         // ... but process the delayed remove callbacks out of the lock as callbacks may
1025         // call into `VkDecoderGlobalState` methods.
1026         for (auto device : devicesToDestroy) {
1027             processDelayedRemovesForDevice(device);
1028         }
1029 
1030         InstanceObjects instanceObjects;
1031 
1032         {
1033             std::lock_guard<std::mutex> lock(mMutex);
1034             extractInstanceAndDependenciesLocked(instance, instanceObjects);
1035         }
1036 
1037         if (mRenderDocWithMultipleVkInstances) {
1038             mRenderDocWithMultipleVkInstances->removeVkInstance(instance);
1039         }
1040 
1041         destroyInstanceObjects(instanceObjects);
1042     }
1043 
on_vkDestroyInstance(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkInstance boxed_instance,const VkAllocationCallbacks * pAllocator)1044     void on_vkDestroyInstance(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
1045                               VkInstance boxed_instance, const VkAllocationCallbacks* pAllocator) {
1046         auto instance = try_unbox_VkInstance(boxed_instance);
1047         if (instance == VK_NULL_HANDLE) {
1048             return;
1049         }
1050         // The instance should not be used after vkDestroyInstanceImpl is called,
1051         // remove it from the cleanup callback mapping.
1052         m_vkEmulation->getCallbacks().unregisterProcessCleanupCallback(instance);
1053 
1054         vkDestroyInstanceImpl(instance, pAllocator);
1055     }
1056 
GetPhysicalDevices(VkInstance instance,VulkanDispatch * vk,std::vector<VkPhysicalDevice> & outPhysicalDevices)1057     VkResult GetPhysicalDevices(VkInstance instance, VulkanDispatch* vk,
1058                                 std::vector<VkPhysicalDevice>& outPhysicalDevices) {
1059         uint32_t physicalDevicesCount = 0;
1060         auto res = vk->vkEnumeratePhysicalDevices(instance, &physicalDevicesCount, nullptr);
1061         if (res != VK_SUCCESS) {
1062             return res;
1063         }
1064 
1065         outPhysicalDevices.resize(physicalDevicesCount);
1066 
1067         res = vk->vkEnumeratePhysicalDevices(instance, &physicalDevicesCount,
1068                                              outPhysicalDevices.data());
1069         if (res != VK_SUCCESS) {
1070             outPhysicalDevices.clear();
1071             return res;
1072         }
1073 
1074         outPhysicalDevices.resize(physicalDevicesCount);
1075 
1076         return VK_SUCCESS;
1077     }
1078 
FilterPhysicalDevicesLocked(VkInstance instance,VulkanDispatch * vk,std::vector<VkPhysicalDevice> & toFilterPhysicalDevices)1079     void FilterPhysicalDevicesLocked(VkInstance instance, VulkanDispatch* vk,
1080                                      std::vector<VkPhysicalDevice>& toFilterPhysicalDevices) {
1081         if (m_vkEmulation->supportsGetPhysicalDeviceProperties2()) {
1082             const auto emulationPhysicalDeviceUuid = *m_vkEmulation->getDeviceUuid();
1083 
1084             PFN_vkGetPhysicalDeviceProperties2KHR getPhysdevProps2Func =
1085                 vk_util::getVkInstanceProcAddrWithFallback<
1086                     vk_util::vk_fn_info::GetPhysicalDeviceProperties2>(
1087                     {
1088                         vk->vkGetInstanceProcAddr,
1089                         m_vk->vkGetInstanceProcAddr,
1090                     },
1091                     instance);
1092 
1093             if (getPhysdevProps2Func) {
1094                 // Remove those devices whose UUIDs don't match the one in VkCommonOperations.
1095                 toFilterPhysicalDevices.erase(
1096                     std::remove_if(toFilterPhysicalDevices.begin(), toFilterPhysicalDevices.end(),
1097                                    [&](VkPhysicalDevice physicalDevice) {
1098                                        // We can get the device UUID.
1099                                        VkPhysicalDeviceIDPropertiesKHR idProps = {
1100                                            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR,
1101                                            nullptr,
1102                                        };
1103                                        VkPhysicalDeviceProperties2KHR propsWithId = {
1104                                            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
1105                                            &idProps,
1106                                        };
1107                                        getPhysdevProps2Func(physicalDevice, &propsWithId);
1108 
1109                                        return memcmp(emulationPhysicalDeviceUuid.data(),
1110                                                      idProps.deviceUUID, VK_UUID_SIZE) != 0;
1111                                    }),
1112                     toFilterPhysicalDevices.end());
1113             } else {
1114                 ERR("Failed to vkGetPhysicalDeviceProperties2KHR().");
1115             }
1116         } else {
1117             // If we don't support ID properties then just advertise only the
1118             // first physical device.
1119             WARN("Device ID not available, returning first physical device.");
1120         }
1121         if (!toFilterPhysicalDevices.empty()) {
1122             toFilterPhysicalDevices.erase(std::next(toFilterPhysicalDevices.begin()),
1123                                           toFilterPhysicalDevices.end());
1124         }
1125     }
1126 
on_vkEnumeratePhysicalDevices(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkInstance boxed_instance,uint32_t * pPhysicalDeviceCount,VkPhysicalDevice * pPhysicalDevices)1127     VkResult on_vkEnumeratePhysicalDevices(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
1128                                            VkInstance boxed_instance,
1129                                            uint32_t* pPhysicalDeviceCount,
1130                                            VkPhysicalDevice* pPhysicalDevices) {
1131         auto instance = unbox_VkInstance(boxed_instance);
1132         auto vk = dispatch_VkInstance(boxed_instance);
1133 
1134         std::vector<VkPhysicalDevice> physicalDevices;
1135         auto res = GetPhysicalDevices(instance, vk, physicalDevices);
1136         if (res != VK_SUCCESS) {
1137             return res;
1138         }
1139 
1140         std::lock_guard<std::mutex> lock(mMutex);
1141 
1142         FilterPhysicalDevicesLocked(instance, vk, physicalDevices);
1143 
1144         const uint32_t requestedCount = pPhysicalDeviceCount ? *pPhysicalDeviceCount : 0;
1145         const uint32_t availableCount = static_cast<uint32_t>(physicalDevices.size());
1146 
1147         if (pPhysicalDeviceCount) {
1148             *pPhysicalDeviceCount = availableCount;
1149         }
1150 
1151         if (pPhysicalDeviceCount && pPhysicalDevices) {
1152             // Box them up
1153             for (uint32_t i = 0; i < std::min(requestedCount, availableCount); ++i) {
1154                 VALIDATE_NEW_HANDLE_INFO_ENTRY(mPhysicalDeviceToInstance, physicalDevices[i]);
1155                 mPhysicalDeviceToInstance[physicalDevices[i]] = instance;
1156                 VALIDATE_NEW_HANDLE_INFO_ENTRY(mPhysdevInfo, physicalDevices[i]);
1157                 auto& physdevInfo = mPhysdevInfo[physicalDevices[i]];
1158                 physdevInfo.instance = instance;
1159                 physdevInfo.boxed = new_boxed_VkPhysicalDevice(physicalDevices[i], vk,
1160                                                                false /* does not own dispatch */);
1161 
1162                 vk->vkGetPhysicalDeviceProperties(physicalDevices[i], &physdevInfo.props);
1163 
1164                 if (physdevInfo.props.apiVersion > kMaxSafeVersion) {
1165                     physdevInfo.props.apiVersion = kMaxSafeVersion;
1166                 }
1167 
1168                 VkPhysicalDeviceMemoryProperties hostMemoryProperties;
1169                 vk->vkGetPhysicalDeviceMemoryProperties(physicalDevices[i], &hostMemoryProperties);
1170 
1171                 physdevInfo.memoryPropertiesHelper =
1172                     std::make_unique<EmulatedPhysicalDeviceMemoryProperties>(
1173                         hostMemoryProperties,
1174                         m_vkEmulation->getRepresentativeColorBufferMemoryTypeInfo()
1175                             .hostMemoryTypeIndex,
1176                         getFeatures());
1177 
1178                 std::vector<VkQueueFamilyProperties> queueFamilyProperties;
1179                 uint32_t queueFamilyPropCount = 0;
1180                 vk->vkGetPhysicalDeviceQueueFamilyProperties(physicalDevices[i],
1181                                                              &queueFamilyPropCount, nullptr);
1182                 queueFamilyProperties.resize((size_t)queueFamilyPropCount);
1183                 vk->vkGetPhysicalDeviceQueueFamilyProperties(
1184                     physicalDevices[i], &queueFamilyPropCount,
1185                     queueFamilyProperties.data());
1186 
1187                 physdevInfo.queuePropertiesHelper =
1188                     std::make_unique<EmulatedPhysicalDeviceQueueProperties>(
1189                         queueFamilyProperties,
1190                         getFeatures());
1191 
1192                 pPhysicalDevices[i] = (VkPhysicalDevice)physdevInfo.boxed;
1193             }
1194             if (requestedCount < availableCount) {
1195                 res = VK_INCOMPLETE;
1196             }
1197         }
1198 
1199         return res;
1200     }
1201 
on_vkGetPhysicalDeviceFeatures(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,VkPhysicalDeviceFeatures * pFeatures)1202     void on_vkGetPhysicalDeviceFeatures(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
1203                                         VkPhysicalDevice boxed_physicalDevice,
1204                                         VkPhysicalDeviceFeatures* pFeatures) {
1205         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1206         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1207 
1208         vk->vkGetPhysicalDeviceFeatures(physicalDevice, pFeatures);
1209 
1210         std::lock_guard<std::mutex> lock(mMutex);
1211 
1212         pFeatures->textureCompressionETC2 |= enableEmulatedEtc2Locked(physicalDevice, vk);
1213         pFeatures->textureCompressionASTC_LDR |= enableEmulatedAstcLocked(physicalDevice, vk);
1214     }
1215 
on_vkGetPhysicalDeviceFeatures2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,VkPhysicalDeviceFeatures2 * pFeatures)1216     void on_vkGetPhysicalDeviceFeatures2(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
1217                                          VkPhysicalDevice boxed_physicalDevice,
1218                                          VkPhysicalDeviceFeatures2* pFeatures) {
1219         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1220         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1221 
1222         std::lock_guard<std::mutex> lock(mMutex);
1223 
1224         auto* physdevInfo = android::base::find(mPhysdevInfo, physicalDevice);
1225         if (!physdevInfo) return;
1226 
1227         auto instance = mPhysicalDeviceToInstance[physicalDevice];
1228         auto* instanceInfo = android::base::find(mInstanceInfo, instance);
1229         if (!instanceInfo) return;
1230 
1231         if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
1232             physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
1233             vk->vkGetPhysicalDeviceFeatures2(physicalDevice, pFeatures);
1234         } else if (hasInstanceExtension(instance,
1235                                         VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1236             vk->vkGetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures);
1237         } else {
1238             // No instance extension, fake it!!!!
1239             if (pFeatures->pNext) {
1240                 fprintf(stderr,
1241                         "%s: Warning: Trying to use extension struct in "
1242                         "VkPhysicalDeviceFeatures2 without having enabled "
1243                         "the extension!\n",
1244                         __func__);
1245             }
1246             *pFeatures = {
1247                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
1248                 0,
1249             };
1250             vk->vkGetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
1251         }
1252 
1253         pFeatures->features.textureCompressionETC2 |= enableEmulatedEtc2Locked(physicalDevice, vk);
1254         pFeatures->features.textureCompressionASTC_LDR |=
1255             enableEmulatedAstcLocked(physicalDevice, vk);
1256         VkPhysicalDeviceSamplerYcbcrConversionFeatures* ycbcrFeatures =
1257             vk_find_struct<VkPhysicalDeviceSamplerYcbcrConversionFeatures>(pFeatures);
1258         if (ycbcrFeatures != nullptr) {
1259             ycbcrFeatures->samplerYcbcrConversion |= m_vkEmulation->isYcbcrEmulationEnabled();
1260         }
1261 
1262         // Disable a set of Vulkan features if BypassVulkanDeviceFeatureOverrides is NOT enabled.
1263         if (!m_vkEmulation->getFeatures().BypassVulkanDeviceFeatureOverrides.enabled) {
1264             VkPhysicalDeviceProtectedMemoryFeatures* protectedMemoryFeatures =
1265                 vk_find_struct<VkPhysicalDeviceProtectedMemoryFeatures>(pFeatures);
1266             if (protectedMemoryFeatures != nullptr) {
1267                 // Protected memory is not supported on emulators. Override feature
1268                 // information to mark as unsupported (see b/329845987).
1269                 protectedMemoryFeatures->protectedMemory = VK_FALSE;
1270             }
1271             VkPhysicalDeviceVulkan11Features* vk11Features =
1272                 vk_find_struct<VkPhysicalDeviceVulkan11Features>(pFeatures);
1273             if (vk11Features != nullptr) {
1274                 vk11Features->protectedMemory = VK_FALSE;
1275             }
1276 
1277             VkPhysicalDevicePrivateDataFeatures* privateDataFeatures =
1278                 vk_find_struct<VkPhysicalDevicePrivateDataFeatures>(pFeatures);
1279             if (privateDataFeatures != nullptr) {
1280                 // Private data from the guest side is not currently supported and causes emulator
1281                 // crashes with the dEQP-VK.api.object_management.private_data tests (b/368009403).
1282                 privateDataFeatures->privateData = VK_FALSE;
1283             }
1284 
1285             VkPhysicalDeviceVulkan13Features* vulkan13Features =
1286                 vk_find_struct<VkPhysicalDeviceVulkan13Features>(pFeatures);
1287             if (vulkan13Features != nullptr) {
1288                 vulkan13Features->privateData = VK_FALSE;
1289             }
1290 
1291             if (m_vkEmulation->getFeatures().VulkanBatchedDescriptorSetUpdate.enabled) {
1292                 // Currently not supporting iub due to descriptor set optimization.
1293                 // TODO: fix the non-optimized descriptor set path and re-enable the features afterwads.
1294                 // b/372217918
1295                 VkPhysicalDeviceInlineUniformBlockFeatures* iubFeatures =
1296                     vk_find_struct<VkPhysicalDeviceInlineUniformBlockFeatures>(pFeatures);
1297                 if (iubFeatures != nullptr) {
1298                     iubFeatures->inlineUniformBlock = VK_FALSE;
1299                 }
1300                 if (vulkan13Features != nullptr) {
1301                     vulkan13Features->inlineUniformBlock = VK_FALSE;
1302                 }
1303             }
1304         }
1305     }
1306 
on_vkGetPhysicalDeviceImageFormatProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags,VkImageFormatProperties * pImageFormatProperties)1307     VkResult on_vkGetPhysicalDeviceImageFormatProperties(
1308         android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
1309         VkPhysicalDevice boxed_physicalDevice, VkFormat format, VkImageType type,
1310         VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
1311         VkImageFormatProperties* pImageFormatProperties) {
1312         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1313         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1314         const bool emulatedTexture = isEmulatedCompressedTexture(format, physicalDevice, vk);
1315         if (emulatedTexture) {
1316             if (!supportEmulatedCompressedImageFormatProperty(format, type, tiling, usage, flags)) {
1317                 memset(pImageFormatProperties, 0, sizeof(VkImageFormatProperties));
1318                 return VK_ERROR_FORMAT_NOT_SUPPORTED;
1319             }
1320             flags &= ~VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT;
1321             flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
1322             usage |= VK_IMAGE_USAGE_STORAGE_BIT;
1323             format = CompressedImageInfo::getCompressedMipmapsFormat(format);
1324         }
1325 
1326         VkResult res = vk->vkGetPhysicalDeviceImageFormatProperties(
1327             physicalDevice, format, type, tiling, usage, flags, pImageFormatProperties);
1328         if (res != VK_SUCCESS) {
1329             return res;
1330         }
1331         if (emulatedTexture) {
1332             maskImageFormatPropertiesForEmulatedTextures(pImageFormatProperties);
1333         }
1334         return res;
1335     }
1336 
on_vkGetPhysicalDeviceImageFormatProperties2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,VkImageFormatProperties2 * pImageFormatProperties)1337     VkResult on_vkGetPhysicalDeviceImageFormatProperties2(
1338         android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
1339         VkPhysicalDevice boxed_physicalDevice,
1340         const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
1341         VkImageFormatProperties2* pImageFormatProperties) {
1342         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1343         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1344         VkPhysicalDeviceImageFormatInfo2 imageFormatInfo;
1345         VkFormat format = pImageFormatInfo->format;
1346         const bool emulatedTexture = isEmulatedCompressedTexture(format, physicalDevice, vk);
1347         if (emulatedTexture) {
1348             if (!supportEmulatedCompressedImageFormatProperty(
1349                     pImageFormatInfo->format, pImageFormatInfo->type, pImageFormatInfo->tiling,
1350                     pImageFormatInfo->usage, pImageFormatInfo->flags)) {
1351                 memset(&pImageFormatProperties->imageFormatProperties, 0,
1352                        sizeof(VkImageFormatProperties));
1353                 return VK_ERROR_FORMAT_NOT_SUPPORTED;
1354             }
1355             imageFormatInfo = *pImageFormatInfo;
1356             pImageFormatInfo = &imageFormatInfo;
1357             imageFormatInfo.flags &= ~VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT;
1358             imageFormatInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
1359             imageFormatInfo.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
1360             imageFormatInfo.format = CompressedImageInfo::getCompressedMipmapsFormat(format);
1361         }
1362 
1363         auto* extImageFormatInfo =
1364             vk_find_struct<VkPhysicalDeviceExternalImageFormatInfo>(pImageFormatInfo);
1365 
1366         if (extImageFormatInfo &&
1367             extImageFormatInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT) {
1368             const_cast<VkPhysicalDeviceExternalImageFormatInfo*>(extImageFormatInfo)->handleType =
1369                 m_vkEmulation->getDefaultExternalMemoryHandleType();
1370         }
1371 
1372         std::lock_guard<std::mutex> lock(mMutex);
1373 
1374         auto* physdevInfo = android::base::find(mPhysdevInfo, physicalDevice);
1375         if (!physdevInfo) {
1376             return VK_ERROR_OUT_OF_HOST_MEMORY;
1377         }
1378 
1379         VkResult res = VK_ERROR_INITIALIZATION_FAILED;
1380 
1381         auto instance = mPhysicalDeviceToInstance[physicalDevice];
1382         auto* instanceInfo = android::base::find(mInstanceInfo, instance);
1383         if (!instanceInfo) {
1384             return res;
1385         }
1386 
1387         if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
1388             physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
1389             res = vk->vkGetPhysicalDeviceImageFormatProperties2(physicalDevice, pImageFormatInfo,
1390                                                                 pImageFormatProperties);
1391         } else if (hasInstanceExtension(instance,
1392                                         VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1393             res = vk->vkGetPhysicalDeviceImageFormatProperties2KHR(physicalDevice, pImageFormatInfo,
1394                                                                    pImageFormatProperties);
1395         } else {
1396             // No instance extension, fake it!!!!
1397             if (pImageFormatProperties->pNext) {
1398                 fprintf(stderr,
1399                         "%s: Warning: Trying to use extension struct in "
1400                         "VkPhysicalDeviceFeatures2 without having enabled "
1401                         "the extension!!!!11111\n",
1402                         __func__);
1403             }
1404             *pImageFormatProperties = {
1405                 VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
1406                 0,
1407             };
1408             res = vk->vkGetPhysicalDeviceImageFormatProperties(
1409                 physicalDevice, pImageFormatInfo->format, pImageFormatInfo->type,
1410                 pImageFormatInfo->tiling, pImageFormatInfo->usage, pImageFormatInfo->flags,
1411                 &pImageFormatProperties->imageFormatProperties);
1412         }
1413         if (res != VK_SUCCESS) {
1414             return res;
1415         }
1416 
1417         VkExternalImageFormatProperties* extImageFormatProps =
1418             vk_find_struct<VkExternalImageFormatProperties>(pImageFormatProperties);
1419 
1420         // Only allow dedicated allocations for external images.
1421         if (extImageFormatInfo && extImageFormatProps) {
1422             extImageFormatProps->externalMemoryProperties.externalMemoryFeatures |=
1423                 VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
1424         }
1425 
1426         if (emulatedTexture) {
1427             maskImageFormatPropertiesForEmulatedTextures(
1428                 &pImageFormatProperties->imageFormatProperties);
1429         }
1430 
1431         return res;
1432     }
1433 
on_vkGetPhysicalDeviceFormatProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,VkFormat format,VkFormatProperties * pFormatProperties)1434     void on_vkGetPhysicalDeviceFormatProperties(android::base::BumpPool* pool,
1435                                                 VkSnapshotApiCallInfo*,
1436                                                 VkPhysicalDevice boxed_physicalDevice,
1437                                                 VkFormat format,
1438                                                 VkFormatProperties* pFormatProperties) {
1439         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1440         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1441         getPhysicalDeviceFormatPropertiesCore<VkFormatProperties>(
1442             [vk](VkPhysicalDevice physicalDevice, VkFormat format,
1443                  VkFormatProperties* pFormatProperties) {
1444                 vk->vkGetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties);
1445             },
1446             vk, physicalDevice, format, pFormatProperties);
1447     }
1448 
on_vkGetPhysicalDeviceFormatProperties2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)1449     void on_vkGetPhysicalDeviceFormatProperties2(android::base::BumpPool* pool,
1450                                                  VkSnapshotApiCallInfo*,
1451                                                  VkPhysicalDevice boxed_physicalDevice,
1452                                                  VkFormat format,
1453                                                  VkFormatProperties2* pFormatProperties) {
1454         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1455         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1456 
1457         enum class WhichFunc {
1458             kGetPhysicalDeviceFormatProperties,
1459             kGetPhysicalDeviceFormatProperties2,
1460             kGetPhysicalDeviceFormatProperties2KHR,
1461         };
1462 
1463         auto func = WhichFunc::kGetPhysicalDeviceFormatProperties2KHR;
1464 
1465         {
1466             std::lock_guard<std::mutex> lock(mMutex);
1467 
1468             auto* physdevInfo = android::base::find(mPhysdevInfo, physicalDevice);
1469             if (!physdevInfo) return;
1470 
1471             auto instance = mPhysicalDeviceToInstance[physicalDevice];
1472             auto* instanceInfo = android::base::find(mInstanceInfo, instance);
1473             if (!instanceInfo) return;
1474 
1475             if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
1476                 physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
1477                 func = WhichFunc::kGetPhysicalDeviceFormatProperties2;
1478             } else if (hasInstanceExtension(
1479                            instance, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1480                 func = WhichFunc::kGetPhysicalDeviceFormatProperties2KHR;
1481             }
1482         }
1483 
1484         switch (func) {
1485             case WhichFunc::kGetPhysicalDeviceFormatProperties2: {
1486                 getPhysicalDeviceFormatPropertiesCore<VkFormatProperties2>(
1487                     [vk](VkPhysicalDevice physicalDevice, VkFormat format,
1488                          VkFormatProperties2* pFormatProperties) {
1489                         vk->vkGetPhysicalDeviceFormatProperties2(physicalDevice, format,
1490                                                                  pFormatProperties);
1491                     },
1492                     vk, physicalDevice, format, pFormatProperties);
1493                 break;
1494             }
1495             case WhichFunc::kGetPhysicalDeviceFormatProperties2KHR: {
1496                 getPhysicalDeviceFormatPropertiesCore<VkFormatProperties2>(
1497                     [vk](VkPhysicalDevice physicalDevice, VkFormat format,
1498                          VkFormatProperties2* pFormatProperties) {
1499                         vk->vkGetPhysicalDeviceFormatProperties2KHR(physicalDevice, format,
1500                                                                     pFormatProperties);
1501                     },
1502                     vk, physicalDevice, format, pFormatProperties);
1503                 break;
1504             }
1505             case WhichFunc::kGetPhysicalDeviceFormatProperties: {
1506                 // No instance extension, fake it!!!!
1507                 if (pFormatProperties->pNext) {
1508                     fprintf(stderr,
1509                             "%s: Warning: Trying to use extension struct in "
1510                             "vkGetPhysicalDeviceFormatProperties2 without having "
1511                             "enabled the extension!!!!11111\n",
1512                             __func__);
1513                 }
1514                 pFormatProperties->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
1515                 getPhysicalDeviceFormatPropertiesCore<VkFormatProperties>(
1516                     [vk](VkPhysicalDevice physicalDevice, VkFormat format,
1517                          VkFormatProperties* pFormatProperties) {
1518                         vk->vkGetPhysicalDeviceFormatProperties(physicalDevice, format,
1519                                                                 pFormatProperties);
1520                     },
1521                     vk, physicalDevice, format, &pFormatProperties->formatProperties);
1522                 break;
1523             }
1524         }
1525     }
1526 
on_vkGetPhysicalDeviceProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,VkPhysicalDeviceProperties * pProperties)1527     void on_vkGetPhysicalDeviceProperties(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
1528                                           VkPhysicalDevice boxed_physicalDevice,
1529                                           VkPhysicalDeviceProperties* pProperties) {
1530         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1531         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1532 
1533         vk->vkGetPhysicalDeviceProperties(physicalDevice, pProperties);
1534 
1535         if (pProperties->apiVersion > kMaxSafeVersion) {
1536             pProperties->apiVersion = kMaxSafeVersion;
1537         }
1538     }
1539 
on_vkGetPhysicalDeviceProperties2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,VkPhysicalDeviceProperties2 * pProperties)1540     void on_vkGetPhysicalDeviceProperties2(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
1541                                            VkPhysicalDevice boxed_physicalDevice,
1542                                            VkPhysicalDeviceProperties2* pProperties) {
1543         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1544         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1545 
1546         std::lock_guard<std::mutex> lock(mMutex);
1547 
1548         auto* physdevInfo = android::base::find(mPhysdevInfo, physicalDevice);
1549         if (!physdevInfo) return;
1550 
1551         auto instance = mPhysicalDeviceToInstance[physicalDevice];
1552         auto* instanceInfo = android::base::find(mInstanceInfo, instance);
1553         if (!instanceInfo) return;
1554 
1555         if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
1556             physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
1557             vk->vkGetPhysicalDeviceProperties2(physicalDevice, pProperties);
1558         } else if (hasInstanceExtension(instance,
1559                                         VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1560             vk->vkGetPhysicalDeviceProperties2KHR(physicalDevice, pProperties);
1561         } else {
1562             // No instance extension, fake it!!!!
1563             if (pProperties->pNext) {
1564                 fprintf(stderr,
1565                         "%s: Warning: Trying to use extension struct in "
1566                         "VkPhysicalDeviceProperties2 without having enabled "
1567                         "the extension!!!!11111\n",
1568                         __func__);
1569             }
1570             *pProperties = {
1571                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
1572                 0,
1573             };
1574             vk->vkGetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
1575         }
1576 
1577         if (pProperties->properties.apiVersion > kMaxSafeVersion) {
1578             pProperties->properties.apiVersion = kMaxSafeVersion;
1579         }
1580     }
1581 
on_vkGetPhysicalDeviceQueueFamilyProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,uint32_t * pQueueFamilyPropertyCount,VkQueueFamilyProperties * pQueueFamilyProperties)1582     void on_vkGetPhysicalDeviceQueueFamilyProperties(
1583         android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
1584         VkPhysicalDevice boxed_physicalDevice, uint32_t* pQueueFamilyPropertyCount,
1585         VkQueueFamilyProperties* pQueueFamilyProperties) {
1586         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1587 
1588         std::lock_guard<std::mutex> lock(mMutex);
1589 
1590         const PhysicalDeviceInfo* physicalDeviceInfo =
1591             android::base::find(mPhysdevInfo, physicalDevice);
1592         if (!physicalDeviceInfo || !physicalDeviceInfo->queuePropertiesHelper) {
1593             ERR("Failed to find physical device info.");
1594             return;
1595         }
1596 
1597         // Use queuePropertiesHelper to accommodate for any property overrides/emulation
1598         const auto& properties =
1599             physicalDeviceInfo->queuePropertiesHelper->getQueueFamilyProperties();
1600         if (pQueueFamilyProperties) {
1601             // Count is given by the client to define amount of space available
1602             *pQueueFamilyPropertyCount =
1603                 std::min((uint32_t)properties.size(), *pQueueFamilyPropertyCount);
1604             for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
1605                 pQueueFamilyProperties[i] = properties[i];
1606             }
1607         } else {
1608             *pQueueFamilyPropertyCount = (uint32_t)properties.size();
1609         }
1610     }
1611 
on_vkGetPhysicalDeviceQueueFamilyProperties2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,uint32_t * pQueueFamilyPropertyCount,VkQueueFamilyProperties2 * pQueueFamilyProperties)1612     void on_vkGetPhysicalDeviceQueueFamilyProperties2(
1613         android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
1614         VkPhysicalDevice boxed_physicalDevice, uint32_t* pQueueFamilyPropertyCount,
1615         VkQueueFamilyProperties2* pQueueFamilyProperties) {
1616         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1617         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1618 
1619         if (pQueueFamilyProperties && pQueueFamilyProperties->pNext) {
1620             // We need to call the driver version to fill in any pNext values
1621             vk->vkGetPhysicalDeviceQueueFamilyProperties2(physicalDevice, pQueueFamilyPropertyCount,
1622                                                           pQueueFamilyProperties);
1623         }
1624 
1625         std::lock_guard<std::mutex> lock(mMutex);
1626 
1627         const PhysicalDeviceInfo* physicalDeviceInfo =
1628             android::base::find(mPhysdevInfo, physicalDevice);
1629         if (!physicalDeviceInfo || !physicalDeviceInfo->queuePropertiesHelper) {
1630             ERR("Failed to find physical device info.");
1631             return;
1632         }
1633 
1634         // Use queuePropertiesHelper to accommodate for any property overrides/emulation
1635         const auto& properties =
1636             physicalDeviceInfo->queuePropertiesHelper->getQueueFamilyProperties();
1637         if (pQueueFamilyProperties) {
1638             // Count is given by the client to define amount of space available
1639             *pQueueFamilyPropertyCount =
1640                 std::min((uint32_t)properties.size(), *pQueueFamilyPropertyCount);
1641             for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
1642                 pQueueFamilyProperties[i].queueFamilyProperties = properties[i];
1643             }
1644         } else {
1645             *pQueueFamilyPropertyCount = (uint32_t)properties.size();
1646         }
1647     }
1648 
on_vkGetPhysicalDeviceMemoryProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,VkPhysicalDeviceMemoryProperties * pMemoryProperties)1649     void on_vkGetPhysicalDeviceMemoryProperties(
1650         android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
1651         VkPhysicalDevice boxed_physicalDevice,
1652         VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
1653         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1654 
1655         std::lock_guard<std::mutex> lock(mMutex);
1656 
1657         auto* physicalDeviceInfo = android::base::find(mPhysdevInfo, physicalDevice);
1658         if (!physicalDeviceInfo) {
1659             ERR("Failed to find physical device info.");
1660             return;
1661         }
1662 
1663         auto& physicalDeviceMemoryHelper = physicalDeviceInfo->memoryPropertiesHelper;
1664         *pMemoryProperties = physicalDeviceMemoryHelper->getGuestMemoryProperties();
1665     }
1666 
on_vkGetPhysicalDeviceMemoryProperties2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,VkPhysicalDeviceMemoryProperties2 * pMemoryProperties)1667     void on_vkGetPhysicalDeviceMemoryProperties2(
1668         android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
1669         VkPhysicalDevice boxed_physicalDevice,
1670         VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
1671         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1672         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1673 
1674         std::lock_guard<std::mutex> lock(mMutex);
1675 
1676         auto* physicalDeviceInfo = android::base::find(mPhysdevInfo, physicalDevice);
1677         if (!physicalDeviceInfo) return;
1678 
1679         auto instance = mPhysicalDeviceToInstance[physicalDevice];
1680         auto* instanceInfo = android::base::find(mInstanceInfo, instance);
1681         if (!instanceInfo) return;
1682 
1683         if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
1684             physicalDeviceInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
1685             vk->vkGetPhysicalDeviceMemoryProperties2(physicalDevice, pMemoryProperties);
1686         } else if (hasInstanceExtension(instance,
1687                                         VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1688             vk->vkGetPhysicalDeviceMemoryProperties2KHR(physicalDevice, pMemoryProperties);
1689         } else {
1690             // No instance extension, fake it!!!!
1691             if (pMemoryProperties->pNext) {
1692                 fprintf(stderr,
1693                         "%s: Warning: Trying to use extension struct in "
1694                         "VkPhysicalDeviceMemoryProperties2 without having enabled "
1695                         "the extension!!!!11111\n",
1696                         __func__);
1697             }
1698             *pMemoryProperties = {
1699                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2,
1700                 0,
1701             };
1702         }
1703 
1704         auto& physicalDeviceMemoryHelper = physicalDeviceInfo->memoryPropertiesHelper;
1705         pMemoryProperties->memoryProperties =
1706             physicalDeviceMemoryHelper->getGuestMemoryProperties();
1707     }
1708 
on_vkEnumerateDeviceExtensionProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)1709     VkResult on_vkEnumerateDeviceExtensionProperties(android::base::BumpPool* pool,
1710                                                      VkSnapshotApiCallInfo*,
1711                                                      VkPhysicalDevice boxed_physicalDevice,
1712                                                      const char* pLayerName,
1713                                                      uint32_t* pPropertyCount,
1714                                                      VkExtensionProperties* pProperties) {
1715         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1716         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1717 
1718         bool shouldPassthrough = !m_vkEmulation->isYcbcrEmulationEnabled();
1719 #if defined(__APPLE__)
1720         shouldPassthrough = shouldPassthrough && !m_vkEmulation->supportsMoltenVk();
1721 #endif
1722         if (shouldPassthrough) {
1723             return vk->vkEnumerateDeviceExtensionProperties(physicalDevice, pLayerName,
1724                                                             pPropertyCount, pProperties);
1725         }
1726 
1727         // If MoltenVK is supported on host, we need to ensure that we include
1728         // VK_MVK_moltenvk extenstion in returned properties.
1729         std::vector<VkExtensionProperties> properties;
1730         VkResult result =
1731             enumerateDeviceExtensionProperties(vk, physicalDevice, pLayerName, properties);
1732         if (result != VK_SUCCESS) {
1733             return result;
1734         }
1735 
1736 #if defined(__APPLE__) && defined(VK_MVK_moltenvk)
1737         // Guest will check for VK_MVK_moltenvk extension for enabling AHB support
1738         if (m_vkEmulation->supportsMoltenVk() &&
1739             !hasDeviceExtension(properties, VK_MVK_MOLTENVK_EXTENSION_NAME)) {
1740             VkExtensionProperties mvk_props;
1741             strncpy(mvk_props.extensionName, VK_MVK_MOLTENVK_EXTENSION_NAME,
1742                     sizeof(mvk_props.extensionName));
1743             mvk_props.specVersion = VK_MVK_MOLTENVK_SPEC_VERSION;
1744             properties.push_back(mvk_props);
1745         }
1746 #endif
1747 
1748         if (m_vkEmulation->isYcbcrEmulationEnabled() &&
1749             !hasDeviceExtension(properties, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME)) {
1750             VkExtensionProperties ycbcr_props;
1751             strncpy(ycbcr_props.extensionName, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME,
1752                     sizeof(ycbcr_props.extensionName));
1753             ycbcr_props.specVersion = VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION;
1754             properties.push_back(ycbcr_props);
1755         }
1756         if (pProperties == nullptr) {
1757             *pPropertyCount = properties.size();
1758         } else {
1759             // return number of structures actually written to pProperties.
1760             *pPropertyCount = std::min((uint32_t)properties.size(), *pPropertyCount);
1761             memcpy(pProperties, properties.data(), *pPropertyCount * sizeof(VkExtensionProperties));
1762         }
1763         return *pPropertyCount < properties.size() ? VK_INCOMPLETE : VK_SUCCESS;
1764     }
1765 
on_vkCreateDevice(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice boxed_physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)1766     VkResult on_vkCreateDevice(android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
1767                                VkPhysicalDevice boxed_physicalDevice,
1768                                const VkDeviceCreateInfo* pCreateInfo,
1769                                const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) {
1770         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1771         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1772 
1773         std::vector<const char*> updatedDeviceExtensions =
1774             filteredDeviceExtensionNames(vk, physicalDevice, pCreateInfo->enabledExtensionCount,
1775                                          pCreateInfo->ppEnabledExtensionNames);
1776 
1777         m_vkEmulation->getDeviceLostHelper().addNeededDeviceExtensions(&updatedDeviceExtensions);
1778 
1779         uint32_t supportedFenceHandleTypes = 0;
1780         uint32_t supportedBinarySemaphoreHandleTypes = 0;
1781         // Run the underlying API call, filtering extensions.
1782 
1783         VkDeviceCreateInfo createInfoFiltered;
1784         deepcopy_VkDeviceCreateInfo(pool, VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, pCreateInfo,
1785                                       &createInfoFiltered);
1786 
1787         // According to the spec, it seems that the application can use compressed texture formats
1788         // without enabling the feature when creating the VkDevice, as long as
1789         // vkGetPhysicalDeviceFormatProperties and vkGetPhysicalDeviceImageFormatProperties reports
1790         // support: to query for additional properties, or if the feature is not enabled,
1791         // vkGetPhysicalDeviceFormatProperties and vkGetPhysicalDeviceImageFormatProperties can be
1792         // used to check for supported properties of individual formats as normal.
1793         bool emulateTextureEtc2 = needEmulatedEtc2(physicalDevice, vk);
1794         bool emulateTextureAstc = needEmulatedAstc(physicalDevice, vk);
1795         VkPhysicalDeviceFeatures featuresFiltered;
1796         std::vector<VkPhysicalDeviceFeatures*> featuresToFilter;
1797 
1798         if (pCreateInfo->pEnabledFeatures) {
1799             featuresFiltered = *pCreateInfo->pEnabledFeatures;
1800             createInfoFiltered.pEnabledFeatures = &featuresFiltered;
1801             featuresToFilter.emplace_back(&featuresFiltered);
1802         }
1803 
1804         // TODO(b/378686769): Force enable private data feature when available to
1805         //  mitigate the issues with duplicated vulkan handles. This should be
1806         //  removed once the issue is properly fixed.
1807         VkPhysicalDevicePrivateDataFeatures forceEnablePrivateData = {
1808             VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES,
1809             nullptr,
1810             VK_TRUE,
1811         };
1812         if (m_vkEmulation->supportsPrivateData()) {
1813             VkPhysicalDevicePrivateDataFeatures* privateDataFeatures =
1814                 vk_find_struct<VkPhysicalDevicePrivateDataFeatures>(&createInfoFiltered);
1815             if (privateDataFeatures != nullptr) {
1816                 privateDataFeatures->privateData = VK_TRUE;
1817             } else {
1818                 // Insert into device create info chain
1819                 forceEnablePrivateData.pNext = const_cast<void*>(createInfoFiltered.pNext);
1820                 createInfoFiltered.pNext = &forceEnablePrivateData;
1821                 privateDataFeatures = &forceEnablePrivateData;
1822             }
1823         }
1824 
1825         VkPhysicalDeviceRobustness2FeaturesEXT modifiedRobustness2features;
1826         const auto r2features = m_vkEmulation->getRobustness2Features();
1827         if (r2features && vk_find_struct<VkPhysicalDeviceRobustness2FeaturesEXT>(
1828                                        &createInfoFiltered) == nullptr) {
1829             VERBOSE("Force-enabling VK_EXT_robustness2 on device creation.");
1830             updatedDeviceExtensions.push_back(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
1831             modifiedRobustness2features = *r2features;
1832             modifiedRobustness2features.pNext = const_cast<void*>(createInfoFiltered.pNext);
1833             createInfoFiltered.pNext = &modifiedRobustness2features;
1834         }
1835 
1836         if (VkPhysicalDeviceFeatures2* features2 =
1837                 vk_find_struct<VkPhysicalDeviceFeatures2>(&createInfoFiltered)) {
1838             featuresToFilter.emplace_back(&features2->features);
1839         }
1840 
1841         {
1842             // Protected memory is not supported on emulators. Override feature
1843             // information to mark as unsupported (see b/329845987).
1844             VkPhysicalDeviceProtectedMemoryFeatures* protectedMemoryFeatures =
1845                 vk_find_struct<VkPhysicalDeviceProtectedMemoryFeatures>(&createInfoFiltered);
1846             if (protectedMemoryFeatures != nullptr) {
1847                 protectedMemoryFeatures->protectedMemory = VK_FALSE;
1848             }
1849 
1850             VkPhysicalDeviceVulkan11Features* vk11Features =
1851                 vk_find_struct<VkPhysicalDeviceVulkan11Features>(&createInfoFiltered);
1852             if (vk11Features != nullptr) {
1853                 vk11Features->protectedMemory = VK_FALSE;
1854             }
1855 
1856             for (uint32_t i = 0; i < createInfoFiltered.queueCreateInfoCount; i++) {
1857                 (const_cast<VkDeviceQueueCreateInfo*>(createInfoFiltered.pQueueCreateInfos))[i]
1858                     .flags &= ~VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
1859             }
1860         }
1861 
1862         VkPhysicalDeviceDiagnosticsConfigFeaturesNV deviceDiagnosticsConfigFeatures = {
1863             .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV,
1864             .diagnosticsConfig = VK_TRUE,
1865         };
1866         if (m_vkEmulation->commandBufferCheckpointsEnabled()) {
1867             deviceDiagnosticsConfigFeatures.pNext = const_cast<void*>(createInfoFiltered.pNext);
1868             createInfoFiltered.pNext = &deviceDiagnosticsConfigFeatures;
1869         }
1870 
1871         for (VkPhysicalDeviceFeatures* feature : featuresToFilter) {
1872             if (emulateTextureEtc2) {
1873                 feature->textureCompressionETC2 = VK_FALSE;
1874             }
1875             if (emulateTextureAstc) {
1876                 feature->textureCompressionASTC_LDR = VK_FALSE;
1877             }
1878         }
1879 
1880         if (auto* ycbcrFeatures = vk_find_struct<VkPhysicalDeviceSamplerYcbcrConversionFeatures>(
1881                 &createInfoFiltered)) {
1882             if (m_vkEmulation->isYcbcrEmulationEnabled() &&
1883                 !m_vkEmulation->supportsSamplerYcbcrConversion()) {
1884                 ycbcrFeatures->samplerYcbcrConversion = VK_FALSE;
1885             }
1886         }
1887 
1888         if (auto* swapchainMaintenance1Features =
1889                 vk_find_struct<VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT>(
1890                     &createInfoFiltered)) {
1891             if (!supportsSwapchainMaintenance1(physicalDevice, vk)) {
1892                 swapchainMaintenance1Features->swapchainMaintenance1 = VK_FALSE;
1893             }
1894         }
1895 
1896         VkDeviceQueueCreateInfo filteredQueueCreateInfo = {};
1897         // Use VulkanVirtualQueue directly to avoid locking for hasVirtualGraphicsQueue call.
1898         if (m_vkEmulation->getFeatures().VulkanVirtualQueue.enabled &&
1899             (createInfoFiltered.queueCreateInfoCount == 1) &&
1900             (createInfoFiltered.pQueueCreateInfos[0].queueCount == 2)) {
1901             // In virtual secondary queue mode, we should filter the queue count
1902             // value inside the device create info before calling the underlying driver.
1903             filteredQueueCreateInfo = createInfoFiltered.pQueueCreateInfos[0];
1904             filteredQueueCreateInfo.queueCount = 1;
1905             createInfoFiltered.pQueueCreateInfos = &filteredQueueCreateInfo;
1906         }
1907 
1908 #ifdef __APPLE__
1909 #ifndef VK_ENABLE_BETA_EXTENSIONS
1910         // TODO(b/349066492): Update Vulkan headers, stringhelpers and compilation parameters
1911         // to use this directly from beta extensions and use regular chain append commands
1912         const VkStructureType VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR =
1913             (VkStructureType)1000163000;
1914 #endif
1915         // Enable all portability features supported on the device
1916         VkPhysicalDevicePortabilitySubsetFeaturesKHR supportedPortabilityFeatures = {
1917             VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR, nullptr};
1918         if (m_vkEmulation->supportsMoltenVk()) {
1919             VkPhysicalDeviceFeatures2 features2 = {
1920                 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
1921                 .pNext = &supportedPortabilityFeatures,
1922             };
1923             vk->vkGetPhysicalDeviceFeatures2(physicalDevice, &features2);
1924 
1925             if (mVerbosePrints) {
1926                 fprintf(stderr,
1927                         "VERBOSE:%s: MoltenVK supportedPortabilityFeatures\n"
1928                         "constantAlphaColorBlendFactors = %d\n"
1929                         "events = %d\n"
1930                         "imageViewFormatReinterpretation = %d\n"
1931                         "imageViewFormatSwizzle = %d\n"
1932                         "imageView2DOn3DImage = %d\n"
1933                         "multisampleArrayImage = %d\n"
1934                         "mutableComparisonSamplers = %d\n"
1935                         "pointPolygons = %d\n"
1936                         "samplerMipLodBias = %d\n"
1937                         "separateStencilMaskRef = %d\n"
1938                         "shaderSampleRateInterpolationFunctions = %d\n"
1939                         "tessellationIsolines = %d\n"
1940                         "tessellationPointMode = %d\n"
1941                         "triangleFans = %d\n"
1942                         "vertexAttributeAccessBeyondStride = %d\n",
1943                         __func__, supportedPortabilityFeatures.constantAlphaColorBlendFactors,
1944                         supportedPortabilityFeatures.events,
1945                         supportedPortabilityFeatures.imageViewFormatReinterpretation,
1946                         supportedPortabilityFeatures.imageViewFormatSwizzle,
1947                         supportedPortabilityFeatures.imageView2DOn3DImage,
1948                         supportedPortabilityFeatures.multisampleArrayImage,
1949                         supportedPortabilityFeatures.mutableComparisonSamplers,
1950                         supportedPortabilityFeatures.pointPolygons,
1951                         supportedPortabilityFeatures.samplerMipLodBias,
1952                         supportedPortabilityFeatures.separateStencilMaskRef,
1953                         supportedPortabilityFeatures.shaderSampleRateInterpolationFunctions,
1954                         supportedPortabilityFeatures.tessellationIsolines,
1955                         supportedPortabilityFeatures.tessellationPointMode,
1956                         supportedPortabilityFeatures.triangleFans,
1957                         supportedPortabilityFeatures.vertexAttributeAccessBeyondStride);
1958             }
1959 
1960             // Insert into device create info chain
1961             supportedPortabilityFeatures.pNext = const_cast<void*>(createInfoFiltered.pNext);
1962             createInfoFiltered.pNext = &supportedPortabilityFeatures;
1963         }
1964 #endif
1965 
1966         // Filter device memory report as callbacks can not be passed between guest and host.
1967         vk_struct_chain_filter<VkDeviceDeviceMemoryReportCreateInfoEXT>(&createInfoFiltered);
1968 
1969         // Filter device groups as they are effectively disabled.
1970         vk_struct_chain_filter<VkDeviceGroupDeviceCreateInfo>(&createInfoFiltered);
1971 
1972         createInfoFiltered.enabledExtensionCount = (uint32_t)updatedDeviceExtensions.size();
1973         createInfoFiltered.ppEnabledExtensionNames = updatedDeviceExtensions.data();
1974 
1975 #if defined(__linux__)
1976         // TODO(b/401005629) always lock before the call on linux
1977         const bool doLockEarly = true;
1978 #else
1979         const bool swiftshader =
1980             (android::base::getEnvironmentVariable("ANDROID_EMU_VK_ICD").compare("swiftshader") ==
1981              0);
1982         // b/155795731: swiftshader needs to lock early.
1983         const bool doLockEarly = swiftshader;
1984 #endif
1985         VkResult result = VK_SUCCESS;
1986         if (!doLockEarly) {
1987             result = vk->vkCreateDevice(physicalDevice, &createInfoFiltered, pAllocator, pDevice);
1988         }
1989         std::lock_guard<std::mutex> lock(mMutex);
1990         if (doLockEarly) {
1991             result = vk->vkCreateDevice(physicalDevice, &createInfoFiltered, pAllocator, pDevice);
1992         }
1993 
1994         if (result != VK_SUCCESS) {
1995             WARN("Failed to create VkDevice: %s.", string_VkResult(result));
1996             return result;
1997         }
1998 
1999         mDeviceToPhysicalDevice[*pDevice] = physicalDevice;
2000 
2001         auto physicalDeviceInfoIt = mPhysdevInfo.find(physicalDevice);
2002         if (physicalDeviceInfoIt == mPhysdevInfo.end()) return VK_ERROR_INITIALIZATION_FAILED;
2003         auto& physicalDeviceInfo = physicalDeviceInfoIt->second;
2004 
2005         auto instanceInfoIt = mInstanceInfo.find(physicalDeviceInfo.instance);
2006         if (instanceInfoIt == mInstanceInfo.end()) return VK_ERROR_INITIALIZATION_FAILED;
2007         auto& instanceInfo = instanceInfoIt->second;
2008 
2009         // Fill out information about the logical device here.
2010         VALIDATE_NEW_HANDLE_INFO_ENTRY(mDeviceInfo, *pDevice);
2011         auto& deviceInfo = mDeviceInfo[*pDevice];
2012         deviceInfo.physicalDevice = physicalDevice;
2013         deviceInfo.emulateTextureEtc2 = emulateTextureEtc2;
2014         deviceInfo.emulateTextureAstc = emulateTextureAstc;
2015         deviceInfo.useAstcCpuDecompression =
2016             m_vkEmulation->getAstcLdrEmulationMode() == AstcEmulationMode::Cpu &&
2017             AstcCpuDecompressor::get().available();
2018         deviceInfo.decompPipelines =
2019             std::make_unique<GpuDecompressionPipelineManager>(m_vk, *pDevice);
2020         getSupportedFenceHandleTypes(vk, physicalDevice, &supportedFenceHandleTypes);
2021         getSupportedSemaphoreHandleTypes(vk, physicalDevice, &supportedBinarySemaphoreHandleTypes);
2022 
2023         deviceInfo.externalFenceInfo.supportedFenceHandleTypes =
2024             static_cast<VkExternalFenceHandleTypeFlagBits>(supportedFenceHandleTypes);
2025         deviceInfo.externalFenceInfo.supportedBinarySemaphoreHandleTypes =
2026             static_cast<VkExternalSemaphoreHandleTypeFlagBits>(supportedBinarySemaphoreHandleTypes);
2027 
2028         INFO("Created VkDevice:%p for application:%s engine:%s ASTC emulation:%s CPU decoding:%s.",
2029              *pDevice, instanceInfo.applicationName.c_str(), instanceInfo.engineName.c_str(),
2030              deviceInfo.emulateTextureAstc ? "on" : "off",
2031              deviceInfo.useAstcCpuDecompression ? "on" : "off");
2032 
2033         for (uint32_t i = 0; i < createInfoFiltered.enabledExtensionCount; ++i) {
2034             deviceInfo.enabledExtensionNames.push_back(
2035                 createInfoFiltered.ppEnabledExtensionNames[i]);
2036         }
2037 
2038         // First, get the dispatch table.
2039         VkDevice boxedDevice = new_boxed_VkDevice(*pDevice, nullptr, true /* own dispatch */);
2040 
2041         if (mLogging) {
2042             INFO("%s: init vulkan dispatch from device", __func__);
2043         }
2044 
2045         VulkanDispatch* dispatch = dispatch_VkDevice(boxedDevice);
2046         init_vulkan_dispatch_from_device(vk, *pDevice, dispatch);
2047         if (m_vkEmulation->debugUtilsEnabled()) {
2048             deviceInfo.debugUtilsHelper = DebugUtilsHelper::withUtilsEnabled(*pDevice, dispatch);
2049         }
2050 
2051         deviceInfo.externalFencePool =
2052             std::make_unique<ExternalFencePool<VulkanDispatch>>(dispatch, *pDevice);
2053 
2054         deviceInfo.deviceOpTracker = std::make_shared<DeviceOpTracker>(*pDevice, dispatch);
2055 
2056         if (mLogging) {
2057             INFO("%s: init vulkan dispatch from device (end)", __func__);
2058         }
2059 
2060         deviceInfo.boxed = boxedDevice;
2061 
2062         DeviceLostHelper::DeviceWithQueues deviceWithQueues = {
2063             .device = *pDevice,
2064             .deviceDispatch = dispatch,
2065         };
2066 
2067         if (mSnapshotState == SnapshotState::Loading) {
2068             if (!mSnapshotLoadVkDeviceToVirtioCpuContextId) {
2069                 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
2070                     << "Missing device to context id map during snapshot load.";
2071             }
2072             auto contextIdIt = mSnapshotLoadVkDeviceToVirtioCpuContextId->find(boxedDevice);
2073             if (contextIdIt == mSnapshotLoadVkDeviceToVirtioCpuContextId->end()) {
2074                 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
2075                     << "Missing context id for VkDevice:" << boxedDevice;
2076             }
2077             deviceInfo.virtioGpuContextId = contextIdIt->second;
2078         } else {
2079             auto* renderThreadInfo = RenderThreadInfoVk::get();
2080             deviceInfo.virtioGpuContextId = renderThreadInfo->ctx_id;
2081         }
2082 
2083         // Next, get information about the queue families used by this device.
2084         std::unordered_map<uint32_t, uint32_t> queueFamilyIndexCounts;
2085         for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
2086             const auto& queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
2087             // Check only queues created with flags = 0 in VkDeviceQueueCreateInfo.
2088             auto flags = queueCreateInfo.flags;
2089             if (flags) continue;
2090             uint32_t queueFamilyIndex = queueCreateInfo.queueFamilyIndex;
2091             uint32_t queueCount = queueCreateInfo.queueCount;
2092             queueFamilyIndexCounts[queueFamilyIndex] = queueCount;
2093         }
2094 
2095         std::vector<uint64_t> extraHandles;
2096         for (auto it : queueFamilyIndexCounts) {
2097             auto index = it.first;
2098             auto count = it.second;
2099             auto addVirtualQueue =
2100                 (count == 2) && physicalDeviceInfo.queuePropertiesHelper->hasVirtualGraphicsQueue();
2101             auto& queues = deviceInfo.queues[index];
2102             for (uint32_t i = 0; i < count; ++i) {
2103                 VkQueue physicalQueue;
2104 
2105                 if (mLogging) {
2106                     INFO("%s: get device queue (begin)", __func__);
2107                 }
2108 
2109                 assert(i == 0 || !addVirtualQueue);
2110                 vk->vkGetDeviceQueue(*pDevice, index, i, &physicalQueue);
2111 
2112                 if (mLogging) {
2113                     INFO("%s: get device queue (end)", __func__);
2114                 }
2115                 auto boxedQueue =
2116                     new_boxed_VkQueue(physicalQueue, dispatch, false /* does not own dispatch */);
2117                 extraHandles.push_back((uint64_t)boxedQueue);
2118 
2119                 VALIDATE_NEW_HANDLE_INFO_ENTRY(mQueueInfo, physicalQueue);
2120                 QueueInfo& physicalQueueInfo = mQueueInfo[physicalQueue];
2121                 physicalQueueInfo.device = *pDevice;
2122                 physicalQueueInfo.queueFamilyIndex = index;
2123                 physicalQueueInfo.boxed = boxedQueue;
2124                 physicalQueueInfo.queueMutex = std::make_shared<std::mutex>();
2125                 queues.push_back(physicalQueue);
2126 
2127                 deviceWithQueues.queues.push_back(DeviceLostHelper::QueueWithMutex{
2128                     .queue = physicalQueue,
2129                     .queueMutex = physicalQueueInfo.queueMutex,
2130                 });
2131 
2132                 if (addVirtualQueue) {
2133                     VERBOSE("Creating virtual device queue for physical VkQueue %p", physicalQueue);
2134                     const uint64_t physicalQueue64 = reinterpret_cast<uint64_t>(physicalQueue);
2135 
2136                     if ((physicalQueue64 & QueueInfo::kVirtualQueueBit) != 0) {
2137                         // Cannot use queue virtualization on this GPU, where the pysical handle
2138                         // values generated are not 2-byte aligned. This is very unusual, but the
2139                         // spec is not enforcing handle values to be aligned and the driver is free
2140                         // to use a similar logic to use the last bit for other purposes.
2141                         // In this case, we ask users to disable the virtual queue support as
2142                         // handling the error dynamically is not feasible.
2143                         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
2144                             << "Cannot use `VulkanVirtualQueue` feature: Unexpected physical queue "
2145                                "handle value.";
2146                     } else {
2147                         uint64_t virtualQueue64 = (physicalQueue64 | QueueInfo::kVirtualQueueBit);
2148                         VkQueue virtualQueue = reinterpret_cast<VkQueue>(virtualQueue64);
2149 
2150                         auto boxedVirtualQueue = new_boxed_VkQueue(
2151                             virtualQueue, dispatch, false /* does not own dispatch */);
2152                         extraHandles.push_back((uint64_t)boxedVirtualQueue);
2153 
2154                         VALIDATE_NEW_HANDLE_INFO_ENTRY(mQueueInfo, virtualQueue);
2155                         QueueInfo& virtualQueueInfo = mQueueInfo[virtualQueue];
2156                         virtualQueueInfo.device = physicalQueueInfo.device;
2157                         virtualQueueInfo.queueFamilyIndex = physicalQueueInfo.queueFamilyIndex;
2158                         virtualQueueInfo.boxed = boxedVirtualQueue;
2159                         virtualQueueInfo.queueMutex = physicalQueueInfo.queueMutex;  // Shares the same lock!
2160                         queues.push_back(virtualQueue);
2161                     }
2162                     i++;
2163                 }
2164             }
2165         }
2166         if (snapshotsEnabled() && snapshotInfo) {
2167             snapshotInfo->addOrderedBoxedHandlesCreatedByCall(extraHandles.data(),
2168                                                               extraHandles.size());
2169         }
2170 
2171         m_vkEmulation->getDeviceLostHelper().onDeviceCreated(std::move(deviceWithQueues));
2172 
2173         // Box the device.
2174         *pDevice = (VkDevice)deviceInfo.boxed;
2175 
2176         if (mLogging) {
2177             INFO("%s: (end)", __func__);
2178         }
2179 
2180         return VK_SUCCESS;
2181     }
2182 
on_vkGetDeviceQueue(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,uint32_t queueFamilyIndex,uint32_t queueIndex,VkQueue * pQueue)2183     void on_vkGetDeviceQueue(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2184                              VkDevice boxed_device, uint32_t queueFamilyIndex, uint32_t queueIndex,
2185                              VkQueue* pQueue) {
2186         auto device = unbox_VkDevice(boxed_device);
2187 
2188         std::lock_guard<std::mutex> lock(mMutex);
2189 
2190         *pQueue = VK_NULL_HANDLE;
2191 
2192         auto* deviceInfo = android::base::find(mDeviceInfo, device);
2193         if (!deviceInfo) return;
2194 
2195         const auto& queues = deviceInfo->queues;
2196 
2197         const auto* queueList = android::base::find(queues, queueFamilyIndex);
2198         if (!queueList) return;
2199         if (queueIndex >= queueList->size()) return;
2200 
2201         VkQueue unboxedQueue = (*queueList)[queueIndex];
2202 
2203         auto* queueInfo = android::base::find(mQueueInfo, unboxedQueue);
2204         if (!queueInfo) {
2205             ERR("vkGetDeviceQueue failed on queue: %p", unboxedQueue);
2206             return;
2207         }
2208 
2209         *pQueue = queueInfo->boxed;
2210     }
2211 
on_vkGetDeviceQueue2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkDeviceQueueInfo2 * pQueueInfo,VkQueue * pQueue)2212     void on_vkGetDeviceQueue2(android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
2213                               VkDevice boxed_device, const VkDeviceQueueInfo2* pQueueInfo,
2214                               VkQueue* pQueue) {
2215         // Protected memory is not supported on emulators. So we should
2216         // not return any queue if a client requests a protected device
2217         // queue. See b/328436383.
2218         if (pQueueInfo->flags & VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT) {
2219             *pQueue = VK_NULL_HANDLE;
2220             WARN("%s: Cannot get protected Vulkan device queue", __func__);
2221             return;
2222         }
2223         uint32_t queueFamilyIndex = pQueueInfo->queueFamilyIndex;
2224         uint32_t queueIndex = pQueueInfo->queueIndex;
2225         on_vkGetDeviceQueue(pool, snapshotInfo, boxed_device, queueFamilyIndex, queueIndex, pQueue);
2226     }
2227 
destroyDeviceWithExclusiveInfo(VkDevice device,DeviceInfo & deviceInfo,std::unordered_map<VkFence,FenceInfo> & fenceInfos,std::unordered_map<VkQueue,QueueInfo> & queueInfos,const VkAllocationCallbacks * pAllocator)2228     void destroyDeviceWithExclusiveInfo(VkDevice device, DeviceInfo& deviceInfo,
2229                                         std::unordered_map<VkFence, FenceInfo>& fenceInfos,
2230                                         std::unordered_map<VkQueue, QueueInfo>& queueInfos,
2231                                         const VkAllocationCallbacks* pAllocator) {
2232         m_vkEmulation->getDeviceLostHelper().onDeviceDestroyed(device);
2233 
2234         deviceInfo.decompPipelines->clear();
2235 
2236         auto eraseIt = queueInfos.begin();
2237         for (; eraseIt != queueInfos.end();) {
2238             if (eraseIt->second.device == device) {
2239                 eraseIt->second.queueMutex.reset();
2240                 delete_VkQueue(eraseIt->second.boxed);
2241                 eraseIt = queueInfos.erase(eraseIt);
2242             } else {
2243                 ++eraseIt;
2244             }
2245         }
2246 
2247         VulkanDispatch* deviceDispatch = dispatch_VkDevice(deviceInfo.boxed);
2248 
2249         for (auto fenceInfoIt = fenceInfos.begin(); fenceInfoIt != fenceInfos.end();) {
2250             auto fence = fenceInfoIt->first;
2251             auto& fenceInfo = fenceInfoIt->second;
2252             if (fenceInfo.device == device) {
2253                 destroyFenceWithExclusiveInfo(device, deviceDispatch, deviceInfo, fence, fenceInfo,
2254                                               nullptr, /*allowExternalFenceRecycling=*/false);
2255                 fenceInfoIt = fenceInfos.erase(fenceInfoIt);
2256             } else {
2257                 ++fenceInfoIt;
2258             }
2259         }
2260 
2261         // Should happen before destroying fences
2262         deviceInfo.deviceOpTracker->OnDestroyDevice();
2263 
2264         // Destroy pooled external fences
2265         auto deviceFences = deviceInfo.externalFencePool->popAll();
2266         for (auto fence : deviceFences) {
2267             deviceDispatch->vkDestroyFence(device, fence, pAllocator);
2268             fenceInfos.erase(fence);
2269         }
2270         deviceInfo.externalFencePool.reset();
2271 
2272         // Run the underlying API call.
2273         {
2274             AutoLock lock(*graphicsDriverLock());
2275             m_vk->vkDestroyDevice(device, pAllocator);
2276         }
2277 
2278         INFO("Destroyed VkDevice:%p", device);
2279         delete_VkDevice(deviceInfo.boxed);
2280     }
2281 
destroyDeviceLocked(VkDevice device,const VkAllocationCallbacks * pAllocator)2282     void destroyDeviceLocked(VkDevice device, const VkAllocationCallbacks* pAllocator) REQUIRES(mMutex) {
2283         auto deviceInfoIt = mDeviceInfo.find(device);
2284         if (deviceInfoIt == mDeviceInfo.end()) return;
2285 
2286         InstanceObjects::DeviceObjects deviceObjects;
2287         deviceObjects.device = mDeviceInfo.extract(deviceInfoIt);
2288         extractDeviceAndDependenciesLocked(device, deviceObjects);
2289         destroyDeviceObjects(deviceObjects);
2290 
2291         mDeviceInfo.erase(device);
2292         mDeviceToPhysicalDevice.erase(device);
2293     }
2294 
on_vkDestroyDevice(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkAllocationCallbacks * pAllocator)2295     void on_vkDestroyDevice(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2296                             VkDevice boxed_device, const VkAllocationCallbacks* pAllocator) {
2297         auto device = unbox_VkDevice(boxed_device);
2298 
2299         processDelayedRemovesForDevice(device);
2300 
2301         std::lock_guard<std::mutex> lock(mMutex);
2302 
2303         destroyDeviceLocked(device, pAllocator);
2304     }
2305 
on_vkCreateBuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer)2306     VkResult on_vkCreateBuffer(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2307                                VkDevice boxed_device, const VkBufferCreateInfo* pCreateInfo,
2308                                const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer) {
2309         auto device = unbox_VkDevice(boxed_device);
2310         auto vk = dispatch_VkDevice(boxed_device);
2311         VkBufferCreateInfo localCreateInfo;
2312         if (snapshotsEnabled()) {
2313             localCreateInfo = *pCreateInfo;
2314             // Add transfer src bit for potential device local memories.
2315             //
2316             // There are 3 ways to populate buffer content:
2317             //   a) use host coherent memory and memory mapping;
2318             //   b) use transfer_dst and vkcmdcopy* (for device local memories);
2319             //   c) use storage and compute shaders.
2320             //
2321             // (a) is covered by memory snapshot. (b) requires an extra vkCmdCopyBuffer
2322             // command on snapshot, thuse we need to add transfer_src for (b) so that
2323             // they could be loaded back on snapshot save. (c) is still future work.
2324             if (localCreateInfo.usage & VK_BUFFER_USAGE_TRANSFER_DST_BIT) {
2325                 localCreateInfo.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
2326             }
2327             pCreateInfo = &localCreateInfo;
2328         }
2329 
2330         VkExternalMemoryBufferCreateInfo externalCI = {
2331             VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO};
2332         if (m_vkEmulation->getFeatures().VulkanAllocateHostMemory.enabled) {
2333             localCreateInfo = *pCreateInfo;
2334             // Hint that we 'may' use host allocation for this buffer. This will only be used for
2335             // host visible memory.
2336             externalCI.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
2337 
2338             // Insert the new struct to the chain
2339             externalCI.pNext = localCreateInfo.pNext;
2340             localCreateInfo.pNext = &externalCI;
2341 
2342             pCreateInfo = &localCreateInfo;
2343         }
2344 
2345         VkResult result = vk->vkCreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
2346 
2347         if (result == VK_SUCCESS) {
2348             std::lock_guard<std::mutex> lock(mMutex);
2349             VALIDATE_NEW_HANDLE_INFO_ENTRY(mBufferInfo, *pBuffer);
2350             auto& bufInfo = mBufferInfo[*pBuffer];
2351             bufInfo.device = device;
2352             bufInfo.usage = pCreateInfo->usage;
2353             bufInfo.size = pCreateInfo->size;
2354             *pBuffer = new_boxed_non_dispatchable_VkBuffer(*pBuffer);
2355         }
2356 
2357         return result;
2358     }
2359 
destroyBufferWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkBuffer buffer,BufferInfo & bufferInfo,const VkAllocationCallbacks * pAllocator)2360     void destroyBufferWithExclusiveInfo(VkDevice device, VulkanDispatch* deviceDispatch,
2361                                         VkBuffer buffer, BufferInfo& bufferInfo,
2362                                         const VkAllocationCallbacks* pAllocator) {
2363         deviceDispatch->vkDestroyBuffer(device, buffer, pAllocator);
2364     }
2365 
destroyBufferLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkBuffer buffer,const VkAllocationCallbacks * pAllocator)2366     void destroyBufferLocked(VkDevice device, VulkanDispatch* deviceDispatch, VkBuffer buffer,
2367                              const VkAllocationCallbacks* pAllocator) REQUIRES(mMutex) {
2368         auto bufferInfoIt = mBufferInfo.find(buffer);
2369         if (bufferInfoIt == mBufferInfo.end()) return;
2370         auto& bufferInfo = bufferInfoIt->second;
2371 
2372         destroyBufferWithExclusiveInfo(device, deviceDispatch, buffer, bufferInfo, pAllocator);
2373 
2374         mBufferInfo.erase(buffer);
2375     }
2376 
on_vkDestroyBuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkBuffer buffer,const VkAllocationCallbacks * pAllocator)2377     void on_vkDestroyBuffer(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2378                             VkDevice boxed_device, VkBuffer buffer,
2379                             const VkAllocationCallbacks* pAllocator) {
2380         auto device = unbox_VkDevice(boxed_device);
2381         auto deviceDispatch = dispatch_VkDevice(boxed_device);
2382 
2383         std::lock_guard<std::mutex> lock(mMutex);
2384         destroyBufferLocked(device, deviceDispatch, buffer, pAllocator);
2385     }
2386 
setBufferMemoryBindInfoLocked(VkDevice device,VkBuffer buffer,VkDeviceMemory memory,VkDeviceSize memoryOffset)2387     VkResult setBufferMemoryBindInfoLocked(VkDevice device, VkBuffer buffer, VkDeviceMemory memory,
2388                                        VkDeviceSize memoryOffset) REQUIRES(mMutex) {
2389         auto* bufferInfo = android::base::find(mBufferInfo, buffer);
2390         if (!bufferInfo) {
2391             WARN("%s: failed to find buffer info!", __func__);
2392             return VK_ERROR_OUT_OF_HOST_MEMORY;
2393         }
2394         bufferInfo->memory = memory;
2395         bufferInfo->memoryOffset = memoryOffset;
2396 
2397         auto* memoryInfo = android::base::find(mMemoryInfo, memory);
2398         if (memoryInfo && memoryInfo->boundBuffer) {
2399             auto* deviceInfo = android::base::find(mDeviceInfo, device);
2400             if (deviceInfo) {
2401                 deviceInfo->debugUtilsHelper.addDebugLabel(buffer, "Buffer:%d",
2402                                                            *memoryInfo->boundBuffer);
2403             }
2404         }
2405         return VK_SUCCESS;
2406     }
2407 
on_vkBindBufferMemory(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkBuffer buffer,VkDeviceMemory memory,VkDeviceSize memoryOffset)2408     VkResult on_vkBindBufferMemory(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2409                                    VkDevice boxed_device, VkBuffer buffer, VkDeviceMemory memory,
2410                                    VkDeviceSize memoryOffset) {
2411         auto device = unbox_VkDevice(boxed_device);
2412         auto vk = dispatch_VkDevice(boxed_device);
2413 
2414         VALIDATE_REQUIRED_HANDLE(memory);
2415         VkResult result = vk->vkBindBufferMemory(device, buffer, memory, memoryOffset);
2416         if (result != VK_SUCCESS) {
2417             return result;
2418         }
2419 
2420         std::lock_guard<std::mutex> lock(mMutex);
2421         return setBufferMemoryBindInfoLocked(device, buffer, memory, memoryOffset);
2422     }
2423 
on_vkBindBufferMemory2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,uint32_t bindInfoCount,const VkBindBufferMemoryInfo * pBindInfos)2424     VkResult on_vkBindBufferMemory2(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2425                                     VkDevice boxed_device, uint32_t bindInfoCount,
2426                                     const VkBindBufferMemoryInfo* pBindInfos) {
2427         auto device = unbox_VkDevice(boxed_device);
2428         auto vk = dispatch_VkDevice(boxed_device);
2429 
2430         for (uint32_t i = 0; i < bindInfoCount; ++i) {
2431             VALIDATE_REQUIRED_HANDLE(pBindInfos[i].memory);
2432         }
2433         VkResult result = vk->vkBindBufferMemory2(device, bindInfoCount, pBindInfos);
2434         if (result != VK_SUCCESS) {
2435             return result;
2436         }
2437 
2438         std::lock_guard<std::mutex> lock(mMutex);
2439         for (uint32_t i = 0; i < bindInfoCount; ++i) {
2440             result = setBufferMemoryBindInfoLocked(device, pBindInfos[i].buffer, pBindInfos[i].memory,
2441                                             pBindInfos[i].memoryOffset);
2442             if (result != VK_SUCCESS) {
2443                 return result;
2444             }
2445         }
2446 
2447         return VK_SUCCESS;
2448     }
2449 
on_vkBindBufferMemory2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,uint32_t bindInfoCount,const VkBindBufferMemoryInfo * pBindInfos)2450     VkResult on_vkBindBufferMemory2KHR(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2451                                        VkDevice boxed_device, uint32_t bindInfoCount,
2452                                        const VkBindBufferMemoryInfo* pBindInfos) {
2453         auto device = unbox_VkDevice(boxed_device);
2454         auto vk = dispatch_VkDevice(boxed_device);
2455 
2456         for (uint32_t i = 0; i < bindInfoCount; ++i) {
2457             VALIDATE_REQUIRED_HANDLE(pBindInfos[i].memory);
2458         }
2459         VkResult result = vk->vkBindBufferMemory2KHR(device, bindInfoCount, pBindInfos);
2460 
2461         if (result == VK_SUCCESS) {
2462             std::lock_guard<std::mutex> lock(mMutex);
2463             for (uint32_t i = 0; i < bindInfoCount; ++i) {
2464                 setBufferMemoryBindInfoLocked(device, pBindInfos[i].buffer, pBindInfos[i].memory,
2465                                               pBindInfos[i].memoryOffset);
2466             }
2467         }
2468 
2469         return result;
2470     }
2471 
on_vkCreateImage(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage,bool boxImage=true)2472     VkResult on_vkCreateImage(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2473                               VkDevice boxed_device, const VkImageCreateInfo* pCreateInfo,
2474                               const VkAllocationCallbacks* pAllocator, VkImage* pImage,
2475                               bool boxImage = true) {
2476         auto device = unbox_VkDevice(boxed_device);
2477         auto vk = dispatch_VkDevice(boxed_device);
2478 
2479         if (pCreateInfo->format == VK_FORMAT_UNDEFINED) {
2480             // VUID-VkImageCreateInfo-pNext-01975:
2481             // If the pNext chain does not include a VkExternalFormatANDROID structure, or does
2482             // and its externalFormat member is 0, the format must not be VK_FORMAT_UNDEFINED.
2483             //
2484             // VkExternalFormatANDROID usages should be replaced with Vulkan formats on the guest
2485             // side during image creation. We don't support external formats on the host side and
2486             // format should be valid at this stage. This error indicates usage of an unsupported
2487             // external format, or an old system image.
2488             // We handle this here to better report the error and avoid crashes in the driver.
2489             ERR("vkCreateImage called with VK_FORMAT_UNDEFINED, external format is not supported.");
2490             return VK_ERROR_INITIALIZATION_FAILED;
2491         }
2492 
2493         std::lock_guard<std::mutex> lock(mMutex);
2494 
2495         auto* deviceInfo = android::base::find(mDeviceInfo, device);
2496         if (!deviceInfo) {
2497             return VK_ERROR_OUT_OF_HOST_MEMORY;
2498         }
2499 
2500         if (deviceInfo->imageFormats.find(pCreateInfo->format) == deviceInfo->imageFormats.end()) {
2501             VERBOSE("gfxstream_texture_format_manifest: %s [%d]", string_VkFormat(pCreateInfo->format), pCreateInfo->format);
2502             deviceInfo->imageFormats.insert(pCreateInfo->format);
2503         }
2504 
2505         const bool needDecompression = deviceInfo->needEmulatedDecompression(pCreateInfo->format);
2506         CompressedImageInfo cmpInfo =
2507             needDecompression
2508                 ? CompressedImageInfo(device, *pCreateInfo, deviceInfo->decompPipelines.get())
2509                 : CompressedImageInfo(device);
2510         VkImageCreateInfo decompInfo;
2511         if (needDecompression) {
2512             decompInfo = cmpInfo.getOutputCreateInfo(*pCreateInfo);
2513             pCreateInfo = &decompInfo;
2514         }
2515 
2516         std::unique_ptr<AndroidNativeBufferInfo> anbInfo = nullptr;
2517         const VkNativeBufferANDROID* nativeBufferANDROID =
2518             vk_find_struct<VkNativeBufferANDROID>(pCreateInfo);
2519 
2520         VkResult createRes = VK_SUCCESS;
2521 
2522         if (nativeBufferANDROID) {
2523             auto* physicalDevice = android::base::find(mDeviceToPhysicalDevice, device);
2524             if (!physicalDevice) {
2525                 return VK_ERROR_DEVICE_LOST;
2526             }
2527 
2528             auto* physicalDeviceInfo = android::base::find(mPhysdevInfo, *physicalDevice);
2529             if (!physicalDeviceInfo) {
2530                 return VK_ERROR_DEVICE_LOST;
2531             }
2532 
2533             const VkPhysicalDeviceMemoryProperties& memoryProperties =
2534                 physicalDeviceInfo->memoryPropertiesHelper->getHostMemoryProperties();
2535 
2536             anbInfo = AndroidNativeBufferInfo::create(
2537                 m_vkEmulation, vk, device, *pool, pCreateInfo, nativeBufferANDROID, pAllocator, &memoryProperties);
2538             if (anbInfo == nullptr) {
2539                 createRes = VK_ERROR_OUT_OF_DEVICE_MEMORY;
2540             }
2541 
2542             if (createRes == VK_SUCCESS) {
2543                 *pImage = anbInfo->getImage();
2544             }
2545         } else {
2546             createRes = vk->vkCreateImage(device, pCreateInfo, pAllocator, pImage);
2547         }
2548 
2549         if (createRes != VK_SUCCESS) return createRes;
2550 
2551         if (needDecompression) {
2552             cmpInfo.setOutputImage(*pImage);
2553             cmpInfo.createCompressedMipmapImages(vk, *pCreateInfo);
2554 
2555             if (cmpInfo.isAstc()) {
2556                 if (deviceInfo->useAstcCpuDecompression) {
2557                     cmpInfo.initAstcCpuDecompression(m_vk, mDeviceInfo[device].physicalDevice);
2558                 }
2559             }
2560         }
2561 
2562         VALIDATE_NEW_HANDLE_INFO_ENTRY(mImageInfo, *pImage);
2563         auto& imageInfo = mImageInfo[*pImage];
2564         imageInfo.device = device;
2565         imageInfo.cmpInfo = std::move(cmpInfo);
2566         imageInfo.imageCreateInfoShallow = vk_make_orphan_copy(*pCreateInfo);
2567         imageInfo.layout = pCreateInfo->initialLayout;
2568         imageInfo.anbInfo = std::move(anbInfo);
2569 
2570         if (boxImage) {
2571             *pImage = new_boxed_non_dispatchable_VkImage(*pImage);
2572         }
2573         return createRes;
2574     }
2575 
destroyImageWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkImage image,ImageInfo & imageInfo,const VkAllocationCallbacks * pAllocator)2576     void destroyImageWithExclusiveInfo(VkDevice device, VulkanDispatch* deviceDispatch,
2577                                        VkImage image, ImageInfo& imageInfo,
2578                                        const VkAllocationCallbacks* pAllocator) {
2579         if (!imageInfo.anbInfo) {
2580             imageInfo.cmpInfo.destroy(deviceDispatch);
2581             if (image != imageInfo.cmpInfo.outputImage()) {
2582                 deviceDispatch->vkDestroyImage(device, image, pAllocator);
2583             }
2584         }
2585 
2586         imageInfo.anbInfo.reset();
2587     }
2588 
destroyImageLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkImage image,const VkAllocationCallbacks * pAllocator)2589     void destroyImageLocked(VkDevice device, VulkanDispatch* deviceDispatch, VkImage image,
2590                             const VkAllocationCallbacks* pAllocator) REQUIRES(mMutex) {
2591         auto imageInfoIt = mImageInfo.find(image);
2592         if (imageInfoIt == mImageInfo.end()) return;
2593         auto& imageInfo = imageInfoIt->second;
2594 
2595         destroyImageWithExclusiveInfo(device, deviceDispatch, image, imageInfo, pAllocator);
2596 
2597         mImageInfo.erase(image);
2598     }
2599 
on_vkDestroyImage(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkImage image,const VkAllocationCallbacks * pAllocator)2600     void on_vkDestroyImage(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2601                            VkDevice boxed_device, VkImage image,
2602                            const VkAllocationCallbacks* pAllocator) {
2603         auto device = unbox_VkDevice(boxed_device);
2604         auto deviceDispatch = dispatch_VkDevice(boxed_device);
2605 
2606         std::lock_guard<std::mutex> lock(mMutex);
2607         destroyImageLocked(device, deviceDispatch, image, pAllocator);
2608     }
2609 
performBindImageMemoryDeferredAhb(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkBindImageMemoryInfo * bimi)2610     VkResult performBindImageMemoryDeferredAhb(android::base::BumpPool* pool,
2611                                                VkSnapshotApiCallInfo* snapshotInfo,
2612                                                VkDevice boxed_device,
2613                                                const VkBindImageMemoryInfo* bimi) {
2614         auto original_underlying_image = bimi->image;
2615         auto original_boxed_image = unboxed_to_boxed_non_dispatchable_VkImage(original_underlying_image);
2616 
2617         VkImageCreateInfo ici = {};
2618         {
2619             std::lock_guard<std::mutex> lock(mMutex);
2620 
2621             auto* imageInfo = android::base::find(mImageInfo, original_underlying_image);
2622             if (!imageInfo) {
2623                 ERR("Image for deferred AHB bind does not exist.");
2624                 return VK_ERROR_OUT_OF_HOST_MEMORY;
2625             }
2626 
2627             ici = imageInfo->imageCreateInfoShallow;
2628         }
2629 
2630         ici.pNext = vk_find_struct<VkNativeBufferANDROID>(bimi);
2631         if (!ici.pNext) {
2632             GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
2633                 << "Missing VkNativeBufferANDROID for deferred AHB bind.";
2634         }
2635 
2636         VkImage underlying_replacement_image = VK_NULL_HANDLE;
2637         VkResult result = on_vkCreateImage(pool, snapshotInfo, boxed_device, &ici, nullptr,
2638                                            &underlying_replacement_image, false);
2639         if (result != VK_SUCCESS) {
2640             ERR("Failed to create image for deferred AHB bind.");
2641             return VK_ERROR_OUT_OF_HOST_MEMORY;
2642         }
2643 
2644         on_vkDestroyImage(pool, snapshotInfo, boxed_device, original_underlying_image, nullptr);
2645 
2646         {
2647             std::lock_guard<std::mutex> lock(mMutex);
2648 
2649             set_boxed_non_dispatchable_VkImage(original_boxed_image, underlying_replacement_image);
2650             const_cast<VkBindImageMemoryInfo*>(bimi)->image = underlying_replacement_image;
2651             const_cast<VkBindImageMemoryInfo*>(bimi)->memory = nullptr;
2652         }
2653 
2654         return VK_SUCCESS;
2655     }
2656 
performBindImageMemory(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkBindImageMemoryInfo * bimi)2657     VkResult performBindImageMemory(android::base::BumpPool* pool,
2658                                     VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
2659                                     const VkBindImageMemoryInfo* bimi) EXCLUDES(mMutex) {
2660         auto image = bimi->image;
2661         auto memory = bimi->memory;
2662         auto memoryOffset = bimi->memoryOffset;
2663 
2664         const auto* anb = vk_find_struct<VkNativeBufferANDROID>(bimi);
2665         if (memory == VK_NULL_HANDLE && anb != nullptr) {
2666             return performBindImageMemoryDeferredAhb(pool, snapshotInfo, boxed_device, bimi);
2667         }
2668 
2669         auto device = unbox_VkDevice(boxed_device);
2670         auto vk = dispatch_VkDevice(boxed_device);
2671 
2672         VALIDATE_REQUIRED_HANDLE(memory);
2673         VkResult result = vk->vkBindImageMemory(device, image, memory, memoryOffset);
2674         if (result != VK_SUCCESS) {
2675             return result;
2676         }
2677 
2678         std::lock_guard<std::mutex> lock(mMutex);
2679 
2680         auto* deviceInfo = android::base::find(mDeviceInfo, device);
2681         if (!deviceInfo) return VK_ERROR_OUT_OF_HOST_MEMORY;
2682 
2683         auto* memoryInfo = android::base::find(mMemoryInfo, memory);
2684         if (!memoryInfo) return VK_ERROR_OUT_OF_HOST_MEMORY;
2685 
2686         auto* imageInfo = android::base::find(mImageInfo, image);
2687         if (!imageInfo) return VK_ERROR_OUT_OF_HOST_MEMORY;
2688         imageInfo->boundColorBuffer = memoryInfo->boundColorBuffer;
2689         if (imageInfo->boundColorBuffer) {
2690             deviceInfo->debugUtilsHelper.addDebugLabel(image, "ColorBuffer:%d",
2691                                                        *imageInfo->boundColorBuffer);
2692         }
2693         imageInfo->memory = memory;
2694 
2695         if (!deviceInfo->emulateTextureEtc2 && !deviceInfo->emulateTextureAstc) {
2696             return VK_SUCCESS;
2697         }
2698 
2699         CompressedImageInfo& cmpInfo = imageInfo->cmpInfo;
2700         if (!deviceInfo->needEmulatedDecompression(cmpInfo)) {
2701             return VK_SUCCESS;
2702         }
2703         return cmpInfo.bindCompressedMipmapsMemory(vk, memory, memoryOffset);
2704     }
2705 
on_vkBindImageMemory(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkImage image,VkDeviceMemory memory,VkDeviceSize memoryOffset)2706     VkResult on_vkBindImageMemory(android::base::BumpPool* pool,
2707                                   VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
2708                                   VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset)
2709         EXCLUDES(mMutex) {
2710         const VkBindImageMemoryInfo bimi = {
2711             .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
2712             .pNext = nullptr,
2713             .image = image,
2714             .memory = memory,
2715             .memoryOffset = memoryOffset,
2716         };
2717         return performBindImageMemory(pool, snapshotInfo, boxed_device, &bimi);
2718     }
2719 
on_vkBindImageMemory2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,uint32_t bindInfoCount,const VkBindImageMemoryInfo * pBindInfos)2720     VkResult on_vkBindImageMemory2(android::base::BumpPool* pool,
2721                                    VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
2722                                    uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos)
2723         EXCLUDES(mMutex) {
2724 #ifdef CONFIG_AEMU
2725         if (bindInfoCount > 1 && snapshotsEnabled()) {
2726             if (mVerbosePrints) {
2727                 fprintf(stderr,
2728                     "vkBindImageMemory2 with more than 1 bindInfoCount not supporting snapshot");
2729             }
2730             get_emugl_vm_operations().setSkipSnapshotSave(true);
2731             get_emugl_vm_operations().setSkipSnapshotSaveReason(SNAPSHOT_SKIP_UNSUPPORTED_VK_API);
2732         }
2733 #endif
2734 
2735         auto device = unbox_VkDevice(boxed_device);
2736         auto vk = dispatch_VkDevice(boxed_device);
2737 
2738         bool needEmulation = false;
2739 
2740         {
2741             std::lock_guard<std::mutex> lock(mMutex);
2742 
2743             auto* deviceInfo = android::base::find(mDeviceInfo, device);
2744             if (!deviceInfo) return VK_ERROR_UNKNOWN;
2745 
2746             for (uint32_t i = 0; i < bindInfoCount; i++) {
2747                 auto* imageInfo = android::base::find(mImageInfo, pBindInfos[i].image);
2748                 if (!imageInfo) return VK_ERROR_UNKNOWN;
2749 
2750                 const auto* anb = vk_find_struct<VkNativeBufferANDROID>(&pBindInfos[i]);
2751                 if (anb != nullptr) {
2752                     needEmulation = true;
2753                     break;
2754                 }
2755 
2756                 if (deviceInfo->needEmulatedDecompression(imageInfo->cmpInfo)) {
2757                     needEmulation = true;
2758                     break;
2759                 }
2760             }
2761         }
2762 
2763         if (needEmulation) {
2764             VkResult result;
2765             for (uint32_t i = 0; i < bindInfoCount; i++) {
2766                 result = performBindImageMemory(pool, snapshotInfo, boxed_device, &pBindInfos[i]);
2767                 if (result != VK_SUCCESS) return result;
2768             }
2769 
2770             return VK_SUCCESS;
2771         }
2772 
2773         VkResult result = vk->vkBindImageMemory2(device, bindInfoCount, pBindInfos);
2774         if (result != VK_SUCCESS) {
2775             return result;
2776         }
2777 
2778         {
2779             std::lock_guard<std::mutex> lock(mMutex);
2780 
2781             auto* deviceInfo = android::base::find(mDeviceInfo, device);
2782             if (!deviceInfo) return VK_ERROR_UNKNOWN;
2783 
2784             for (uint32_t i = 0; i < bindInfoCount; i++) {
2785                 auto* memoryInfo = android::base::find(mMemoryInfo, pBindInfos[i].memory);
2786                 if (!memoryInfo) return VK_ERROR_OUT_OF_HOST_MEMORY;
2787 
2788                 auto* imageInfo = android::base::find(mImageInfo, pBindInfos[i].image);
2789                 if (!imageInfo) return VK_ERROR_OUT_OF_HOST_MEMORY;
2790 
2791                 imageInfo->boundColorBuffer = memoryInfo->boundColorBuffer;
2792                 if (memoryInfo->boundColorBuffer && deviceInfo->debugUtilsHelper.isEnabled()) {
2793                     deviceInfo->debugUtilsHelper.addDebugLabel(
2794                         pBindInfos[i].image, "ColorBuffer:%d", *memoryInfo->boundColorBuffer);
2795                 }
2796                 imageInfo->memory = pBindInfos[i].memory;
2797             }
2798         }
2799 
2800         return result;
2801     }
2802 
on_vkCreateImageView(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkImageViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImageView * pView)2803     VkResult on_vkCreateImageView(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2804                                   VkDevice boxed_device, const VkImageViewCreateInfo* pCreateInfo,
2805                                   const VkAllocationCallbacks* pAllocator, VkImageView* pView) {
2806         auto device = unbox_VkDevice(boxed_device);
2807         auto vk = dispatch_VkDevice(boxed_device);
2808         if (!pCreateInfo) {
2809             return VK_ERROR_OUT_OF_HOST_MEMORY;
2810         }
2811 
2812         std::lock_guard<std::mutex> lock(mMutex);
2813         auto* deviceInfo = android::base::find(mDeviceInfo, device);
2814         auto* imageInfo = android::base::find(mImageInfo, pCreateInfo->image);
2815         if (!deviceInfo || !imageInfo) return VK_ERROR_OUT_OF_HOST_MEMORY;
2816         VkImageViewCreateInfo createInfo;
2817         bool needEmulatedAlpha = false;
2818         if (deviceInfo->needEmulatedDecompression(pCreateInfo->format)) {
2819             if (imageInfo->cmpInfo.outputImage()) {
2820                 createInfo = *pCreateInfo;
2821                 createInfo.format = CompressedImageInfo::getOutputFormat(pCreateInfo->format);
2822                 needEmulatedAlpha = CompressedImageInfo::needEmulatedAlpha(pCreateInfo->format);
2823                 createInfo.image = imageInfo->cmpInfo.outputImage();
2824                 pCreateInfo = &createInfo;
2825             }
2826         } else if (deviceInfo->needEmulatedDecompression(imageInfo->cmpInfo)) {
2827             // Image view on the compressed mipmaps
2828             createInfo = *pCreateInfo;
2829             createInfo.format =
2830                 CompressedImageInfo::getCompressedMipmapsFormat(pCreateInfo->format);
2831             needEmulatedAlpha = false;
2832             createInfo.image =
2833                 imageInfo->cmpInfo.compressedMipmap(pCreateInfo->subresourceRange.baseMipLevel);
2834             createInfo.subresourceRange.baseMipLevel = 0;
2835             pCreateInfo = &createInfo;
2836         }
2837         if (imageInfo->anbInfo && imageInfo->anbInfo->isExternallyBacked()) {
2838             createInfo = *pCreateInfo;
2839             pCreateInfo = &createInfo;
2840         }
2841 
2842         VkResult result = vk->vkCreateImageView(device, pCreateInfo, pAllocator, pView);
2843         if (result != VK_SUCCESS) {
2844             return result;
2845         }
2846 
2847         VALIDATE_NEW_HANDLE_INFO_ENTRY(mImageViewInfo, *pView);
2848         auto& imageViewInfo = mImageViewInfo[*pView];
2849         imageViewInfo.device = device;
2850         imageViewInfo.needEmulatedAlpha = needEmulatedAlpha;
2851         imageViewInfo.boundColorBuffer = imageInfo->boundColorBuffer;
2852         if (imageViewInfo.boundColorBuffer) {
2853             deviceInfo->debugUtilsHelper.addDebugLabel(*pView, "ColorBuffer:%d",
2854                                                        *imageViewInfo.boundColorBuffer);
2855         }
2856 
2857         *pView = new_boxed_non_dispatchable_VkImageView(*pView);
2858         return result;
2859     }
2860 
destroyImageViewWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkImageView imageView,ImageViewInfo & imageViewInfo,const VkAllocationCallbacks * pAllocator)2861     void destroyImageViewWithExclusiveInfo(VkDevice device, VulkanDispatch* deviceDispatch,
2862                                            VkImageView imageView, ImageViewInfo& imageViewInfo,
2863                                            const VkAllocationCallbacks* pAllocator) {
2864         deviceDispatch->vkDestroyImageView(device, imageView, pAllocator);
2865     }
2866 
destroyImageViewLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkImageView imageView,const VkAllocationCallbacks * pAllocator)2867     void destroyImageViewLocked(VkDevice device, VulkanDispatch* deviceDispatch,
2868                                 VkImageView imageView, const VkAllocationCallbacks* pAllocator)
2869         REQUIRES(mMutex) {
2870         auto imageViewInfoIt = mImageViewInfo.find(imageView);
2871         if (imageViewInfoIt == mImageViewInfo.end()) return;
2872         auto& imageViewInfo = imageViewInfoIt->second;
2873 
2874         destroyImageViewWithExclusiveInfo(device, deviceDispatch, imageView, imageViewInfo,
2875                                           pAllocator);
2876 
2877         mImageViewInfo.erase(imageView);
2878     }
2879 
on_vkDestroyImageView(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkImageView imageView,const VkAllocationCallbacks * pAllocator)2880     void on_vkDestroyImageView(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2881                                VkDevice boxed_device, VkImageView imageView,
2882                                const VkAllocationCallbacks* pAllocator) {
2883         auto device = unbox_VkDevice(boxed_device);
2884         auto deviceDispatch = dispatch_VkDevice(boxed_device);
2885 
2886         std::lock_guard<std::mutex> lock(mMutex);
2887         destroyImageViewLocked(device, deviceDispatch, imageView, pAllocator);
2888     }
2889 
on_vkCreateSampler(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkSamplerCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)2890     VkResult on_vkCreateSampler(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2891                                 VkDevice boxed_device, const VkSamplerCreateInfo* pCreateInfo,
2892                                 const VkAllocationCallbacks* pAllocator, VkSampler* pSampler) {
2893         auto device = unbox_VkDevice(boxed_device);
2894         auto vk = dispatch_VkDevice(boxed_device);
2895         VkResult result = vk->vkCreateSampler(device, pCreateInfo, pAllocator, pSampler);
2896         if (result != VK_SUCCESS) {
2897             return result;
2898         }
2899         std::lock_guard<std::mutex> lock(mMutex);
2900         VALIDATE_NEW_HANDLE_INFO_ENTRY(mSamplerInfo, *pSampler);
2901         auto& samplerInfo = mSamplerInfo[*pSampler];
2902         samplerInfo.device = device;
2903         deepcopy_VkSamplerCreateInfo(pool, VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
2904                                      pCreateInfo, &samplerInfo.createInfo);
2905         // We emulate RGB with RGBA for some compressed textures, which does not
2906         // handle translarent border correctly.
2907         samplerInfo.needEmulatedAlpha =
2908             (pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER ||
2909              pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER ||
2910              pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) &&
2911             (pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK ||
2912              pCreateInfo->borderColor == VK_BORDER_COLOR_INT_TRANSPARENT_BLACK ||
2913              pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT ||
2914              pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT);
2915 
2916         *pSampler = new_boxed_non_dispatchable_VkSampler(*pSampler);
2917 
2918         return result;
2919     }
2920 
destroySamplerWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkSampler sampler,SamplerInfo & samplerInfo,const VkAllocationCallbacks * pAllocator)2921     void destroySamplerWithExclusiveInfo(VkDevice device, VulkanDispatch* deviceDispatch,
2922                                          VkSampler sampler, SamplerInfo& samplerInfo,
2923                                          const VkAllocationCallbacks* pAllocator) {
2924         deviceDispatch->vkDestroySampler(device, sampler, pAllocator);
2925 
2926         if (samplerInfo.emulatedborderSampler != VK_NULL_HANDLE) {
2927             deviceDispatch->vkDestroySampler(device, samplerInfo.emulatedborderSampler, nullptr);
2928         }
2929     }
2930 
destroySamplerLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkSampler sampler,const VkAllocationCallbacks * pAllocator)2931     void destroySamplerLocked(VkDevice device, VulkanDispatch* deviceDispatch, VkSampler sampler,
2932                               const VkAllocationCallbacks* pAllocator) REQUIRES(mMutex) {
2933         auto samplerInfoIt = mSamplerInfo.find(sampler);
2934         if (samplerInfoIt == mSamplerInfo.end()) return;
2935         auto& samplerInfo = samplerInfoIt->second;
2936 
2937         destroySamplerWithExclusiveInfo(device, deviceDispatch, sampler, samplerInfo, pAllocator);
2938 
2939         mSamplerInfo.erase(samplerInfoIt);
2940     }
2941 
on_vkDestroySampler(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkSampler sampler,const VkAllocationCallbacks * pAllocator)2942     void on_vkDestroySampler(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2943                              VkDevice boxed_device, VkSampler sampler,
2944                              const VkAllocationCallbacks* pAllocator) {
2945         auto device = unbox_VkDevice(boxed_device);
2946         auto deviceDispatch = dispatch_VkDevice(boxed_device);
2947 
2948         std::lock_guard<std::mutex> lock(mMutex);
2949         destroySamplerLocked(device, deviceDispatch, sampler, pAllocator);
2950     }
2951 
exportSemaphore(VulkanDispatch * vk,VkDevice device,VkSemaphore semaphore,VK_EXT_SYNC_HANDLE * outHandle,std::optional<VkExternalSemaphoreHandleTypeFlagBits> handleType=std::nullopt)2952     VkResult exportSemaphore(
2953         VulkanDispatch* vk, VkDevice device, VkSemaphore semaphore, VK_EXT_SYNC_HANDLE* outHandle,
2954         std::optional<VkExternalSemaphoreHandleTypeFlagBits> handleType = std::nullopt)
2955         EXCLUDES(mMutex) {
2956 #if defined(_WIN32)
2957         VkSemaphoreGetWin32HandleInfoKHR getWin32 = {
2958             VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
2959             0,
2960             semaphore,
2961             VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT,
2962         };
2963 
2964         return vk->vkGetSemaphoreWin32HandleKHR(device, &getWin32, outHandle);
2965 #elif defined(__linux__)
2966         VkExternalSemaphoreHandleTypeFlagBits handleTypeBits =
2967             VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
2968         if (handleType) {
2969             handleTypeBits = *handleType;
2970         }
2971 
2972         VkSemaphoreGetFdInfoKHR getFd = {
2973             VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
2974             0,
2975             semaphore,
2976             handleTypeBits,
2977         };
2978 
2979         {
2980             std::lock_guard<std::mutex> lock(mMutex);
2981             if (!hasDeviceExtension(device, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME)) {
2982                 // Note: VK_KHR_external_semaphore_fd might be advertised in the guest,
2983                 // because SYNC_FD handling is performed guest-side only. But still need
2984                 // need to error out here when handling a non-sync, opaque FD.
2985                 return VK_ERROR_OUT_OF_HOST_MEMORY;
2986             }
2987         }
2988 
2989         return vk->vkGetSemaphoreFdKHR(device, &getFd, outHandle);
2990 #else
2991         return VK_ERROR_OUT_OF_HOST_MEMORY;
2992 #endif
2993     }
2994 
on_vkCreateSemaphore(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkSemaphoreCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSemaphore * pSemaphore)2995     VkResult on_vkCreateSemaphore(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
2996                                   VkDevice boxed_device, const VkSemaphoreCreateInfo* pCreateInfo,
2997                                   const VkAllocationCallbacks* pAllocator,
2998                                   VkSemaphore* pSemaphore) {
2999         auto device = unbox_VkDevice(boxed_device);
3000         auto vk = dispatch_VkDevice(boxed_device);
3001 
3002         VkSemaphoreCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);
3003         vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&localCreateInfo);
3004 
3005         bool timelineSemaphore = false;
3006 
3007         VkSemaphoreTypeCreateInfoKHR localSemaphoreTypeCreateInfo;
3008         if (const VkSemaphoreTypeCreateInfoKHR* semaphoreTypeCiPtr =
3009                 vk_find_struct<VkSemaphoreTypeCreateInfoKHR>(pCreateInfo);
3010             semaphoreTypeCiPtr) {
3011             localSemaphoreTypeCreateInfo = vk_make_orphan_copy(*semaphoreTypeCiPtr);
3012             vk_append_struct(&structChainIter, &localSemaphoreTypeCreateInfo);
3013 
3014             if (localSemaphoreTypeCreateInfo.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE) {
3015                 timelineSemaphore = true;
3016             }
3017         }
3018 
3019         VkExportSemaphoreCreateInfoKHR localExportSemaphoreCi = {};
3020 
3021         /* Timeline semaphores are exportable:
3022          *
3023          * "Timeline semaphore specific external sharing capabilities can be queried using
3024          *  vkGetPhysicalDeviceExternalSemaphoreProperties by chaining the new
3025          *  VkSemaphoreTypeCreateInfoKHR structure to its pExternalSemaphoreInfo structure.
3026          *  This allows having a different set of external semaphore handle types supported
3027          *  for timeline semaphores vs. binary semaphores."
3028          *
3029          *  We just don't support this here since neither Android or Zink use this feature
3030          *  with timeline semaphores yet.
3031          */
3032         if (m_vkEmulation->getFeatures().VulkanExternalSync.enabled && !timelineSemaphore) {
3033             localExportSemaphoreCi.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO;
3034             localExportSemaphoreCi.pNext = nullptr;
3035 
3036             {
3037                 std::lock_guard<std::mutex> lock(mMutex);
3038                 auto* deviceInfo = android::base::find(mDeviceInfo, device);
3039 
3040                 if (!deviceInfo) {
3041                     return VK_ERROR_DEVICE_LOST;
3042                 }
3043 
3044                 if (deviceInfo->externalFenceInfo.supportedBinarySemaphoreHandleTypes &
3045                     VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT) {
3046                     localExportSemaphoreCi.handleTypes =
3047                         VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT;
3048                 } else if (deviceInfo->externalFenceInfo.supportedBinarySemaphoreHandleTypes &
3049                            VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
3050                     localExportSemaphoreCi.handleTypes =
3051                         VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
3052                 } else if (deviceInfo->externalFenceInfo.supportedBinarySemaphoreHandleTypes &
3053                            VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT) {
3054                     localExportSemaphoreCi.handleTypes =
3055                         VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
3056                 }
3057             }
3058 
3059             vk_append_struct(&structChainIter, &localExportSemaphoreCi);
3060         }
3061 
3062         VkResult res = vk->vkCreateSemaphore(device, &localCreateInfo, pAllocator, pSemaphore);
3063 
3064         if (res != VK_SUCCESS) return res;
3065 
3066         std::lock_guard<std::mutex> lock(mMutex);
3067 
3068         VALIDATE_NEW_HANDLE_INFO_ENTRY(mSemaphoreInfo, *pSemaphore);
3069         auto& semaphoreInfo = mSemaphoreInfo[*pSemaphore];
3070         semaphoreInfo.device = device;
3071 
3072         *pSemaphore = new_boxed_non_dispatchable_VkSemaphore(*pSemaphore);
3073 
3074         return res;
3075     }
3076 
on_vkCreateFence(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkFenceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkFence * pFence)3077     VkResult on_vkCreateFence(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3078                               VkDevice boxed_device, const VkFenceCreateInfo* pCreateInfo,
3079                               const VkAllocationCallbacks* pAllocator, VkFence* pFence) {
3080         auto device = unbox_VkDevice(boxed_device);
3081         auto vk = dispatch_VkDevice(boxed_device);
3082 
3083         VkFenceCreateInfo localCreateInfo = *pCreateInfo;
3084         if (mSnapshotState == SnapshotState::Loading) {
3085             // On snapshot load we create all fences as signaled then reset those that are not.
3086             localCreateInfo.flags |= VK_FENCE_CREATE_SIGNALED_BIT;
3087         }
3088 
3089         const VkExportFenceCreateInfo* exportFenceInfoPtr =
3090             vk_find_struct<VkExportFenceCreateInfo>(&localCreateInfo);
3091         bool exportSyncFd = exportFenceInfoPtr && (exportFenceInfoPtr->handleTypes &
3092                                                    VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT);
3093         bool fenceReused = false;
3094 
3095         *pFence = VK_NULL_HANDLE;
3096 
3097         if (exportSyncFd) {
3098             // Remove VkExportFenceCreateInfo, since host doesn't need to create
3099             // an exportable fence in this case
3100             ExternalFencePool<VulkanDispatch>* externalFencePool = nullptr;
3101             vk_struct_chain_remove(exportFenceInfoPtr, &localCreateInfo);
3102             {
3103                 std::lock_guard<std::mutex> lock(mMutex);
3104                 auto* deviceInfo = android::base::find(mDeviceInfo, device);
3105                 if (!deviceInfo) return VK_ERROR_OUT_OF_HOST_MEMORY;
3106                 externalFencePool = deviceInfo->externalFencePool.get();
3107             }
3108             *pFence = externalFencePool->pop(&localCreateInfo);
3109             if (*pFence != VK_NULL_HANDLE) {
3110                 fenceReused = true;
3111             }
3112         }
3113 
3114         if (*pFence == VK_NULL_HANDLE) {
3115             VkResult res = vk->vkCreateFence(device, &localCreateInfo, pAllocator, pFence);
3116             if (res != VK_SUCCESS) {
3117                 return res;
3118             }
3119         }
3120 
3121         {
3122             std::lock_guard<std::mutex> lock(mMutex);
3123 
3124             // Create FenceInfo for *pFence.
3125             if (!fenceReused) {
3126                 VALIDATE_NEW_HANDLE_INFO_ENTRY(mFenceInfo, *pFence);
3127             }
3128             auto& fenceInfo = mFenceInfo[*pFence];
3129             fenceInfo.device = device;
3130             fenceInfo.vk = vk;
3131 
3132             *pFence = new_boxed_non_dispatchable_VkFence(*pFence);
3133             fenceInfo.boxed = *pFence;
3134             fenceInfo.external = exportSyncFd;
3135 
3136             if (localCreateInfo.flags & VK_FENCE_CREATE_SIGNALED_BIT) {
3137                 fenceInfo.state = FenceInfo::State::kWaitable;
3138             } else {
3139                 fenceInfo.state = FenceInfo::State::kNotWaitable;
3140             }
3141         }
3142 
3143         return VK_SUCCESS;
3144     }
3145 
on_vkGetFenceStatus(android::base::BumpPool *,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkFence fence)3146     VkResult on_vkGetFenceStatus(android::base::BumpPool*, VkSnapshotApiCallInfo*,
3147                                  VkDevice boxed_device, VkFence fence) {
3148         auto device = unbox_VkDevice(boxed_device);
3149         auto vk = dispatch_VkDevice(boxed_device);
3150         {
3151             std::lock_guard<std::mutex> lock(mMutex);
3152             auto* fenceInfo = android::base::find(mFenceInfo, fence);
3153             if (!fenceInfo) {
3154                 ERR("%s: Invalid fence %p", fence);
3155                 return VK_SUCCESS;
3156             }
3157         }
3158 
3159         return vk->vkGetFenceStatus(device, fence);
3160     }
3161 
on_vkWaitForFences(android::base::BumpPool *,VkSnapshotApiCallInfo *,VkDevice boxed_device,uint32_t fenceCount,const VkFence * pFences,VkBool32 waitAll,uint64_t timeout)3162     VkResult on_vkWaitForFences(android::base::BumpPool*, VkSnapshotApiCallInfo*,
3163                                 VkDevice boxed_device, uint32_t fenceCount, const VkFence* pFences,
3164                                 VkBool32 waitAll, uint64_t timeout) {
3165         auto device = unbox_VkDevice(boxed_device);
3166         auto vk = dispatch_VkDevice(boxed_device);
3167 
3168         // TODO(b/397501277): wait state checks cause test failures on old API levels
3169         return waitForFences(device, vk, fenceCount, pFences, waitAll, timeout, false);
3170     }
3171 
on_vkResetFences(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,uint32_t fenceCount,const VkFence * pFences)3172     VkResult on_vkResetFences(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3173                               VkDevice boxed_device, uint32_t fenceCount, const VkFence* pFences) {
3174         auto device = unbox_VkDevice(boxed_device);
3175         auto vk = dispatch_VkDevice(boxed_device);
3176 
3177         std::vector<VkFence> cleanedFences;
3178         std::vector<VkFence> externalFences;
3179 
3180         {
3181             std::lock_guard<std::mutex> lock(mMutex);
3182             for (uint32_t i = 0; i < fenceCount; i++) {
3183                 if (pFences[i] == VK_NULL_HANDLE) continue;
3184 
3185                 if (mFenceInfo.find(pFences[i]) == mFenceInfo.end()) {
3186                     ERR("Invalid fence handle: %p!", pFences[i]);
3187                 } else {
3188                     if (mFenceInfo[pFences[i]].external) {
3189                         externalFences.push_back(pFences[i]);
3190                     } else {
3191                         // Reset all fences' states to kNotWaitable.
3192                         cleanedFences.push_back(pFences[i]);
3193                         mFenceInfo[pFences[i]].state = FenceInfo::State::kNotWaitable;
3194                     }
3195                 }
3196             }
3197         }
3198 
3199         if (!cleanedFences.empty()) {
3200             VK_CHECK(vk->vkResetFences(device, (uint32_t)cleanedFences.size(),
3201                                        cleanedFences.data()));
3202         }
3203 
3204         // For external fences, we unilaterally put them in the pool to ensure they finish
3205         // TODO: should store creation info / pNext chain per fence and re-apply?
3206         VkFenceCreateInfo createInfo{
3207             .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
3208             .pNext = 0,
3209             .flags = 0,
3210         };
3211 
3212         std::lock_guard<std::mutex> lock(mMutex);
3213 
3214         auto* deviceInfo = android::base::find(mDeviceInfo, device);
3215         if (!deviceInfo) return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3216         for (auto fence : externalFences) {
3217             VkFence replacement = deviceInfo->externalFencePool->pop(&createInfo);
3218             if (replacement == VK_NULL_HANDLE) {
3219                 VK_CHECK(vk->vkCreateFence(device, &createInfo, 0, &replacement));
3220             }
3221             deviceInfo->externalFencePool->add(fence);
3222 
3223             {
3224                 auto boxed_fence = unboxed_to_boxed_non_dispatchable_VkFence(fence);
3225                 set_boxed_non_dispatchable_VkFence(boxed_fence, replacement);
3226 
3227                 auto& fenceInfo = mFenceInfo[replacement];
3228                 fenceInfo.device = device;
3229                 fenceInfo.vk = vk;
3230                 fenceInfo.boxed = boxed_fence;
3231                 fenceInfo.external = true;
3232                 fenceInfo.state = FenceInfo::State::kNotWaitable;
3233 
3234                 mFenceInfo[fence].boxed = VK_NULL_HANDLE;
3235             }
3236         }
3237 
3238         return VK_SUCCESS;
3239     }
3240 
on_vkImportSemaphoreFdKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkImportSemaphoreFdInfoKHR * pImportSemaphoreFdInfo)3241     VkResult on_vkImportSemaphoreFdKHR(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3242                                        VkDevice boxed_device,
3243                                        const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo) {
3244         auto device = unbox_VkDevice(boxed_device);
3245         auto vk = dispatch_VkDevice(boxed_device);
3246 
3247 #ifdef _WIN32
3248         VK_EXT_SYNC_HANDLE handle = VK_EXT_SYNC_HANDLE_INVALID;
3249         {
3250             std::lock_guard<std::mutex> lock(mMutex);
3251 
3252             auto* infoPtr = android::base::find(
3253                 mSemaphoreInfo, mExternalSemaphoresById[pImportSemaphoreFdInfo->fd]);
3254             if (!infoPtr) {
3255                 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
3256             }
3257 
3258             handle = dupExternalSync(infoPtr->externalHandle);
3259         }
3260 
3261         VkImportSemaphoreWin32HandleInfoKHR win32ImportInfo = {
3262             VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
3263             0,
3264             pImportSemaphoreFdInfo->semaphore,
3265             pImportSemaphoreFdInfo->flags,
3266             VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR,
3267             handle,
3268             L"",
3269         };
3270 
3271         return vk->vkImportSemaphoreWin32HandleKHR(device, &win32ImportInfo);
3272 #else
3273         {
3274             std::lock_guard<std::mutex> lock(mMutex);
3275 
3276             if (!hasDeviceExtension(device, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME)) {
3277                 // Note: VK_KHR_external_semaphore_fd might be advertised in the guest,
3278                 // because SYNC_FD handling is performed guest-side only. But still need
3279                 // need to error out here when handling a non-sync, opaque FD.
3280                 return VK_ERROR_OUT_OF_HOST_MEMORY;
3281             }
3282         }
3283 
3284         VkImportSemaphoreFdInfoKHR importInfo = *pImportSemaphoreFdInfo;
3285         importInfo.fd = dup(pImportSemaphoreFdInfo->fd);
3286         return vk->vkImportSemaphoreFdKHR(device, &importInfo);
3287 #endif
3288     }
3289 
on_vkGetSemaphoreFdKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkSemaphoreGetFdInfoKHR * pGetFdInfo,int * pFd)3290     VkResult on_vkGetSemaphoreFdKHR(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3291                                     VkDevice boxed_device,
3292                                     const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd) {
3293         auto device = unbox_VkDevice(boxed_device);
3294         auto vk = dispatch_VkDevice(boxed_device);
3295         VK_EXT_SYNC_HANDLE handle;
3296 
3297         VkResult result = exportSemaphore(vk, device, pGetFdInfo->semaphore, &handle);
3298         if (result != VK_SUCCESS) {
3299             return result;
3300         }
3301 
3302         std::lock_guard<std::mutex> lock(mMutex);
3303         mSemaphoreInfo[pGetFdInfo->semaphore].externalHandle = handle;
3304 #ifdef _WIN32
3305         int nextId = genSemaphoreId();
3306         mExternalSemaphoresById[nextId] = pGetFdInfo->semaphore;
3307         *pFd = nextId;
3308 #else
3309         // No next id; its already an fd
3310         mSemaphoreInfo[pGetFdInfo->semaphore].externalHandle = handle;
3311 #endif
3312         return result;
3313     }
3314 
on_vkGetSemaphoreGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkSemaphore semaphore,uint64_t syncId)3315     VkResult on_vkGetSemaphoreGOOGLE(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3316                                      VkDevice boxed_device, VkSemaphore semaphore,
3317                                      uint64_t syncId) {
3318         if (!m_vkEmulation->getFeatures().VulkanExternalSync.enabled) {
3319             return VK_ERROR_FEATURE_NOT_PRESENT;
3320         }
3321 
3322         auto vk = dispatch_VkDevice(boxed_device);
3323         auto device = unbox_VkDevice(boxed_device);
3324 
3325         uint32_t virtioGpuContextId = 0;
3326         VkExternalSemaphoreHandleTypeFlagBits flagBits =
3327             static_cast<VkExternalSemaphoreHandleTypeFlagBits>(0);
3328         {
3329             std::lock_guard<std::mutex> lock(mMutex);
3330             auto* deviceInfo = android::base::find(mDeviceInfo, device);
3331 
3332             if (!deviceInfo) {
3333                 return VK_ERROR_DEVICE_LOST;
3334             }
3335 
3336             if (deviceInfo->externalFenceInfo.supportedBinarySemaphoreHandleTypes &
3337                 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT) {
3338                 flagBits = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT;
3339             } else if (deviceInfo->externalFenceInfo.supportedBinarySemaphoreHandleTypes &
3340                        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
3341                 flagBits = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
3342             } else if (deviceInfo->externalFenceInfo.supportedBinarySemaphoreHandleTypes &
3343                        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT) {
3344                 flagBits = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
3345             }
3346 
3347             if (!deviceInfo->virtioGpuContextId) {
3348                 ERR("VkDevice:%p is missing virtio gpu context id.", device);
3349                 return VK_ERROR_OUT_OF_HOST_MEMORY;
3350             }
3351             virtioGpuContextId = *deviceInfo->virtioGpuContextId;
3352         }
3353 
3354         VK_EXT_SYNC_HANDLE handle;
3355         VkResult result =
3356             exportSemaphore(vk, device, semaphore, &handle,
3357                             std::make_optional<VkExternalSemaphoreHandleTypeFlagBits>(flagBits));
3358         if (result != VK_SUCCESS) {
3359             return result;
3360         }
3361 
3362         ManagedDescriptor descriptor(handle);
3363         ExternalObjectManager::get()->addSyncDescriptorInfo(
3364             virtioGpuContextId, syncId, std::move(descriptor), /*streamHandleType*/ 0);
3365         return VK_SUCCESS;
3366     }
3367 
destroySemaphoreWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkSemaphore semaphore,DeviceInfo & deviceInfo,SemaphoreInfo & semaphoreInfo,const VkAllocationCallbacks * pAllocator)3368     void destroySemaphoreWithExclusiveInfo(VkDevice device, VulkanDispatch* deviceDispatch,
3369                                            VkSemaphore semaphore, DeviceInfo& deviceInfo,
3370                                            SemaphoreInfo& semaphoreInfo,
3371                                            const VkAllocationCallbacks* pAllocator) {
3372 #ifndef _WIN32
3373         if (semaphoreInfo.externalHandle != VK_EXT_SYNC_HANDLE_INVALID) {
3374             close(semaphoreInfo.externalHandle);
3375         }
3376 #endif
3377 
3378         if (semaphoreInfo.latestUse && !IsDone(*semaphoreInfo.latestUse)) {
3379             deviceInfo.deviceOpTracker->AddPendingGarbage(*semaphoreInfo.latestUse, semaphore);
3380             deviceInfo.deviceOpTracker->PollAndProcessGarbage();
3381         } else {
3382             deviceDispatch->vkDestroySemaphore(device, semaphore, pAllocator);
3383         }
3384     }
3385 
destroySemaphoreLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkSemaphore semaphore,const VkAllocationCallbacks * pAllocator)3386     void destroySemaphoreLocked(VkDevice device, VulkanDispatch* deviceDispatch,
3387                                 VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator)
3388         REQUIRES(mMutex) {
3389         auto deviceInfoIt = mDeviceInfo.find(device);
3390         if (deviceInfoIt == mDeviceInfo.end()) return;
3391         auto& deviceInfo = deviceInfoIt->second;
3392 
3393         auto semaphoreInfoIt = mSemaphoreInfo.find(semaphore);
3394         if (semaphoreInfoIt == mSemaphoreInfo.end()) return;
3395         auto& semaphoreInfo = semaphoreInfoIt->second;
3396 
3397         destroySemaphoreWithExclusiveInfo(device, deviceDispatch, semaphore, deviceInfo,
3398                                           semaphoreInfo, pAllocator);
3399 
3400         mSemaphoreInfo.erase(semaphoreInfoIt);
3401     }
3402 
on_vkDestroySemaphore(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkSemaphore semaphore,const VkAllocationCallbacks * pAllocator)3403     void on_vkDestroySemaphore(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3404                                VkDevice boxed_device, VkSemaphore semaphore,
3405                                const VkAllocationCallbacks* pAllocator) {
3406         auto device = unbox_VkDevice(boxed_device);
3407         auto deviceDispatch = dispatch_VkDevice(boxed_device);
3408 
3409         std::lock_guard<std::mutex> lock(mMutex);
3410         destroySemaphoreLocked(device, deviceDispatch, semaphore, pAllocator);
3411     }
3412 
on_vkWaitSemaphores(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkSemaphoreWaitInfo * pWaitInfo,uint64_t timeout)3413     VkResult on_vkWaitSemaphores(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3414                              VkDevice boxed_device, const VkSemaphoreWaitInfo* pWaitInfo,
3415                              uint64_t timeout) {
3416         auto device = unbox_VkDevice(boxed_device);
3417         auto deviceDispatch = dispatch_VkDevice(boxed_device);
3418 
3419         return deviceDispatch->vkWaitSemaphores(device, pWaitInfo, timeout);
3420     }
3421 
on_vkSignalSemaphore(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkSemaphoreSignalInfo * pSignalInfo)3422     VkResult on_vkSignalSemaphore(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3423                                   VkDevice boxed_device, const VkSemaphoreSignalInfo* pSignalInfo) {
3424         auto device = unbox_VkDevice(boxed_device);
3425         auto deviceDispatch = dispatch_VkDevice(boxed_device);
3426 
3427         return deviceDispatch->vkSignalSemaphore(device, pSignalInfo);
3428     }
3429 
3430     enum class DestroyFenceStatus { kDestroyed, kRecycled };
3431 
destroyFenceWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,DeviceInfo & deviceInfo,VkFence fence,FenceInfo & fenceInfo,const VkAllocationCallbacks * pAllocator,bool allowExternalFenceRecycling)3432     DestroyFenceStatus destroyFenceWithExclusiveInfo(VkDevice device,
3433                                                      VulkanDispatch* deviceDispatch,
3434                                                      DeviceInfo& deviceInfo, VkFence fence,
3435                                                      FenceInfo& fenceInfo,
3436                                                      const VkAllocationCallbacks* pAllocator,
3437                                                      bool allowExternalFenceRecycling) {
3438         fenceInfo.boxed = VK_NULL_HANDLE;
3439 
3440         // External fences are just slated for recycling. This addresses known
3441         // behavior where the guest might destroy the fence prematurely. b/228221208
3442         if (fenceInfo.external) {
3443             if (allowExternalFenceRecycling) {
3444                 deviceInfo.externalFencePool->add(fence);
3445             }
3446             return DestroyFenceStatus::kRecycled;
3447         }
3448 
3449         if (fenceInfo.latestUse && !IsDone(*fenceInfo.latestUse)) {
3450             deviceInfo.deviceOpTracker->AddPendingGarbage(*fenceInfo.latestUse, fence);
3451             deviceInfo.deviceOpTracker->PollAndProcessGarbage();
3452         } else {
3453             deviceDispatch->vkDestroyFence(device, fence, pAllocator);
3454         }
3455 
3456         return DestroyFenceStatus::kDestroyed;
3457     }
3458 
destroyFenceLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkFence fence,const VkAllocationCallbacks * pAllocator,bool allowExternalFenceRecycling)3459     void destroyFenceLocked(VkDevice device, VulkanDispatch* deviceDispatch, VkFence fence,
3460                             const VkAllocationCallbacks* pAllocator,
3461                             bool allowExternalFenceRecycling) REQUIRES(mMutex) {
3462         auto fenceInfoIt = mFenceInfo.find(fence);
3463         if (fenceInfoIt == mFenceInfo.end()) {
3464             ERR("Failed to find fence info for VkFence:%p. Leaking fence!", fence);
3465             return;
3466         }
3467         auto& fenceInfo = fenceInfoIt->second;
3468 
3469         auto deviceInfoIt = mDeviceInfo.find(device);
3470         if (deviceInfoIt == mDeviceInfo.end()) {
3471             ERR("Failed to find device info for VkDevice:%p for VkFence:%p. Leaking fence!", device,
3472                 fence);
3473             return;
3474         }
3475         auto& deviceInfo = deviceInfoIt->second;
3476 
3477         auto destroyStatus =
3478             destroyFenceWithExclusiveInfo(device, deviceDispatch, deviceInfo, fence, fenceInfo,
3479                                           pAllocator, /*allowExternalFenceRecycling=*/true);
3480         if (destroyStatus == DestroyFenceStatus::kDestroyed) {
3481             mFenceInfo.erase(fenceInfoIt);
3482         }
3483     }
3484 
on_vkDestroyFence(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkFence fence,const VkAllocationCallbacks * pAllocator)3485     void on_vkDestroyFence(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3486                            VkDevice boxed_device, VkFence fence,
3487                            const VkAllocationCallbacks* pAllocator) {
3488         if (fence == VK_NULL_HANDLE) return;
3489 
3490         auto device = unbox_VkDevice(boxed_device);
3491         auto deviceDispatch = dispatch_VkDevice(boxed_device);
3492 
3493         std::lock_guard<std::mutex> lock(mMutex);
3494         destroyFenceLocked(device, deviceDispatch, fence, pAllocator, true);
3495     }
3496 
on_vkCreateDescriptorSetLayout(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkDescriptorSetLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorSetLayout * pSetLayout)3497     VkResult on_vkCreateDescriptorSetLayout(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3498                                             VkDevice boxed_device,
3499                                             const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
3500                                             const VkAllocationCallbacks* pAllocator,
3501                                             VkDescriptorSetLayout* pSetLayout) {
3502         auto device = unbox_VkDevice(boxed_device);
3503         auto vk = dispatch_VkDevice(boxed_device);
3504 
3505         auto res = vk->vkCreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout);
3506 
3507         if (res == VK_SUCCESS) {
3508             std::lock_guard<std::mutex> lock(mMutex);
3509             VALIDATE_NEW_HANDLE_INFO_ENTRY(mDescriptorSetLayoutInfo, *pSetLayout);
3510             auto& info = mDescriptorSetLayoutInfo[*pSetLayout];
3511             info.device = device;
3512             *pSetLayout = new_boxed_non_dispatchable_VkDescriptorSetLayout(*pSetLayout);
3513             info.boxed = *pSetLayout;
3514 
3515             info.createInfo = *pCreateInfo;
3516             for (uint32_t i = 0; i < pCreateInfo->bindingCount; ++i) {
3517                 info.bindings.push_back(pCreateInfo->pBindings[i]);
3518             }
3519         }
3520 
3521         return res;
3522     }
3523 
destroyDescriptorSetLayoutWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkDescriptorSetLayout descriptorSetLayout,DescriptorSetLayoutInfo & descriptorSetLayoutInfo,const VkAllocationCallbacks * pAllocator)3524     void destroyDescriptorSetLayoutWithExclusiveInfo(
3525         VkDevice device, VulkanDispatch* deviceDispatch, VkDescriptorSetLayout descriptorSetLayout,
3526         DescriptorSetLayoutInfo& descriptorSetLayoutInfo, const VkAllocationCallbacks* pAllocator) {
3527         deviceDispatch->vkDestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
3528     }
3529 
destroyDescriptorSetLayoutLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkDescriptorSetLayout descriptorSetLayout,const VkAllocationCallbacks * pAllocator)3530     void destroyDescriptorSetLayoutLocked(VkDevice device, VulkanDispatch* deviceDispatch,
3531                                           VkDescriptorSetLayout descriptorSetLayout,
3532                                           const VkAllocationCallbacks* pAllocator)
3533         REQUIRES(mMutex) {
3534         auto descriptorSetLayoutInfoIt = mDescriptorSetLayoutInfo.find(descriptorSetLayout);
3535         if (descriptorSetLayoutInfoIt == mDescriptorSetLayoutInfo.end()) return;
3536         auto& descriptorSetLayoutInfo = descriptorSetLayoutInfoIt->second;
3537 
3538         destroyDescriptorSetLayoutWithExclusiveInfo(device, deviceDispatch, descriptorSetLayout,
3539                                                     descriptorSetLayoutInfo, pAllocator);
3540 
3541         mDescriptorSetLayoutInfo.erase(descriptorSetLayoutInfoIt);
3542     }
3543 
on_vkDestroyDescriptorSetLayout(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkDescriptorSetLayout descriptorSetLayout,const VkAllocationCallbacks * pAllocator)3544     void on_vkDestroyDescriptorSetLayout(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3545                                          VkDevice boxed_device,
3546                                          VkDescriptorSetLayout descriptorSetLayout,
3547                                          const VkAllocationCallbacks* pAllocator) {
3548         auto device = unbox_VkDevice(boxed_device);
3549         auto deviceDispatch = dispatch_VkDevice(boxed_device);
3550 
3551         std::lock_guard<std::mutex> lock(mMutex);
3552         destroyDescriptorSetLayoutLocked(device, deviceDispatch, descriptorSetLayout, pAllocator);
3553     }
3554 
on_vkCreateDescriptorPool(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkDescriptorPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorPool * pDescriptorPool)3555     VkResult on_vkCreateDescriptorPool(android::base::BumpPool* pool,
3556                                        VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
3557                                        const VkDescriptorPoolCreateInfo* pCreateInfo,
3558                                        const VkAllocationCallbacks* pAllocator,
3559                                        VkDescriptorPool* pDescriptorPool) {
3560         auto device = unbox_VkDevice(boxed_device);
3561         auto vk = dispatch_VkDevice(boxed_device);
3562 
3563         auto res = vk->vkCreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool);
3564 
3565         if (res == VK_SUCCESS) {
3566             std::lock_guard<std::mutex> lock(mMutex);
3567             VALIDATE_NEW_HANDLE_INFO_ENTRY(mDescriptorPoolInfo, *pDescriptorPool);
3568             auto& info = mDescriptorPoolInfo[*pDescriptorPool];
3569             info.device = device;
3570             *pDescriptorPool = new_boxed_non_dispatchable_VkDescriptorPool(*pDescriptorPool);
3571             info.boxed = *pDescriptorPool;
3572             info.createInfo = *pCreateInfo;
3573             info.maxSets = pCreateInfo->maxSets;
3574             info.usedSets = 0;
3575 
3576             for (uint32_t i = 0; i < pCreateInfo->poolSizeCount; ++i) {
3577                 DescriptorPoolInfo::PoolState state;
3578                 state.type = pCreateInfo->pPoolSizes[i].type;
3579                 state.descriptorCount = pCreateInfo->pPoolSizes[i].descriptorCount;
3580                 state.used = 0;
3581                 info.pools.push_back(state);
3582             }
3583 
3584             if (m_vkEmulation->getFeatures().VulkanBatchedDescriptorSetUpdate.enabled) {
3585                 for (uint32_t i = 0; i < pCreateInfo->maxSets; ++i) {
3586                     info.poolIds.push_back(
3587                         (uint64_t)new_boxed_non_dispatchable_VkDescriptorSet(VK_NULL_HANDLE));
3588                 }
3589                 if (snapshotsEnabled() && snapshotInfo) {
3590                     snapshotInfo->addOrderedBoxedHandlesCreatedByCall(info.poolIds.data(),
3591                                                                       info.poolIds.size());
3592                 }
3593             }
3594         }
3595 
3596         return res;
3597     }
3598 
cleanupDescriptorPoolAllocedSetsLocked(DescriptorPoolInfo & descriptorPoolInfo,std::unordered_map<VkDescriptorSet,DescriptorSetInfo> & descriptorSetInfos,bool isDestroy=false)3599     void cleanupDescriptorPoolAllocedSetsLocked(
3600         DescriptorPoolInfo& descriptorPoolInfo,
3601         std::unordered_map<VkDescriptorSet, DescriptorSetInfo>& descriptorSetInfos,
3602         bool isDestroy = false) {
3603         for (auto it : descriptorPoolInfo.allocedSetsToBoxed) {
3604             auto unboxedSet = it.first;
3605             auto boxedSet = it.second;
3606             descriptorSetInfos.erase(unboxedSet);
3607             if (!m_vkEmulation->getFeatures().VulkanBatchedDescriptorSetUpdate.enabled) {
3608                 delete_VkDescriptorSet(boxedSet);
3609             }
3610         }
3611 
3612         if (m_vkEmulation->getFeatures().VulkanBatchedDescriptorSetUpdate.enabled) {
3613             if (isDestroy) {
3614                 for (auto poolId : descriptorPoolInfo.poolIds) {
3615                     delete_VkDescriptorSet((VkDescriptorSet)poolId);
3616                 }
3617             } else {
3618                 for (auto poolId : descriptorPoolInfo.poolIds) {
3619                     auto handleInfo = sBoxedHandleManager.get(poolId);
3620                     if (handleInfo)
3621                         handleInfo->underlying = reinterpret_cast<uint64_t>(VK_NULL_HANDLE);
3622                 }
3623             }
3624         }
3625 
3626         descriptorPoolInfo.usedSets = 0;
3627         descriptorPoolInfo.allocedSetsToBoxed.clear();
3628 
3629         for (auto& pool : descriptorPoolInfo.pools) {
3630             pool.used = 0;
3631         }
3632     }
3633 
destroyDescriptorPoolWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkDescriptorPool descriptorPool,DescriptorPoolInfo & descriptorPoolInfo,std::unordered_map<VkDescriptorSet,DescriptorSetInfo> & descriptorSetInfos,const VkAllocationCallbacks * pAllocator)3634     void destroyDescriptorPoolWithExclusiveInfo(
3635         VkDevice device, VulkanDispatch* deviceDispatch, VkDescriptorPool descriptorPool,
3636         DescriptorPoolInfo& descriptorPoolInfo,
3637         std::unordered_map<VkDescriptorSet, DescriptorSetInfo>& descriptorSetInfos,
3638         const VkAllocationCallbacks* pAllocator) {
3639         cleanupDescriptorPoolAllocedSetsLocked(descriptorPoolInfo, descriptorSetInfos,
3640                                                true /* destroy */);
3641 
3642         deviceDispatch->vkDestroyDescriptorPool(device, descriptorPool, pAllocator);
3643     }
3644 
destroyDescriptorPoolLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkDescriptorPool descriptorPool,const VkAllocationCallbacks * pAllocator)3645     void destroyDescriptorPoolLocked(VkDevice device, VulkanDispatch* deviceDispatch,
3646                                      VkDescriptorPool descriptorPool,
3647                                      const VkAllocationCallbacks* pAllocator) REQUIRES(mMutex) {
3648         auto descriptorPoolInfoIt = mDescriptorPoolInfo.find(descriptorPool);
3649         if (descriptorPoolInfoIt == mDescriptorPoolInfo.end()) return;
3650         auto& descriptorPoolInfo = descriptorPoolInfoIt->second;
3651 
3652         destroyDescriptorPoolWithExclusiveInfo(device, deviceDispatch, descriptorPool,
3653                                                descriptorPoolInfo, mDescriptorSetInfo, pAllocator);
3654 
3655         mDescriptorPoolInfo.erase(descriptorPoolInfoIt);
3656     }
3657 
on_vkDestroyDescriptorPool(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkDescriptorPool descriptorPool,const VkAllocationCallbacks * pAllocator)3658     void on_vkDestroyDescriptorPool(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3659                                     VkDevice boxed_device, VkDescriptorPool descriptorPool,
3660                                     const VkAllocationCallbacks* pAllocator) {
3661         auto device = unbox_VkDevice(boxed_device);
3662         auto deviceDispatch = dispatch_VkDevice(boxed_device);
3663 
3664         std::lock_guard<std::mutex> lock(mMutex);
3665         destroyDescriptorPoolLocked(device, deviceDispatch, descriptorPool, pAllocator);
3666     }
3667 
resetDescriptorPoolInfoLocked(VkDescriptorPool descriptorPool)3668     void resetDescriptorPoolInfoLocked(VkDescriptorPool descriptorPool) REQUIRES(mMutex) {
3669         auto descriptorPoolInfoIt = mDescriptorPoolInfo.find(descriptorPool);
3670         if (descriptorPoolInfoIt == mDescriptorPoolInfo.end()) return;
3671         auto& descriptorPoolInfo = descriptorPoolInfoIt->second;
3672 
3673         cleanupDescriptorPoolAllocedSetsLocked(descriptorPoolInfo, mDescriptorSetInfo,
3674                                                /*isDestroy=*/false);
3675     }
3676 
on_vkResetDescriptorPool(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkDescriptorPool descriptorPool,VkDescriptorPoolResetFlags flags)3677     VkResult on_vkResetDescriptorPool(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3678                                       VkDevice boxed_device, VkDescriptorPool descriptorPool,
3679                                       VkDescriptorPoolResetFlags flags) {
3680         auto device = unbox_VkDevice(boxed_device);
3681         auto deviceDispatch = dispatch_VkDevice(boxed_device);
3682 
3683         auto result = deviceDispatch->vkResetDescriptorPool(device, descriptorPool, flags);
3684         if (result != VK_SUCCESS) return result;
3685 
3686         std::lock_guard<std::mutex> lock(mMutex);
3687         resetDescriptorPoolInfoLocked(descriptorPool);
3688 
3689         return VK_SUCCESS;
3690     }
3691 
initDescriptorSetInfoLocked(VkDevice device,VkDescriptorPool pool,VkDescriptorSetLayout setLayout,uint64_t boxedDescriptorSet,VkDescriptorSet descriptorSet)3692     void initDescriptorSetInfoLocked(VkDevice device, VkDescriptorPool pool,
3693                                      VkDescriptorSetLayout setLayout, uint64_t boxedDescriptorSet,
3694                                      VkDescriptorSet descriptorSet) REQUIRES(mMutex) {
3695         auto* poolInfo = android::base::find(mDescriptorPoolInfo, pool);
3696         if (!poolInfo) {
3697             GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Cannot find poolInfo";
3698         }
3699 
3700         auto* setLayoutInfo = android::base::find(mDescriptorSetLayoutInfo, setLayout);
3701         if (!setLayoutInfo) {
3702             GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Cannot find setLayout";
3703         }
3704 
3705         VALIDATE_NEW_HANDLE_INFO_ENTRY(mDescriptorSetInfo, descriptorSet);
3706         auto& setInfo = mDescriptorSetInfo[descriptorSet];
3707 
3708         setInfo.device = device;
3709         setInfo.pool = pool;
3710         setInfo.unboxedLayout = setLayout;
3711         setInfo.bindings = setLayoutInfo->bindings;
3712         for (size_t i = 0; i < setInfo.bindings.size(); i++) {
3713             VkDescriptorSetLayoutBinding dslBinding = setInfo.bindings[i];
3714             int bindingIdx = dslBinding.binding;
3715             if ((int)setInfo.allWrites.size() <= bindingIdx) {
3716                 setInfo.allWrites.resize(bindingIdx + 1);
3717             }
3718             setInfo.allWrites[bindingIdx].resize(dslBinding.descriptorCount);
3719             for (auto& write : setInfo.allWrites[bindingIdx]) {
3720                 write.descriptorType = dslBinding.descriptorType;
3721                 write.dstArrayElement = 0;
3722             }
3723         }
3724 
3725         poolInfo->allocedSetsToBoxed[descriptorSet] = (VkDescriptorSet)boxedDescriptorSet;
3726         applyDescriptorSetAllocationLocked(*poolInfo, setInfo.bindings);
3727     }
3728 
on_vkAllocateDescriptorSets(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkDescriptorSetAllocateInfo * pAllocateInfo,VkDescriptorSet * pDescriptorSets)3729     VkResult on_vkAllocateDescriptorSets(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3730                                          VkDevice boxed_device,
3731                                          const VkDescriptorSetAllocateInfo* pAllocateInfo,
3732                                          VkDescriptorSet* pDescriptorSets) {
3733         auto device = unbox_VkDevice(boxed_device);
3734         auto vk = dispatch_VkDevice(boxed_device);
3735 
3736         std::lock_guard<std::mutex> lock(mMutex);
3737 
3738         auto allocValidationRes = validateDescriptorSetAllocLocked(pAllocateInfo);
3739         if (allocValidationRes != VK_SUCCESS) return allocValidationRes;
3740 
3741         auto res = vk->vkAllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
3742 
3743         if (res == VK_SUCCESS) {
3744             auto* poolInfo =
3745                 android::base::find(mDescriptorPoolInfo, pAllocateInfo->descriptorPool);
3746             if (!poolInfo) return res;
3747 
3748             for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; ++i) {
3749                 auto unboxed = pDescriptorSets[i];
3750                 pDescriptorSets[i] = new_boxed_non_dispatchable_VkDescriptorSet(pDescriptorSets[i]);
3751                 initDescriptorSetInfoLocked(device, pAllocateInfo->descriptorPool,
3752                                             pAllocateInfo->pSetLayouts[i],
3753                                             (uint64_t)(pDescriptorSets[i]), unboxed);
3754             }
3755         }
3756 
3757         return res;
3758     }
3759 
on_vkFreeDescriptorSets(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkDescriptorPool descriptorPool,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets)3760     VkResult on_vkFreeDescriptorSets(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3761                                      VkDevice boxed_device, VkDescriptorPool descriptorPool,
3762                                      uint32_t descriptorSetCount,
3763                                      const VkDescriptorSet* pDescriptorSets) {
3764         auto device = unbox_VkDevice(boxed_device);
3765         auto vk = dispatch_VkDevice(boxed_device);
3766 
3767         auto res =
3768             vk->vkFreeDescriptorSets(device, descriptorPool, descriptorSetCount, pDescriptorSets);
3769 
3770         if (res == VK_SUCCESS) {
3771             std::lock_guard<std::mutex> lock(mMutex);
3772 
3773             for (uint32_t i = 0; i < descriptorSetCount; ++i) {
3774                 auto* setInfo = android::base::find(mDescriptorSetInfo, pDescriptorSets[i]);
3775                 if (!setInfo) continue;
3776                 auto* poolInfo = android::base::find(mDescriptorPoolInfo, setInfo->pool);
3777                 if (!poolInfo) continue;
3778 
3779                 removeDescriptorSetAllocationLocked(*poolInfo, setInfo->bindings);
3780 
3781                 auto descSetAllocedEntry =
3782                     android::base::find(poolInfo->allocedSetsToBoxed, pDescriptorSets[i]);
3783                 if (!descSetAllocedEntry) continue;
3784 
3785                 auto handleInfo = sBoxedHandleManager.get((uint64_t)*descSetAllocedEntry);
3786                 if (handleInfo) {
3787                     if (m_vkEmulation->getFeatures().VulkanBatchedDescriptorSetUpdate.enabled) {
3788                         handleInfo->underlying = reinterpret_cast<uint64_t>(VK_NULL_HANDLE);
3789                     } else {
3790                         delete_VkDescriptorSet(*descSetAllocedEntry);
3791                     }
3792                 }
3793 
3794                 poolInfo->allocedSetsToBoxed.erase(pDescriptorSets[i]);
3795 
3796                 mDescriptorSetInfo.erase(pDescriptorSets[i]);
3797             }
3798         }
3799 
3800         return res;
3801     }
3802 
on_vkUpdateDescriptorSets(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites,uint32_t descriptorCopyCount,const VkCopyDescriptorSet * pDescriptorCopies)3803     void on_vkUpdateDescriptorSets(android::base::BumpPool* pool,
3804                                    VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
3805                                    uint32_t descriptorWriteCount,
3806                                    const VkWriteDescriptorSet* pDescriptorWrites,
3807                                    uint32_t descriptorCopyCount,
3808                                    const VkCopyDescriptorSet* pDescriptorCopies) {
3809         auto device = unbox_VkDevice(boxed_device);
3810         auto vk = dispatch_VkDevice(boxed_device);
3811 
3812         std::lock_guard<std::mutex> lock(mMutex);
3813         on_vkUpdateDescriptorSetsImpl(pool, snapshotInfo, vk, device, descriptorWriteCount, pDescriptorWrites,
3814                                       descriptorCopyCount, pDescriptorCopies);
3815     }
3816 
on_vkUpdateDescriptorSetsImpl(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VulkanDispatch * vk,VkDevice device,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites,uint32_t descriptorCopyCount,const VkCopyDescriptorSet * pDescriptorCopies)3817     void on_vkUpdateDescriptorSetsImpl(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
3818                                        VulkanDispatch* vk, VkDevice device,
3819                                        uint32_t descriptorWriteCount,
3820                                        const VkWriteDescriptorSet* pDescriptorWrites,
3821                                        uint32_t descriptorCopyCount,
3822                                        const VkCopyDescriptorSet* pDescriptorCopies) REQUIRES(mMutex) {
3823         for (uint32_t writeIdx = 0; writeIdx < descriptorWriteCount; writeIdx++) {
3824             const VkWriteDescriptorSet& descriptorWrite = pDescriptorWrites[writeIdx];
3825             auto ite = mDescriptorSetInfo.find(descriptorWrite.dstSet);
3826             if (ite == mDescriptorSetInfo.end()) {
3827                 continue;
3828             }
3829             DescriptorSetInfo& descriptorSetInfo = ite->second;
3830             auto& table = descriptorSetInfo.allWrites;
3831             VkDescriptorType descType = descriptorWrite.descriptorType;
3832             uint32_t dstBinding = descriptorWrite.dstBinding;
3833             uint32_t dstArrayElement = descriptorWrite.dstArrayElement;
3834             uint32_t descriptorCount = descriptorWrite.descriptorCount;
3835 
3836             uint32_t arrOffset = dstArrayElement;
3837 
3838             if (isDescriptorTypeImageInfo(descType)) {
3839                 for (uint32_t writeElemIdx = 0; writeElemIdx < descriptorCount;
3840                      ++writeElemIdx, ++arrOffset) {
3841                     // Descriptor writes wrap to the next binding. See
3842                     // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkWriteDescriptorSet.html
3843                     if (arrOffset >= table[dstBinding].size()) {
3844                         ++dstBinding;
3845                         arrOffset = 0;
3846                     }
3847                     auto& entry = table[dstBinding][arrOffset];
3848                     entry.imageInfo = descriptorWrite.pImageInfo[writeElemIdx];
3849                     entry.writeType = DescriptorSetInfo::DescriptorWriteType::ImageInfo;
3850                     entry.descriptorType = descType;
3851                     entry.alives.clear();
3852                     entry.boundColorBuffer.reset();
3853                     if (descriptorTypeContainsImage(descType)) {
3854                         auto* imageViewInfo =
3855                             android::base::find(mImageViewInfo, entry.imageInfo.imageView);
3856                         if (imageViewInfo) {
3857                             entry.alives.push_back(imageViewInfo->alive);
3858                             entry.boundColorBuffer = imageViewInfo->boundColorBuffer;
3859                         }
3860                     }
3861                     if (descriptorTypeContainsSampler(descType)) {
3862                         auto* samplerInfo =
3863                             android::base::find(mSamplerInfo, entry.imageInfo.sampler);
3864                         if (samplerInfo) {
3865                             entry.alives.push_back(samplerInfo->alive);
3866                         }
3867                     }
3868                 }
3869             } else if (isDescriptorTypeBufferInfo(descType)) {
3870                 for (uint32_t writeElemIdx = 0; writeElemIdx < descriptorCount;
3871                      ++writeElemIdx, ++arrOffset) {
3872                     if (arrOffset >= table[dstBinding].size()) {
3873                         ++dstBinding;
3874                         arrOffset = 0;
3875                     }
3876                     auto& entry = table[dstBinding][arrOffset];
3877                     entry.bufferInfo = descriptorWrite.pBufferInfo[writeElemIdx];
3878                     entry.writeType = DescriptorSetInfo::DescriptorWriteType::BufferInfo;
3879                     entry.descriptorType = descType;
3880                     entry.alives.clear();
3881                     auto* bufferInfo = android::base::find(mBufferInfo, entry.bufferInfo.buffer);
3882                     if (bufferInfo) {
3883                         entry.alives.push_back(bufferInfo->alive);
3884                     }
3885                 }
3886             } else if (isDescriptorTypeBufferView(descType)) {
3887                 for (uint32_t writeElemIdx = 0; writeElemIdx < descriptorCount;
3888                      ++writeElemIdx, ++arrOffset) {
3889                     if (arrOffset >= table[dstBinding].size()) {
3890                         ++dstBinding;
3891                         arrOffset = 0;
3892                     }
3893                     auto& entry = table[dstBinding][arrOffset];
3894                     entry.bufferView = descriptorWrite.pTexelBufferView[writeElemIdx];
3895                     entry.writeType = DescriptorSetInfo::DescriptorWriteType::BufferView;
3896                     entry.descriptorType = descType;
3897                     if (snapshotsEnabled()) {
3898                         // TODO: check alive
3899                         ERR("%s: Snapshot for texel buffer view is incomplete.\n", __func__);
3900                     }
3901                 }
3902             } else if (isDescriptorTypeInlineUniformBlock(descType)) {
3903                 const VkWriteDescriptorSetInlineUniformBlock* descInlineUniformBlock =
3904                     static_cast<const VkWriteDescriptorSetInlineUniformBlock*>(
3905                         descriptorWrite.pNext);
3906                 while (descInlineUniformBlock &&
3907                        descInlineUniformBlock->sType !=
3908                            VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK) {
3909                     descInlineUniformBlock =
3910                         static_cast<const VkWriteDescriptorSetInlineUniformBlock*>(
3911                             descInlineUniformBlock->pNext);
3912                 }
3913                 if (!descInlineUniformBlock) {
3914                     GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
3915                         << __func__ << ": did not find inline uniform block";
3916                     return;
3917                 }
3918                 auto& entry = table[dstBinding][0];
3919                 entry.inlineUniformBlock = *descInlineUniformBlock;
3920                 entry.inlineUniformBlockBuffer.assign(
3921                     static_cast<const uint8_t*>(descInlineUniformBlock->pData),
3922                     static_cast<const uint8_t*>(descInlineUniformBlock->pData) +
3923                         descInlineUniformBlock->dataSize);
3924                 entry.writeType = DescriptorSetInfo::DescriptorWriteType::InlineUniformBlock;
3925                 entry.descriptorType = descType;
3926                 entry.dstArrayElement = dstArrayElement;
3927             } else if (isDescriptorTypeAccelerationStructure(descType)) {
3928                 // TODO
3929                 // Look for pNext inline uniform block or acceleration structure.
3930                 // Append new DescriptorWrite entry that holds the buffer
3931                 if (snapshotsEnabled()) {
3932                     ERR("%s: Ignoring Snapshot for emulated write for descriptor type 0x%x\n",
3933                         __func__, descType);
3934                 }
3935             }
3936         }
3937         // TODO: bookkeep pDescriptorCopies
3938         // Our primary use case vkQueueCommitDescriptorSetUpdatesGOOGLE does not use
3939         // pDescriptorCopies. Thus skip its implementation for now.
3940         if (descriptorCopyCount && snapshotsEnabled()) {
3941             ERR("%s: Snapshot does not support descriptor copy yet\n");
3942         }
3943         bool needEmulateWriteDescriptor = false;
3944         // c++ seems to allow for 0-size array allocation
3945         std::unique_ptr<bool[]> descriptorWritesNeedDeepCopy(new bool[descriptorWriteCount]);
3946         for (uint32_t i = 0; i < descriptorWriteCount; i++) {
3947             const VkWriteDescriptorSet& descriptorWrite = pDescriptorWrites[i];
3948             descriptorWritesNeedDeepCopy[i] = false;
3949             if (!vk_util::vk_descriptor_type_has_image_view(descriptorWrite.descriptorType)) {
3950                 continue;
3951             }
3952             for (uint32_t j = 0; j < descriptorWrite.descriptorCount; j++) {
3953                 const VkDescriptorImageInfo& imageInfo = descriptorWrite.pImageInfo[j];
3954                 const auto* imgViewInfo = android::base::find(mImageViewInfo, imageInfo.imageView);
3955                 if (!imgViewInfo) {
3956                     continue;
3957                 }
3958                 if (descriptorWrite.descriptorType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
3959                     continue;
3960                 }
3961                 const auto* samplerInfo = android::base::find(mSamplerInfo, imageInfo.sampler);
3962                 if (samplerInfo && imgViewInfo->needEmulatedAlpha &&
3963                     samplerInfo->needEmulatedAlpha) {
3964                     needEmulateWriteDescriptor = true;
3965                     descriptorWritesNeedDeepCopy[i] = true;
3966                     break;
3967                 }
3968             }
3969         }
3970         if (!needEmulateWriteDescriptor) {
3971             vk->vkUpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites,
3972                                        descriptorCopyCount, pDescriptorCopies);
3973             return;
3974         }
3975         std::list<std::unique_ptr<VkDescriptorImageInfo[]>> imageInfoPool;
3976         std::unique_ptr<VkWriteDescriptorSet[]> descriptorWrites(
3977             new VkWriteDescriptorSet[descriptorWriteCount]);
3978         for (uint32_t i = 0; i < descriptorWriteCount; i++) {
3979             const VkWriteDescriptorSet& srcDescriptorWrite = pDescriptorWrites[i];
3980             VkWriteDescriptorSet& dstDescriptorWrite = descriptorWrites[i];
3981             // Shallow copy first
3982             dstDescriptorWrite = srcDescriptorWrite;
3983             if (!descriptorWritesNeedDeepCopy[i]) {
3984                 continue;
3985             }
3986             // Deep copy
3987             assert(dstDescriptorWrite.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
3988             imageInfoPool.emplace_back(
3989                 new VkDescriptorImageInfo[dstDescriptorWrite.descriptorCount]);
3990             VkDescriptorImageInfo* imageInfos = imageInfoPool.back().get();
3991             memcpy(imageInfos, srcDescriptorWrite.pImageInfo,
3992                    dstDescriptorWrite.descriptorCount * sizeof(VkDescriptorImageInfo));
3993             dstDescriptorWrite.pImageInfo = imageInfos;
3994             for (uint32_t j = 0; j < dstDescriptorWrite.descriptorCount; j++) {
3995                 VkDescriptorImageInfo& imageInfo = imageInfos[j];
3996                 const auto* imgViewInfo = android::base::find(mImageViewInfo, imageInfo.imageView);
3997                 auto* samplerInfo = android::base::find(mSamplerInfo, imageInfo.sampler);
3998                 if (!imgViewInfo || !samplerInfo) continue;
3999                 if (imgViewInfo->needEmulatedAlpha && samplerInfo->needEmulatedAlpha) {
4000                     if (samplerInfo->emulatedborderSampler == VK_NULL_HANDLE) {
4001                         // create the emulated sampler
4002                         VkSamplerCreateInfo createInfo;
4003                         deepcopy_VkSamplerCreateInfo(pool, VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
4004                                                      &samplerInfo->createInfo, &createInfo);
4005                         switch (createInfo.borderColor) {
4006                             case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
4007                                 createInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
4008                                 break;
4009                             case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
4010                                 createInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
4011                                 break;
4012                             case VK_BORDER_COLOR_FLOAT_CUSTOM_EXT:
4013                             case VK_BORDER_COLOR_INT_CUSTOM_EXT: {
4014                                 VkSamplerCustomBorderColorCreateInfoEXT*
4015                                     customBorderColorCreateInfo =
4016                                         vk_find_struct<VkSamplerCustomBorderColorCreateInfoEXT>(
4017                                             &createInfo);
4018                                 if (customBorderColorCreateInfo) {
4019                                     switch (createInfo.borderColor) {
4020                                         case VK_BORDER_COLOR_FLOAT_CUSTOM_EXT:
4021                                             customBorderColorCreateInfo->customBorderColor
4022                                                 .float32[3] = 1.0f;
4023                                             break;
4024                                         case VK_BORDER_COLOR_INT_CUSTOM_EXT:
4025                                             customBorderColorCreateInfo->customBorderColor
4026                                                 .int32[3] = 128;
4027                                             break;
4028                                         default:
4029                                             break;
4030                                     }
4031                                 }
4032                                 break;
4033                             }
4034                             default:
4035                                 break;
4036                         }
4037                         vk->vkCreateSampler(device, &createInfo, nullptr,
4038                                             &samplerInfo->emulatedborderSampler);
4039                     }
4040                     imageInfo.sampler = samplerInfo->emulatedborderSampler;
4041                 }
4042             }
4043         }
4044         vk->vkUpdateDescriptorSets(device, descriptorWriteCount, descriptorWrites.get(),
4045                                    descriptorCopyCount, pDescriptorCopies);
4046     }
4047 
on_vkCreateShaderModule(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkShaderModuleCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkShaderModule * pShaderModule)4048     VkResult on_vkCreateShaderModule(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4049                                      VkDevice boxed_device,
4050                                      const VkShaderModuleCreateInfo* pCreateInfo,
4051                                      const VkAllocationCallbacks* pAllocator,
4052                                      VkShaderModule* pShaderModule) {
4053         auto device = unbox_VkDevice(boxed_device);
4054         auto deviceDispatch = dispatch_VkDevice(boxed_device);
4055 
4056         VkResult result =
4057             deviceDispatch->vkCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule);
4058         if (result != VK_SUCCESS) {
4059             return result;
4060         }
4061 
4062         std::lock_guard<std::mutex> lock(mMutex);
4063 
4064         VALIDATE_NEW_HANDLE_INFO_ENTRY(mShaderModuleInfo, *pShaderModule);
4065         auto& shaderModuleInfo = mShaderModuleInfo[*pShaderModule];
4066         shaderModuleInfo.device = device;
4067 
4068         *pShaderModule = new_boxed_non_dispatchable_VkShaderModule(*pShaderModule);
4069 
4070         return result;
4071     }
4072 
destroyShaderModuleWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkShaderModule shaderModule,ShaderModuleInfo &,const VkAllocationCallbacks * pAllocator)4073     void destroyShaderModuleWithExclusiveInfo(VkDevice device, VulkanDispatch* deviceDispatch,
4074                                               VkShaderModule shaderModule, ShaderModuleInfo&,
4075                                               const VkAllocationCallbacks* pAllocator) {
4076         deviceDispatch->vkDestroyShaderModule(device, shaderModule, pAllocator);
4077     }
4078 
destroyShaderModuleLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkShaderModule shaderModule,const VkAllocationCallbacks * pAllocator)4079     void destroyShaderModuleLocked(VkDevice device, VulkanDispatch* deviceDispatch,
4080                                    VkShaderModule shaderModule,
4081                                    const VkAllocationCallbacks* pAllocator) REQUIRES(mMutex) {
4082         auto shaderModuleInfoIt = mShaderModuleInfo.find(shaderModule);
4083         if (shaderModuleInfoIt == mShaderModuleInfo.end()) return;
4084         auto& shaderModuleInfo = shaderModuleInfoIt->second;
4085 
4086         destroyShaderModuleWithExclusiveInfo(device, deviceDispatch, shaderModule, shaderModuleInfo,
4087                                              pAllocator);
4088 
4089         mShaderModuleInfo.erase(shaderModuleInfoIt);
4090     }
4091 
on_vkDestroyShaderModule(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkShaderModule shaderModule,const VkAllocationCallbacks * pAllocator)4092     void on_vkDestroyShaderModule(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4093                                   VkDevice boxed_device, VkShaderModule shaderModule,
4094                                   const VkAllocationCallbacks* pAllocator) {
4095         auto device = unbox_VkDevice(boxed_device);
4096         auto deviceDispatch = dispatch_VkDevice(boxed_device);
4097 
4098         std::lock_guard<std::mutex> lock(mMutex);
4099         destroyShaderModuleLocked(device, deviceDispatch, shaderModule, pAllocator);
4100     }
4101 
on_vkCreatePipelineCache(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkPipelineCacheCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipelineCache * pPipelineCache)4102     VkResult on_vkCreatePipelineCache(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4103                                       VkDevice boxed_device,
4104                                       const VkPipelineCacheCreateInfo* pCreateInfo,
4105                                       const VkAllocationCallbacks* pAllocator,
4106                                       VkPipelineCache* pPipelineCache) {
4107         auto device = unbox_VkDevice(boxed_device);
4108         auto deviceDispatch = dispatch_VkDevice(boxed_device);
4109 
4110         VkResult result =
4111             deviceDispatch->vkCreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache);
4112         if (result != VK_SUCCESS) {
4113             return result;
4114         }
4115 
4116         std::lock_guard<std::mutex> lock(mMutex);
4117 
4118         VALIDATE_NEW_HANDLE_INFO_ENTRY(mPipelineCacheInfo, *pPipelineCache);
4119         auto& pipelineCacheInfo = mPipelineCacheInfo[*pPipelineCache];
4120         pipelineCacheInfo.device = device;
4121 
4122         *pPipelineCache = new_boxed_non_dispatchable_VkPipelineCache(*pPipelineCache);
4123 
4124         return result;
4125     }
4126 
destroyPipelineCacheWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkPipelineCache pipelineCache,PipelineCacheInfo & pipelineCacheInfo,const VkAllocationCallbacks * pAllocator)4127     void destroyPipelineCacheWithExclusiveInfo(VkDevice device, VulkanDispatch* deviceDispatch,
4128                                                VkPipelineCache pipelineCache,
4129                                                PipelineCacheInfo& pipelineCacheInfo,
4130                                                const VkAllocationCallbacks* pAllocator) {
4131         deviceDispatch->vkDestroyPipelineCache(device, pipelineCache, pAllocator);
4132     }
4133 
destroyPipelineCacheLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkPipelineCache pipelineCache,const VkAllocationCallbacks * pAllocator)4134     void destroyPipelineCacheLocked(VkDevice device, VulkanDispatch* deviceDispatch,
4135                                     VkPipelineCache pipelineCache,
4136                                     const VkAllocationCallbacks* pAllocator) REQUIRES(mMutex) {
4137         auto pipelineCacheInfoIt = mPipelineCacheInfo.find(pipelineCache);
4138         if (pipelineCacheInfoIt == mPipelineCacheInfo.end()) return;
4139         auto& pipelineCacheInfo = pipelineCacheInfoIt->second;
4140 
4141         destroyPipelineCacheWithExclusiveInfo(device, deviceDispatch, pipelineCache,
4142                                               pipelineCacheInfo, pAllocator);
4143 
4144         mPipelineCacheInfo.erase(pipelineCache);
4145     }
4146 
on_vkDestroyPipelineCache(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkPipelineCache pipelineCache,const VkAllocationCallbacks * pAllocator)4147     void on_vkDestroyPipelineCache(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4148                                    VkDevice boxed_device, VkPipelineCache pipelineCache,
4149                                    const VkAllocationCallbacks* pAllocator) {
4150         auto device = unbox_VkDevice(boxed_device);
4151         auto deviceDispatch = dispatch_VkDevice(boxed_device);
4152 
4153         std::lock_guard<std::mutex> lock(mMutex);
4154         destroyPipelineCacheLocked(device, deviceDispatch, pipelineCache, pAllocator);
4155     }
4156 
on_vkCreatePipelineLayout(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkPipelineLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipelineLayout * pPipelineLayout)4157     VkResult on_vkCreatePipelineLayout(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4158                                       VkDevice boxed_device,
4159                                       const VkPipelineLayoutCreateInfo* pCreateInfo,
4160                                       const VkAllocationCallbacks* pAllocator,
4161                                       VkPipelineLayout* pPipelineLayout) {
4162         auto device = unbox_VkDevice(boxed_device);
4163         auto deviceDispatch = dispatch_VkDevice(boxed_device);
4164 
4165         VkResult result =
4166             deviceDispatch->vkCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout);
4167         if (result != VK_SUCCESS) {
4168             return result;
4169         }
4170 
4171         std::lock_guard<std::mutex> lock(mMutex);
4172 
4173         VALIDATE_NEW_HANDLE_INFO_ENTRY(mPipelineLayoutInfo, *pPipelineLayout);
4174         auto& pipelineLayoutInfo = mPipelineLayoutInfo[*pPipelineLayout];
4175         pipelineLayoutInfo.device = device;
4176 
4177         *pPipelineLayout = new_boxed_non_dispatchable_VkPipelineLayout(*pPipelineLayout);
4178 
4179         return result;
4180     }
4181 
destroyPipelineLayoutWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkPipelineLayout pipelineLayout,PipelineLayoutInfo & pipelineLayoutInfo,const VkAllocationCallbacks * pAllocator)4182     void destroyPipelineLayoutWithExclusiveInfo(VkDevice device, VulkanDispatch* deviceDispatch,
4183                                                 VkPipelineLayout pipelineLayout,
4184                                                 PipelineLayoutInfo& pipelineLayoutInfo,
4185                                                 const VkAllocationCallbacks* pAllocator) {
4186         deviceDispatch->vkDestroyPipelineLayout(device, pipelineLayout, pAllocator);
4187     }
4188 
destroyPipelineLayoutLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkPipelineLayout pipelineLayout,const VkAllocationCallbacks * pAllocator)4189     void destroyPipelineLayoutLocked(VkDevice device, VulkanDispatch* deviceDispatch,
4190                                      VkPipelineLayout pipelineLayout,
4191                                      const VkAllocationCallbacks* pAllocator) REQUIRES(mMutex) {
4192         auto pipelineLayoutInfoIt = mPipelineLayoutInfo.find(pipelineLayout);
4193         if (pipelineLayoutInfoIt == mPipelineLayoutInfo.end()) return;
4194         auto& pipelineLayoutInfo = pipelineLayoutInfoIt->second;
4195 
4196         destroyPipelineLayoutWithExclusiveInfo(device, deviceDispatch, pipelineLayout,
4197                                                pipelineLayoutInfo, pAllocator);
4198 
4199         mPipelineLayoutInfo.erase(pipelineLayout);
4200     }
4201 
4202     // This call will be delayed as VulkanQueueSubmitWithCommands feature can change order
4203     // of the commands and pipeline layouts need to stay valid during recording.
on_vkDestroyPipelineLayout(android::base::BumpPool *,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkPipelineLayout pipelineLayout,const VkAllocationCallbacks * pAllocator)4204     void on_vkDestroyPipelineLayout(android::base::BumpPool*, VkSnapshotApiCallInfo*,
4205                                     VkDevice boxed_device, VkPipelineLayout pipelineLayout,
4206                                     const VkAllocationCallbacks* pAllocator) {
4207         auto device = unbox_VkDevice(boxed_device);
4208         auto deviceDispatch = dispatch_VkDevice(boxed_device);
4209 
4210         std::lock_guard<std::mutex> lock(mMutex);
4211         destroyPipelineLayoutLocked(device, deviceDispatch, pipelineLayout, pAllocator);
4212     }
4213 
on_vkCreateGraphicsPipelines(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)4214     VkResult on_vkCreateGraphicsPipelines(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4215                                           VkDevice boxed_device, VkPipelineCache pipelineCache,
4216                                           uint32_t createInfoCount,
4217                                           const VkGraphicsPipelineCreateInfo* pCreateInfos,
4218                                           const VkAllocationCallbacks* pAllocator,
4219                                           VkPipeline* pPipelines) {
4220         auto device = unbox_VkDevice(boxed_device);
4221         auto deviceDispatch = dispatch_VkDevice(boxed_device);
4222 
4223         VkResult result = deviceDispatch->vkCreateGraphicsPipelines(
4224             device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
4225         if (result != VK_SUCCESS && result != VK_PIPELINE_COMPILE_REQUIRED) {
4226             return result;
4227         }
4228 
4229         std::lock_guard<std::mutex> lock(mMutex);
4230 
4231         for (uint32_t i = 0; i < createInfoCount; i++) {
4232             if (!pPipelines[i]) {
4233                 continue;
4234             }
4235             VALIDATE_NEW_HANDLE_INFO_ENTRY(mPipelineInfo, pPipelines[i]);
4236             auto& pipelineInfo = mPipelineInfo[pPipelines[i]];
4237             pipelineInfo.device = device;
4238 
4239             pPipelines[i] = new_boxed_non_dispatchable_VkPipeline(pPipelines[i]);
4240         }
4241 
4242         return result;
4243     }
4244 
on_vkCreateComputePipelines(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)4245     VkResult on_vkCreateComputePipelines(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4246                                          VkDevice boxed_device, VkPipelineCache pipelineCache,
4247                                          uint32_t createInfoCount,
4248                                          const VkComputePipelineCreateInfo* pCreateInfos,
4249                                          const VkAllocationCallbacks* pAllocator,
4250                                          VkPipeline* pPipelines) {
4251         auto device = unbox_VkDevice(boxed_device);
4252         auto deviceDispatch = dispatch_VkDevice(boxed_device);
4253 
4254         VkResult result = deviceDispatch->vkCreateComputePipelines(
4255             device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
4256         if (result != VK_SUCCESS && result != VK_PIPELINE_COMPILE_REQUIRED) {
4257             return result;
4258         }
4259 
4260         std::lock_guard<std::mutex> lock(mMutex);
4261 
4262         for (uint32_t i = 0; i < createInfoCount; i++) {
4263             if (!pPipelines[i]) {
4264                 continue;
4265             }
4266             VALIDATE_NEW_HANDLE_INFO_ENTRY(mPipelineInfo, pPipelines[i]);
4267             auto& pipelineInfo = mPipelineInfo[pPipelines[i]];
4268             pipelineInfo.device = device;
4269 
4270             pPipelines[i] = new_boxed_non_dispatchable_VkPipeline(pPipelines[i]);
4271         }
4272 
4273         return result;
4274     }
4275 
destroyPipelineWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkPipeline pipeline,PipelineInfo & pipelineInfo,const VkAllocationCallbacks * pAllocator)4276     void destroyPipelineWithExclusiveInfo(VkDevice device, VulkanDispatch* deviceDispatch,
4277                                           VkPipeline pipeline, PipelineInfo& pipelineInfo,
4278                                           const VkAllocationCallbacks* pAllocator) {
4279         deviceDispatch->vkDestroyPipeline(device, pipeline, pAllocator);
4280     }
4281 
destroyPipelineLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkPipeline pipeline,const VkAllocationCallbacks * pAllocator)4282     void destroyPipelineLocked(VkDevice device, VulkanDispatch* deviceDispatch, VkPipeline pipeline,
4283                                const VkAllocationCallbacks* pAllocator) REQUIRES(mMutex) {
4284         auto pipelineInfoIt = mPipelineInfo.find(pipeline);
4285         if (pipelineInfoIt == mPipelineInfo.end()) return;
4286         auto& pipelineInfo = pipelineInfoIt->second;
4287 
4288         destroyPipelineWithExclusiveInfo(device, deviceDispatch, pipeline, pipelineInfo,
4289                                          pAllocator);
4290 
4291         mPipelineInfo.erase(pipeline);
4292     }
4293 
on_vkDestroyPipeline(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkPipeline pipeline,const VkAllocationCallbacks * pAllocator)4294     void on_vkDestroyPipeline(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4295                               VkDevice boxed_device, VkPipeline pipeline,
4296                               const VkAllocationCallbacks* pAllocator) {
4297         auto device = unbox_VkDevice(boxed_device);
4298         auto deviceDispatch = dispatch_VkDevice(boxed_device);
4299 
4300         std::lock_guard<std::mutex> lock(mMutex);
4301         destroyPipelineLocked(device, deviceDispatch, pipeline, pAllocator);
4302     }
4303 
on_vkCmdCopyImage(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageCopy * pRegions)4304     void on_vkCmdCopyImage(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4305                            VkCommandBuffer boxed_commandBuffer, VkImage srcImage,
4306                            VkImageLayout srcImageLayout, VkImage dstImage,
4307                            VkImageLayout dstImageLayout, uint32_t regionCount,
4308                            const VkImageCopy* pRegions) {
4309         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4310         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4311 
4312         std::lock_guard<std::mutex> lock(mMutex);
4313         auto* srcImg = android::base::find(mImageInfo, srcImage);
4314         auto* dstImg = android::base::find(mImageInfo, dstImage);
4315         if (!srcImg || !dstImg) return;
4316 
4317         VkDevice device = srcImg->cmpInfo.device();
4318         auto* deviceInfo = android::base::find(mDeviceInfo, device);
4319         if (!deviceInfo) return;
4320 
4321         bool needEmulatedSrc = deviceInfo->needEmulatedDecompression(srcImg->cmpInfo);
4322         bool needEmulatedDst = deviceInfo->needEmulatedDecompression(dstImg->cmpInfo);
4323         if (!needEmulatedSrc && !needEmulatedDst) {
4324             vk->vkCmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
4325                                regionCount, pRegions);
4326             return;
4327         }
4328         VkImage srcImageMip = srcImage;
4329         VkImage dstImageMip = dstImage;
4330         for (uint32_t r = 0; r < regionCount; r++) {
4331             if (needEmulatedSrc) {
4332                 srcImageMip = srcImg->cmpInfo.compressedMipmap(pRegions[r].srcSubresource.mipLevel);
4333             }
4334             if (needEmulatedDst) {
4335                 dstImageMip = dstImg->cmpInfo.compressedMipmap(pRegions[r].dstSubresource.mipLevel);
4336             }
4337             VkImageCopy region = CompressedImageInfo::getCompressedMipmapsImageCopy(
4338                 pRegions[r], srcImg->cmpInfo, dstImg->cmpInfo, needEmulatedSrc, needEmulatedDst);
4339             vk->vkCmdCopyImage(commandBuffer, srcImageMip, srcImageLayout, dstImageMip,
4340                                dstImageLayout, 1, &region);
4341         }
4342     }
4343 
on_vkCmdCopyImageToBuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferImageCopy * pRegions)4344     void on_vkCmdCopyImageToBuffer(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4345                                    VkCommandBuffer boxed_commandBuffer, VkImage srcImage,
4346                                    VkImageLayout srcImageLayout, VkBuffer dstBuffer,
4347                                    uint32_t regionCount, const VkBufferImageCopy* pRegions) {
4348         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4349         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4350 
4351         std::lock_guard<std::mutex> lock(mMutex);
4352         auto* imageInfo = android::base::find(mImageInfo, srcImage);
4353         auto* bufferInfo = android::base::find(mBufferInfo, dstBuffer);
4354         if (!imageInfo || !bufferInfo) return;
4355         auto* deviceInfo = android::base::find(mDeviceInfo, bufferInfo->device);
4356         if (!deviceInfo) return;
4357         CompressedImageInfo& cmpInfo = imageInfo->cmpInfo;
4358         if (!deviceInfo->needEmulatedDecompression(cmpInfo)) {
4359             vk->vkCmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer,
4360                                        regionCount, pRegions);
4361             return;
4362         }
4363         for (uint32_t r = 0; r < regionCount; r++) {
4364             uint32_t mipLevel = pRegions[r].imageSubresource.mipLevel;
4365             VkBufferImageCopy region = cmpInfo.getBufferImageCopy(pRegions[r]);
4366             vk->vkCmdCopyImageToBuffer(commandBuffer, cmpInfo.compressedMipmap(mipLevel),
4367                                        srcImageLayout, dstBuffer, 1, &region);
4368         }
4369     }
4370 
on_vkCmdCopyImage2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,const VkCopyImageInfo2 * pCopyImageInfo)4371     void on_vkCmdCopyImage2(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4372                             VkCommandBuffer boxed_commandBuffer,
4373                             const VkCopyImageInfo2* pCopyImageInfo) {
4374         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4375         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4376 
4377         std::lock_guard<std::mutex> lock(mMutex);
4378         auto* srcImg = android::base::find(mImageInfo, pCopyImageInfo->srcImage);
4379         auto* dstImg = android::base::find(mImageInfo, pCopyImageInfo->dstImage);
4380         if (!srcImg || !dstImg) return;
4381 
4382         VkDevice device = srcImg->cmpInfo.device();
4383         auto* deviceInfo = android::base::find(mDeviceInfo, device);
4384         if (!deviceInfo) return;
4385 
4386         bool needEmulatedSrc = deviceInfo->needEmulatedDecompression(srcImg->cmpInfo);
4387         bool needEmulatedDst = deviceInfo->needEmulatedDecompression(dstImg->cmpInfo);
4388         if (!needEmulatedSrc && !needEmulatedDst) {
4389             vk->vkCmdCopyImage2(commandBuffer, pCopyImageInfo);
4390             return;
4391         }
4392         VkImage srcImageMip = pCopyImageInfo->srcImage;
4393         VkImage dstImageMip = pCopyImageInfo->dstImage;
4394         for (uint32_t r = 0; r < pCopyImageInfo->regionCount; r++) {
4395             if (needEmulatedSrc) {
4396                 srcImageMip = srcImg->cmpInfo.compressedMipmap(pCopyImageInfo->pRegions[r].srcSubresource.mipLevel);
4397             }
4398             if (needEmulatedDst) {
4399                 dstImageMip = dstImg->cmpInfo.compressedMipmap(pCopyImageInfo->pRegions[r].dstSubresource.mipLevel);
4400             }
4401 
4402             VkCopyImageInfo2 inf2 = *pCopyImageInfo;
4403             inf2.regionCount = 1;
4404             inf2.srcImage = srcImageMip;
4405             inf2.dstImage = dstImageMip;
4406 
4407             VkImageCopy2 region = CompressedImageInfo::getCompressedMipmapsImageCopy(
4408                 pCopyImageInfo->pRegions[r], srcImg->cmpInfo, dstImg->cmpInfo, needEmulatedSrc, needEmulatedDst);
4409             inf2.pRegions = &region;
4410 
4411             vk->vkCmdCopyImage2(commandBuffer, &inf2);
4412         }
4413     }
4414 
on_vkCmdCopyImageToBuffer2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,const VkCopyImageToBufferInfo2 * pCopyImageToBufferInfo)4415     void on_vkCmdCopyImageToBuffer2(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4416                                     VkCommandBuffer boxed_commandBuffer,
4417                                     const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo) {
4418         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4419         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4420 
4421         std::lock_guard<std::mutex> lock(mMutex);
4422         auto* imageInfo = android::base::find(mImageInfo, pCopyImageToBufferInfo->srcImage);
4423         auto* bufferInfo = android::base::find(mBufferInfo, pCopyImageToBufferInfo->dstBuffer);
4424         if (!imageInfo || !bufferInfo) return;
4425         auto* deviceInfo = android::base::find(mDeviceInfo, bufferInfo->device);
4426         if (!deviceInfo) return;
4427         CompressedImageInfo& cmpInfo = imageInfo->cmpInfo;
4428         if (!deviceInfo->needEmulatedDecompression(cmpInfo)) {
4429             vk->vkCmdCopyImageToBuffer2(commandBuffer, pCopyImageToBufferInfo);
4430             return;
4431         }
4432         for (uint32_t r = 0; r < pCopyImageToBufferInfo->regionCount; r++) {
4433             uint32_t mipLevel = pCopyImageToBufferInfo->pRegions[r].imageSubresource.mipLevel;
4434             VkBufferImageCopy2 region = cmpInfo.getBufferImageCopy(pCopyImageToBufferInfo->pRegions[r]);
4435             VkCopyImageToBufferInfo2 inf = *pCopyImageToBufferInfo;
4436             inf.regionCount = 1;
4437             inf.pRegions = &region;
4438             inf.srcImage = cmpInfo.compressedMipmap(mipLevel);
4439 
4440             vk->vkCmdCopyImageToBuffer2(commandBuffer, &inf);
4441         }
4442     }
4443 
on_vkCmdCopyImage2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,const VkCopyImageInfo2KHR * pCopyImageInfo)4444     void on_vkCmdCopyImage2KHR(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4445                                VkCommandBuffer boxed_commandBuffer,
4446                                const VkCopyImageInfo2KHR* pCopyImageInfo) {
4447         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4448         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4449 
4450         std::lock_guard<std::mutex> lock(mMutex);
4451         auto* srcImg = android::base::find(mImageInfo, pCopyImageInfo->srcImage);
4452         auto* dstImg = android::base::find(mImageInfo, pCopyImageInfo->dstImage);
4453         if (!srcImg || !dstImg) return;
4454 
4455         VkDevice device = srcImg->cmpInfo.device();
4456         auto* deviceInfo = android::base::find(mDeviceInfo, device);
4457         if (!deviceInfo) return;
4458 
4459         bool needEmulatedSrc = deviceInfo->needEmulatedDecompression(srcImg->cmpInfo);
4460         bool needEmulatedDst = deviceInfo->needEmulatedDecompression(dstImg->cmpInfo);
4461         if (!needEmulatedSrc && !needEmulatedDst) {
4462             vk->vkCmdCopyImage2KHR(commandBuffer, pCopyImageInfo);
4463             return;
4464         }
4465         VkImage srcImageMip = pCopyImageInfo->srcImage;
4466         VkImage dstImageMip = pCopyImageInfo->dstImage;
4467         for (uint32_t r = 0; r < pCopyImageInfo->regionCount; r++) {
4468             if (needEmulatedSrc) {
4469                 srcImageMip = srcImg->cmpInfo.compressedMipmap(pCopyImageInfo->pRegions[r].srcSubresource.mipLevel);
4470             }
4471             if (needEmulatedDst) {
4472                 dstImageMip = dstImg->cmpInfo.compressedMipmap(pCopyImageInfo->pRegions[r].dstSubresource.mipLevel);
4473             }
4474 
4475             VkCopyImageInfo2KHR inf2 = *pCopyImageInfo;
4476             inf2.regionCount = 1;
4477             inf2.srcImage = srcImageMip;
4478             inf2.dstImage = dstImageMip;
4479 
4480             VkImageCopy2KHR region = CompressedImageInfo::getCompressedMipmapsImageCopy(
4481                 pCopyImageInfo->pRegions[r], srcImg->cmpInfo, dstImg->cmpInfo, needEmulatedSrc, needEmulatedDst);
4482             inf2.pRegions = &region;
4483 
4484             vk->vkCmdCopyImage2KHR(commandBuffer, &inf2);
4485         }
4486     }
4487 
on_vkCmdCopyImageToBuffer2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,const VkCopyImageToBufferInfo2KHR * pCopyImageToBufferInfo)4488     void on_vkCmdCopyImageToBuffer2KHR(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4489                                        VkCommandBuffer boxed_commandBuffer,
4490                                        const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo) {
4491         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4492         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4493 
4494         std::lock_guard<std::mutex> lock(mMutex);
4495         auto* imageInfo = android::base::find(mImageInfo, pCopyImageToBufferInfo->srcImage);
4496         auto* bufferInfo = android::base::find(mBufferInfo, pCopyImageToBufferInfo->dstBuffer);
4497         if (!imageInfo || !bufferInfo) return;
4498         auto* deviceInfo = android::base::find(mDeviceInfo, bufferInfo->device);
4499         if (!deviceInfo) return;
4500         CompressedImageInfo& cmpInfo = imageInfo->cmpInfo;
4501         if (!deviceInfo->needEmulatedDecompression(cmpInfo)) {
4502             vk->vkCmdCopyImageToBuffer2KHR(commandBuffer, pCopyImageToBufferInfo);
4503             return;
4504         }
4505         for (uint32_t r = 0; r < pCopyImageToBufferInfo->regionCount; r++) {
4506             uint32_t mipLevel = pCopyImageToBufferInfo->pRegions[r].imageSubresource.mipLevel;
4507             VkBufferImageCopy2KHR region = cmpInfo.getBufferImageCopy(pCopyImageToBufferInfo->pRegions[r]);
4508             VkCopyImageToBufferInfo2KHR inf = *pCopyImageToBufferInfo;
4509             inf.regionCount = 1;
4510             inf.pRegions = &region;
4511             inf.srcImage = cmpInfo.compressedMipmap(mipLevel);
4512 
4513             vk->vkCmdCopyImageToBuffer2KHR(commandBuffer, &inf);
4514         }
4515     }
4516 
on_vkGetImageMemoryRequirements(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkImage image,VkMemoryRequirements * pMemoryRequirements)4517     void on_vkGetImageMemoryRequirements(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4518                                          VkDevice boxed_device, VkImage image,
4519                                          VkMemoryRequirements* pMemoryRequirements) {
4520         auto device = unbox_VkDevice(boxed_device);
4521         auto vk = dispatch_VkDevice(boxed_device);
4522         vk->vkGetImageMemoryRequirements(device, image, pMemoryRequirements);
4523         std::lock_guard<std::mutex> lock(mMutex);
4524         updateImageMemorySizeLocked(device, image, pMemoryRequirements);
4525 
4526         auto* physicalDevice = android::base::find(mDeviceToPhysicalDevice, device);
4527         if (!physicalDevice) {
4528             ERR("Failed to find physical device for device:%p", device);
4529             return;
4530         }
4531 
4532         auto* physicalDeviceInfo = android::base::find(mPhysdevInfo, *physicalDevice);
4533         if (!physicalDeviceInfo) {
4534             ERR("Failed to find physical device info for physical device:%p", *physicalDevice);
4535             return;
4536         }
4537 
4538         auto& physicalDeviceMemHelper = physicalDeviceInfo->memoryPropertiesHelper;
4539         physicalDeviceMemHelper->transformToGuestMemoryRequirements(pMemoryRequirements);
4540     }
4541 
on_vkGetImageMemoryRequirements2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)4542     void on_vkGetImageMemoryRequirements2(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4543                                           VkDevice boxed_device,
4544                                           const VkImageMemoryRequirementsInfo2* pInfo,
4545                                           VkMemoryRequirements2* pMemoryRequirements) {
4546         auto device = unbox_VkDevice(boxed_device);
4547         auto vk = dispatch_VkDevice(boxed_device);
4548 
4549         std::lock_guard<std::mutex> lock(mMutex);
4550 
4551         auto* physicalDevice = android::base::find(mDeviceToPhysicalDevice, device);
4552         if (!physicalDevice) {
4553             ERR("Failed to find physical device for device:%p", device);
4554             return;
4555         }
4556 
4557         auto* physicalDeviceInfo = android::base::find(mPhysdevInfo, *physicalDevice);
4558         if (!physicalDeviceInfo) {
4559             ERR("Failed to find physical device info for physical device:%p", *physicalDevice);
4560             return;
4561         }
4562 
4563         if ((physicalDeviceInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) &&
4564             vk->vkGetImageMemoryRequirements2) {
4565             vk->vkGetImageMemoryRequirements2(device, pInfo, pMemoryRequirements);
4566         } else if (hasDeviceExtension(device, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME)) {
4567             vk->vkGetImageMemoryRequirements2KHR(device, pInfo, pMemoryRequirements);
4568         } else {
4569             if (pInfo->pNext) {
4570                 ERR("Warning: trying to use extension struct in VkMemoryRequirements2 without "
4571                     "having enabled the extension!");
4572             }
4573 
4574             vk->vkGetImageMemoryRequirements(device, pInfo->image,
4575                                              &pMemoryRequirements->memoryRequirements);
4576         }
4577 
4578         updateImageMemorySizeLocked(device, pInfo->image, &pMemoryRequirements->memoryRequirements);
4579 
4580         auto& physicalDeviceMemHelper = physicalDeviceInfo->memoryPropertiesHelper;
4581         physicalDeviceMemHelper->transformToGuestMemoryRequirements(
4582             &pMemoryRequirements->memoryRequirements);
4583     }
4584 
on_vkGetBufferMemoryRequirements(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkBuffer buffer,VkMemoryRequirements * pMemoryRequirements)4585     void on_vkGetBufferMemoryRequirements(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4586                                           VkDevice boxed_device, VkBuffer buffer,
4587                                           VkMemoryRequirements* pMemoryRequirements) {
4588         auto device = unbox_VkDevice(boxed_device);
4589         auto vk = dispatch_VkDevice(boxed_device);
4590         vk->vkGetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
4591 
4592         std::lock_guard<std::mutex> lock(mMutex);
4593 
4594         auto* physicalDevice = android::base::find(mDeviceToPhysicalDevice, device);
4595         if (!physicalDevice) {
4596             GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
4597                 << "No physical device available for " << device;
4598         }
4599 
4600         auto* physicalDeviceInfo = android::base::find(mPhysdevInfo, *physicalDevice);
4601         if (!physicalDeviceInfo) {
4602             GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
4603                 << "No physical device info available for " << *physicalDevice;
4604         }
4605 
4606         auto& physicalDeviceMemHelper = physicalDeviceInfo->memoryPropertiesHelper;
4607         physicalDeviceMemHelper->transformToGuestMemoryRequirements(pMemoryRequirements);
4608     }
4609 
on_vkGetBufferMemoryRequirements2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkBufferMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)4610     void on_vkGetBufferMemoryRequirements2(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4611                                            VkDevice boxed_device,
4612                                            const VkBufferMemoryRequirementsInfo2* pInfo,
4613                                            VkMemoryRequirements2* pMemoryRequirements) {
4614         auto device = unbox_VkDevice(boxed_device);
4615         auto vk = dispatch_VkDevice(boxed_device);
4616 
4617         std::lock_guard<std::mutex> lock(mMutex);
4618 
4619         auto* physicalDevice = android::base::find(mDeviceToPhysicalDevice, device);
4620         if (!physicalDevice) {
4621             GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
4622                 << "No physical device available for " << device;
4623         }
4624 
4625         auto* physicalDeviceInfo = android::base::find(mPhysdevInfo, *physicalDevice);
4626         if (!physicalDeviceInfo) {
4627             GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
4628                 << "No physical device info available for " << *physicalDevice;
4629         }
4630 
4631         if ((physicalDeviceInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) &&
4632             vk->vkGetBufferMemoryRequirements2) {
4633             vk->vkGetBufferMemoryRequirements2(device, pInfo, pMemoryRequirements);
4634         } else if (hasDeviceExtension(device, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME)) {
4635             vk->vkGetBufferMemoryRequirements2KHR(device, pInfo, pMemoryRequirements);
4636         } else {
4637             if (pInfo->pNext) {
4638                 ERR("Warning: trying to use extension struct in VkMemoryRequirements2 without "
4639                     "having enabled the extension!");
4640             }
4641 
4642             vk->vkGetBufferMemoryRequirements(device, pInfo->buffer,
4643                                               &pMemoryRequirements->memoryRequirements);
4644         }
4645 
4646         auto& physicalDeviceMemHelper = physicalDeviceInfo->memoryPropertiesHelper;
4647         physicalDeviceMemHelper->transformToGuestMemoryRequirements(
4648             &pMemoryRequirements->memoryRequirements);
4649     }
4650 
on_vkCmdCopyBufferToImage(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,VkBuffer srcBuffer,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkBufferImageCopy * pRegions,const VkDecoderContext & context)4651     void on_vkCmdCopyBufferToImage(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4652                                    VkCommandBuffer boxed_commandBuffer, VkBuffer srcBuffer,
4653                                    VkImage dstImage, VkImageLayout dstImageLayout,
4654                                    uint32_t regionCount, const VkBufferImageCopy* pRegions,
4655                                    const VkDecoderContext& context) {
4656         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4657         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4658 
4659         std::lock_guard<std::mutex> lock(mMutex);
4660         auto* imageInfo = android::base::find(mImageInfo, dstImage);
4661         if (!imageInfo) return;
4662         auto* bufferInfo = android::base::find(mBufferInfo, srcBuffer);
4663         if (!bufferInfo) {
4664             return;
4665         }
4666         VkDevice device = bufferInfo->device;
4667         auto* deviceInfo = android::base::find(mDeviceInfo, device);
4668         if (!deviceInfo) {
4669             return;
4670         }
4671         if (!deviceInfo->needEmulatedDecompression(imageInfo->cmpInfo)) {
4672             vk->vkCmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout,
4673                                        regionCount, pRegions);
4674             return;
4675         }
4676         auto* cmdBufferInfo = android::base::find(mCommandBufferInfo, commandBuffer);
4677         if (!cmdBufferInfo) {
4678             return;
4679         }
4680         CompressedImageInfo& cmpInfo = imageInfo->cmpInfo;
4681 
4682         for (uint32_t r = 0; r < regionCount; r++) {
4683             uint32_t mipLevel = pRegions[r].imageSubresource.mipLevel;
4684             VkBufferImageCopy region = cmpInfo.getBufferImageCopy(pRegions[r]);
4685             vk->vkCmdCopyBufferToImage(commandBuffer, srcBuffer, cmpInfo.compressedMipmap(mipLevel),
4686                                        dstImageLayout, 1, &region);
4687         }
4688 
4689         if (cmpInfo.canDecompressOnCpu()) {
4690             // Get a pointer to the compressed image memory
4691             const MemoryInfo* memoryInfo = android::base::find(mMemoryInfo, bufferInfo->memory);
4692             if (!memoryInfo) {
4693                 WARN("ASTC CPU decompression: couldn't find mapped memory info");
4694                 return;
4695             }
4696             if (!memoryInfo->ptr) {
4697                 WARN("ASTC CPU decompression: VkBuffer memory isn't host-visible");
4698                 return;
4699             }
4700             uint8_t* astcData = (uint8_t*)(memoryInfo->ptr) + bufferInfo->memoryOffset;
4701             cmpInfo.decompressOnCpu(commandBuffer, astcData, bufferInfo->size, dstImage,
4702                                     dstImageLayout, regionCount, pRegions, context);
4703         }
4704     }
4705 
on_vkCmdCopyBufferToImage2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,const VkCopyBufferToImageInfo2 * pCopyBufferToImageInfo,const VkDecoderContext & context)4706     void on_vkCmdCopyBufferToImage2(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4707                                     VkCommandBuffer boxed_commandBuffer,
4708                                     const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo,
4709                                     const VkDecoderContext& context) {
4710         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4711         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4712 
4713         std::lock_guard<std::mutex> lock(mMutex);
4714         auto* imageInfo = android::base::find(mImageInfo, pCopyBufferToImageInfo->dstImage);
4715         if (!imageInfo) return;
4716         auto* bufferInfo = android::base::find(mBufferInfo, pCopyBufferToImageInfo->srcBuffer);
4717         if (!bufferInfo) {
4718             return;
4719         }
4720         VkDevice device = bufferInfo->device;
4721         auto* deviceInfo = android::base::find(mDeviceInfo, device);
4722         if (!deviceInfo) {
4723             return;
4724         }
4725         if (!deviceInfo->needEmulatedDecompression(imageInfo->cmpInfo)) {
4726             vk->vkCmdCopyBufferToImage2(commandBuffer, pCopyBufferToImageInfo);
4727             return;
4728         }
4729         auto* cmdBufferInfo = android::base::find(mCommandBufferInfo, commandBuffer);
4730         if (!cmdBufferInfo) {
4731             return;
4732         }
4733         CompressedImageInfo& cmpInfo = imageInfo->cmpInfo;
4734 
4735         for (uint32_t r = 0; r < pCopyBufferToImageInfo->regionCount; r++) {
4736             VkCopyBufferToImageInfo2 inf;
4737             uint32_t mipLevel = pCopyBufferToImageInfo->pRegions[r].imageSubresource.mipLevel;
4738             inf.dstImage = cmpInfo.compressedMipmap(mipLevel);
4739             VkBufferImageCopy2 region = cmpInfo.getBufferImageCopy(pCopyBufferToImageInfo->pRegions[r]);
4740             inf.regionCount = 1;
4741             inf.pRegions = &region;
4742 
4743             vk->vkCmdCopyBufferToImage2(commandBuffer, &inf);
4744         }
4745 
4746         if (cmpInfo.canDecompressOnCpu()) {
4747             // Get a pointer to the compressed image memory
4748             const MemoryInfo* memoryInfo = android::base::find(mMemoryInfo, bufferInfo->memory);
4749             if (!memoryInfo) {
4750                 WARN("ASTC CPU decompression: couldn't find mapped memory info");
4751                 return;
4752             }
4753             if (!memoryInfo->ptr) {
4754                 WARN("ASTC CPU decompression: VkBuffer memory isn't host-visible");
4755                 return;
4756             }
4757             uint8_t* astcData = (uint8_t*)(memoryInfo->ptr) + bufferInfo->memoryOffset;
4758 
4759             cmpInfo.decompressOnCpu(commandBuffer, astcData, bufferInfo->size, pCopyBufferToImageInfo, context);
4760         }
4761     }
4762 
on_vkCmdCopyBufferToImage2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,const VkCopyBufferToImageInfo2KHR * pCopyBufferToImageInfo,const VkDecoderContext & context)4763     void on_vkCmdCopyBufferToImage2KHR(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4764                                        VkCommandBuffer boxed_commandBuffer,
4765                                        const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo,
4766                                        const VkDecoderContext& context) {
4767         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4768         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4769 
4770         std::lock_guard<std::mutex> lock(mMutex);
4771         auto* imageInfo = android::base::find(mImageInfo, pCopyBufferToImageInfo->dstImage);
4772         if (!imageInfo) return;
4773         auto* bufferInfo = android::base::find(mBufferInfo, pCopyBufferToImageInfo->srcBuffer);
4774         if (!bufferInfo) {
4775             return;
4776         }
4777         VkDevice device = bufferInfo->device;
4778         auto* deviceInfo = android::base::find(mDeviceInfo, device);
4779         if (!deviceInfo) {
4780             return;
4781         }
4782         if (!deviceInfo->needEmulatedDecompression(imageInfo->cmpInfo)) {
4783             vk->vkCmdCopyBufferToImage2KHR(commandBuffer, pCopyBufferToImageInfo);
4784             return;
4785         }
4786         auto* cmdBufferInfo = android::base::find(mCommandBufferInfo, commandBuffer);
4787         if (!cmdBufferInfo) {
4788             return;
4789         }
4790         CompressedImageInfo& cmpInfo = imageInfo->cmpInfo;
4791 
4792         for (uint32_t r = 0; r < pCopyBufferToImageInfo->regionCount; r++) {
4793             VkCopyBufferToImageInfo2KHR inf;
4794             uint32_t mipLevel = pCopyBufferToImageInfo->pRegions[r].imageSubresource.mipLevel;
4795             inf.dstImage = cmpInfo.compressedMipmap(mipLevel);
4796             VkBufferImageCopy2KHR region = cmpInfo.getBufferImageCopy(pCopyBufferToImageInfo->pRegions[r]);
4797             inf.regionCount = 1;
4798             inf.pRegions = &region;
4799 
4800             vk->vkCmdCopyBufferToImage2KHR(commandBuffer, &inf);
4801         }
4802 
4803         if (cmpInfo.canDecompressOnCpu()) {
4804             // Get a pointer to the compressed image memory
4805             const MemoryInfo* memoryInfo = android::base::find(mMemoryInfo, bufferInfo->memory);
4806             if (!memoryInfo) {
4807                 WARN("ASTC CPU decompression: couldn't find mapped memory info");
4808                 return;
4809             }
4810             if (!memoryInfo->ptr) {
4811                 WARN("ASTC CPU decompression: VkBuffer memory isn't host-visible");
4812                 return;
4813             }
4814             uint8_t* astcData = (uint8_t*)(memoryInfo->ptr) + bufferInfo->memoryOffset;
4815 
4816             cmpInfo.decompressOnCpu(commandBuffer, astcData, bufferInfo->size, pCopyBufferToImageInfo, context);
4817         }
4818     }
4819 
convertQueueFamilyForeignToExternal(uint32_t * queueFamilyIndexPtr)4820     inline void convertQueueFamilyForeignToExternal(uint32_t* queueFamilyIndexPtr) {
4821         if (*queueFamilyIndexPtr == VK_QUEUE_FAMILY_FOREIGN_EXT) {
4822             *queueFamilyIndexPtr = VK_QUEUE_FAMILY_EXTERNAL;
4823         }
4824     }
4825 
convertQueueFamilyForeignToExternal_VkBufferMemoryBarrier(VkBufferMemoryBarrier * barrier)4826     inline void convertQueueFamilyForeignToExternal_VkBufferMemoryBarrier(
4827         VkBufferMemoryBarrier* barrier) {
4828         convertQueueFamilyForeignToExternal(&barrier->srcQueueFamilyIndex);
4829         convertQueueFamilyForeignToExternal(&barrier->dstQueueFamilyIndex);
4830     }
4831 
convertQueueFamilyForeignToExternal_VkImageMemoryBarrier(VkImageMemoryBarrier * barrier)4832     inline void convertQueueFamilyForeignToExternal_VkImageMemoryBarrier(
4833         VkImageMemoryBarrier* barrier) {
4834         convertQueueFamilyForeignToExternal(&barrier->srcQueueFamilyIndex);
4835         convertQueueFamilyForeignToExternal(&barrier->dstQueueFamilyIndex);
4836     }
4837 
getIMBImage(const VkImageMemoryBarrier & imb)4838     inline VkImage getIMBImage(const VkImageMemoryBarrier& imb) { return imb.image; }
getIMBImage(const VkImageMemoryBarrier2 & imb)4839     inline VkImage getIMBImage(const VkImageMemoryBarrier2& imb) { return imb.image; }
4840 
getIMBNewLayout(const VkImageMemoryBarrier & imb)4841     inline VkImageLayout getIMBNewLayout(const VkImageMemoryBarrier& imb) { return imb.newLayout; }
getIMBNewLayout(const VkImageMemoryBarrier2 & imb)4842     inline VkImageLayout getIMBNewLayout(const VkImageMemoryBarrier2& imb) { return imb.newLayout; }
4843 
getIMBSrcQueueFamilyIndex(const VkImageMemoryBarrier & imb)4844     inline uint32_t getIMBSrcQueueFamilyIndex(const VkImageMemoryBarrier& imb) {
4845         return imb.srcQueueFamilyIndex;
4846     }
getIMBSrcQueueFamilyIndex(const VkImageMemoryBarrier2 & imb)4847     inline uint32_t getIMBSrcQueueFamilyIndex(const VkImageMemoryBarrier2& imb) {
4848         return imb.srcQueueFamilyIndex;
4849     }
getIMBDstQueueFamilyIndex(const VkImageMemoryBarrier & imb)4850     inline uint32_t getIMBDstQueueFamilyIndex(const VkImageMemoryBarrier& imb) {
4851         return imb.dstQueueFamilyIndex;
4852     }
getIMBDstQueueFamilyIndex(const VkImageMemoryBarrier2 & imb)4853     inline uint32_t getIMBDstQueueFamilyIndex(const VkImageMemoryBarrier2& imb) {
4854         return imb.dstQueueFamilyIndex;
4855     }
4856 
4857     template <typename VkImageMemoryBarrierType>
processImageMemoryBarrierLocked(VkCommandBuffer commandBuffer,uint32_t imageMemoryBarrierCount,const VkImageMemoryBarrierType * pImageMemoryBarriers)4858     void processImageMemoryBarrierLocked(VkCommandBuffer commandBuffer,
4859                                          uint32_t imageMemoryBarrierCount,
4860                                          const VkImageMemoryBarrierType* pImageMemoryBarriers)
4861         REQUIRES(mMutex) {
4862         CommandBufferInfo* cmdBufferInfo = android::base::find(mCommandBufferInfo, commandBuffer);
4863         if (!cmdBufferInfo) return;
4864 
4865         // TODO: update image layout in ImageInfo
4866         for (uint32_t i = 0; i < imageMemoryBarrierCount; i++) {
4867             auto* imageInfo = android::base::find(mImageInfo, getIMBImage(pImageMemoryBarriers[i]));
4868             if (!imageInfo) {
4869                 continue;
4870             }
4871             cmdBufferInfo->imageLayouts[getIMBImage(pImageMemoryBarriers[i])] =
4872                 getIMBNewLayout(pImageMemoryBarriers[i]);
4873             if (!imageInfo->boundColorBuffer.has_value()) {
4874                 continue;
4875             }
4876             HandleType cb = imageInfo->boundColorBuffer.value();
4877             if (getIMBSrcQueueFamilyIndex(pImageMemoryBarriers[i]) == VK_QUEUE_FAMILY_EXTERNAL) {
4878                 cmdBufferInfo->acquiredColorBuffers.insert(cb);
4879             }
4880             if (getIMBDstQueueFamilyIndex(pImageMemoryBarriers[i]) == VK_QUEUE_FAMILY_EXTERNAL) {
4881                 cmdBufferInfo->releasedColorBuffers.insert(cb);
4882             }
4883             cmdBufferInfo->cbLayouts[cb] = getIMBNewLayout(pImageMemoryBarriers[i]);
4884         }
4885     }
4886 
on_vkCmdPipelineBarrier(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkDependencyFlags dependencyFlags,uint32_t memoryBarrierCount,const VkMemoryBarrier * pMemoryBarriers,uint32_t bufferMemoryBarrierCount,const VkBufferMemoryBarrier * pBufferMemoryBarriers,uint32_t imageMemoryBarrierCount,const VkImageMemoryBarrier * pImageMemoryBarriers)4887     void on_vkCmdPipelineBarrier(
4888         android::base::BumpPool* pool, VkSnapshotApiCallInfo*, VkCommandBuffer boxed_commandBuffer,
4889         VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
4890         VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount,
4891         const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount,
4892         const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
4893         const VkImageMemoryBarrier* pImageMemoryBarriers) {
4894         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4895         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4896 
4897         for (uint32_t i = 0; i < bufferMemoryBarrierCount; ++i) {
4898             convertQueueFamilyForeignToExternal_VkBufferMemoryBarrier(
4899                 ((VkBufferMemoryBarrier*)pBufferMemoryBarriers) + i);
4900         }
4901 
4902         for (uint32_t i = 0; i < imageMemoryBarrierCount; ++i) {
4903             convertQueueFamilyForeignToExternal_VkImageMemoryBarrier(
4904                 ((VkImageMemoryBarrier*)pImageMemoryBarriers) + i);
4905         }
4906 
4907         if (imageMemoryBarrierCount == 0) {
4908             vk->vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
4909                                      memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
4910                                      pBufferMemoryBarriers, imageMemoryBarrierCount,
4911                                      pImageMemoryBarriers);
4912             return;
4913         }
4914         std::lock_guard<std::mutex> lock(mMutex);
4915         CommandBufferInfo* cmdBufferInfo = android::base::find(mCommandBufferInfo, commandBuffer);
4916         if (!cmdBufferInfo) return;
4917 
4918         DeviceInfo* deviceInfo = android::base::find(mDeviceInfo, cmdBufferInfo->device);
4919         if (!deviceInfo) return;
4920 
4921         processImageMemoryBarrierLocked(commandBuffer, imageMemoryBarrierCount,
4922                                         pImageMemoryBarriers);
4923 
4924         if (!deviceInfo->emulateTextureEtc2 && !deviceInfo->emulateTextureAstc) {
4925             vk->vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
4926                                      memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
4927                                      pBufferMemoryBarriers, imageMemoryBarrierCount,
4928                                      pImageMemoryBarriers);
4929             return;
4930         }
4931 
4932         // This is a compressed image. Handle decompression before calling vkCmdPipelineBarrier
4933 
4934         std::vector<VkImageMemoryBarrier> imageBarriers;
4935         bool needRebind = false;
4936 
4937         for (uint32_t i = 0; i < imageMemoryBarrierCount; i++) {
4938             const VkImageMemoryBarrier& srcBarrier = pImageMemoryBarriers[i];
4939             auto* imageInfo = android::base::find(mImageInfo, srcBarrier.image);
4940 
4941             // If the image doesn't need GPU decompression, nothing to do.
4942             if (!imageInfo || !deviceInfo->needGpuDecompression(imageInfo->cmpInfo)) {
4943                 imageBarriers.push_back(srcBarrier);
4944                 continue;
4945             }
4946 
4947             // Otherwise, decompress the image, if we're going to read from it.
4948             needRebind |= imageInfo->cmpInfo.decompressIfNeeded(
4949                 vk, commandBuffer, srcStageMask, dstStageMask, srcBarrier, imageBarriers);
4950         }
4951 
4952         if (needRebind && cmdBufferInfo->computePipeline) {
4953             // Recover pipeline bindings
4954             // TODO(gregschlom): instead of doing this here again and again after each image we
4955             // decompress, could we do it once before calling vkCmdDispatch?
4956             vk->vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE,
4957                                   cmdBufferInfo->computePipeline);
4958             if (!cmdBufferInfo->currentDescriptorSets.empty()) {
4959                 vk->vkCmdBindDescriptorSets(
4960                     commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, cmdBufferInfo->descriptorLayout,
4961                     cmdBufferInfo->firstSet, cmdBufferInfo->currentDescriptorSets.size(),
4962                     cmdBufferInfo->currentDescriptorSets.data(),
4963                     cmdBufferInfo->dynamicOffsets.size(), cmdBufferInfo->dynamicOffsets.data());
4964             }
4965         }
4966 
4967         // Apply the remaining barriers
4968         if (memoryBarrierCount || bufferMemoryBarrierCount || !imageBarriers.empty()) {
4969             vk->vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
4970                                      memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
4971                                      pBufferMemoryBarriers, imageBarriers.size(),
4972                                      imageBarriers.data());
4973         }
4974     }
4975 
on_vkCmdPipelineBarrier2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,const VkDependencyInfo * pDependencyInfo)4976     void on_vkCmdPipelineBarrier2(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
4977                                   VkCommandBuffer boxed_commandBuffer,
4978                                   const VkDependencyInfo* pDependencyInfo) {
4979         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4980         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4981 
4982         for (uint32_t i = 0; i < pDependencyInfo->bufferMemoryBarrierCount; ++i) {
4983             convertQueueFamilyForeignToExternal_VkBufferMemoryBarrier(
4984                 ((VkBufferMemoryBarrier*)pDependencyInfo->pBufferMemoryBarriers) + i);
4985         }
4986 
4987         for (uint32_t i = 0; i < pDependencyInfo->imageMemoryBarrierCount; ++i) {
4988             convertQueueFamilyForeignToExternal_VkImageMemoryBarrier(
4989                 ((VkImageMemoryBarrier*)pDependencyInfo->pImageMemoryBarriers) + i);
4990         }
4991 
4992         std::lock_guard<std::mutex> lock(mMutex);
4993         CommandBufferInfo* cmdBufferInfo = android::base::find(mCommandBufferInfo, commandBuffer);
4994         if (!cmdBufferInfo) return;
4995 
4996         DeviceInfo* deviceInfo = android::base::find(mDeviceInfo, cmdBufferInfo->device);
4997         if (!deviceInfo) return;
4998 
4999         processImageMemoryBarrierLocked(commandBuffer, pDependencyInfo->imageMemoryBarrierCount,
5000                                         pDependencyInfo->pImageMemoryBarriers);
5001 
5002         // TODO: If this is a decompressed image, handle decompression before calling
5003         // VkCmdvkCmdPipelineBarrier2 i.e. match on_vkCmdPipelineBarrier implementation
5004         vk->vkCmdPipelineBarrier2(commandBuffer, pDependencyInfo);
5005     }
5006 
mapHostVisibleMemoryToGuestPhysicalAddressLocked(VulkanDispatch * vk,VkDevice device,VkDeviceMemory memory,uint64_t physAddr)5007     bool mapHostVisibleMemoryToGuestPhysicalAddressLocked(VulkanDispatch* vk, VkDevice device,
5008                                                           VkDeviceMemory memory, uint64_t physAddr)
5009         REQUIRES(mMutex) {
5010         if (!m_vkEmulation->getFeatures().GlDirectMem.enabled &&
5011             !m_vkEmulation->getFeatures().VirtioGpuNext.enabled) {
5012             // INFO("%s: Tried to use direct mapping "
5013             // "while GlDirectMem is not enabled!");
5014         }
5015 
5016         auto* info = android::base::find(mMemoryInfo, memory);
5017         if (!info) return false;
5018 
5019         info->guestPhysAddr = physAddr;
5020 
5021         constexpr size_t kPageBits = 12;
5022         constexpr size_t kPageSize = 1u << kPageBits;
5023         constexpr size_t kPageOffsetMask = kPageSize - 1;
5024 
5025         uintptr_t addr = reinterpret_cast<uintptr_t>(info->ptr);
5026         uintptr_t pageOffset = addr & kPageOffsetMask;
5027 
5028         info->pageAlignedHva = reinterpret_cast<void*>(addr - pageOffset);
5029         info->sizeToPage = ((info->size + pageOffset + kPageSize - 1) >> kPageBits) << kPageBits;
5030 
5031         if (mLogging) {
5032             INFO("%s: map: %p, %p -> [0x%llx 0x%llx]", __func__, info->ptr,
5033                     info->pageAlignedHva, (unsigned long long)info->guestPhysAddr,
5034                     (unsigned long long)info->guestPhysAddr + info->sizeToPage);
5035         }
5036 
5037         info->directMapped = true;
5038         uint64_t gpa = info->guestPhysAddr;
5039         void* hva = info->pageAlignedHva;
5040         size_t sizeToPage = info->sizeToPage;
5041 
5042         get_emugl_vm_operations().mapUserBackedRam(gpa, hva, sizeToPage);
5043 
5044         if (mVerbosePrints) {
5045             INFO("VERBOSE:%s: registering gpa 0x%llx", __func__,
5046                     (unsigned long long)gpa);
5047         }
5048 
5049         if (!mUseOldMemoryCleanupPath) {
5050             get_emugl_address_space_device_control_ops().register_deallocation_callback(
5051                 (void*)(new uint64_t(sizeToPage)), gpa, [](void* thisPtr, uint64_t gpa) {
5052                     uint64_t* sizePtr = (uint64_t*)thisPtr;
5053                     get_emugl_vm_operations().unmapUserBackedRam(gpa, *sizePtr);
5054                     delete sizePtr;
5055                 });
5056         }
5057 
5058         return true;
5059     }
5060 
5061     // Only call this from the address space device deallocation operation's
5062     // context, or it's possible that the guest/host view of which gpa's are
5063     // occupied goes out of sync.
unmapMemoryAtGpa(uint64_t gpa,uint64_t size)5064     void unmapMemoryAtGpa(uint64_t gpa, uint64_t size) {
5065         // DO NOT place any additional locks in here, as it may cause a deadlock due to mismatched
5066         // lock ordering, as VM operations will typically have its own mutex already.
5067         if (mVerbosePrints) {
5068             INFO("VERBOSE:%s: deallocation callback for gpa 0x%llx", __func__,
5069                     (unsigned long long)gpa);
5070         }
5071 
5072         // Just blindly unmap here. Let the VM implementation deal with invalid addresses.
5073         get_emugl_vm_operations().unmapUserBackedRam(gpa, size);
5074     }
5075 
on_vkAllocateMemory(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkMemoryAllocateInfo * pAllocateInfo,const VkAllocationCallbacks * pAllocator,VkDeviceMemory * pMemory)5076     VkResult on_vkAllocateMemory(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
5077                                  VkDevice boxed_device, const VkMemoryAllocateInfo* pAllocateInfo,
5078                                  const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory) {
5079         if (!pAllocateInfo) return VK_ERROR_INITIALIZATION_FAILED;
5080         auto device = unbox_VkDevice(boxed_device);
5081         auto vk = dispatch_VkDevice(boxed_device);
5082 
5083         VkMemoryAllocateInfo localAllocInfo = vk_make_orphan_copy(*pAllocateInfo);
5084         vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&localAllocInfo);
5085 
5086         VkMemoryAllocateFlagsInfo allocFlagsInfo;
5087         const VkMemoryAllocateFlagsInfo* allocFlagsInfoPtr =
5088             vk_find_struct<VkMemoryAllocateFlagsInfo>(pAllocateInfo);
5089         if (allocFlagsInfoPtr) {
5090             allocFlagsInfo = *allocFlagsInfoPtr;
5091             vk_append_struct(&structChainIter, &allocFlagsInfo);
5092         }
5093 
5094         VkMemoryOpaqueCaptureAddressAllocateInfo opaqueCaptureAddressAllocInfo;
5095         const VkMemoryOpaqueCaptureAddressAllocateInfo* opaqueCaptureAddressAllocInfoPtr =
5096             vk_find_struct<VkMemoryOpaqueCaptureAddressAllocateInfo>(pAllocateInfo);
5097         if (opaqueCaptureAddressAllocInfoPtr) {
5098             opaqueCaptureAddressAllocInfo = *opaqueCaptureAddressAllocInfoPtr;
5099             vk_append_struct(&structChainIter, &opaqueCaptureAddressAllocInfo);
5100         }
5101 
5102         const VkMemoryDedicatedAllocateInfo* dedicatedAllocInfoPtr =
5103             vk_find_struct<VkMemoryDedicatedAllocateInfo>(pAllocateInfo);
5104         VkMemoryDedicatedAllocateInfo localDedicatedAllocInfo = {};
5105 
5106         if (dedicatedAllocInfoPtr) {
5107             localDedicatedAllocInfo = vk_make_orphan_copy(*dedicatedAllocInfoPtr);
5108         }
5109         if (!usingDirectMapping()) {
5110             // We copy bytes 1 page at a time from the guest to the host
5111             // if we are not using direct mapping. This means we can end up
5112             // writing over memory we did not intend.
5113             // E.g. swiftshader just allocated with malloc, which can have
5114             // data stored between allocations.
5115         #ifdef PAGE_SIZE
5116             localAllocInfo.allocationSize += static_cast<VkDeviceSize>(PAGE_SIZE);
5117             localAllocInfo.allocationSize &= ~static_cast<VkDeviceSize>(PAGE_SIZE - 1);
5118         #elif defined(_WIN32)
5119             localAllocInfo.allocationSize += static_cast<VkDeviceSize>(4096);
5120             localAllocInfo.allocationSize &= ~static_cast<VkDeviceSize>(4095);
5121         #else
5122             localAllocInfo.allocationSize += static_cast<VkDeviceSize>(getpagesize());
5123             localAllocInfo.allocationSize &= ~static_cast<VkDeviceSize>(getpagesize() - 1);
5124         #endif
5125         }
5126         // Note for AHardwareBuffers, the Vulkan spec states:
5127         //
5128         //     Android hardware buffers have intrinsic width, height, format, and usage
5129         //     properties, so Vulkan images bound to memory imported from an Android
5130         //     hardware buffer must use dedicated allocations
5131         //
5132         // so any allocation requests with a VkImportAndroidHardwareBufferInfoANDROID
5133         // will necessarily have a VkMemoryDedicatedAllocateInfo. However, the host
5134         // may or may not actually use a dedicated allocations during Buffer/ColorBuffer
5135         // setup. Below checks if the underlying Buffer/ColorBuffer backing memory was
5136         // originally created with a dedicated allocation.
5137         bool shouldUseDedicatedAllocInfo = dedicatedAllocInfoPtr != nullptr;
5138 
5139         const VkImportColorBufferGOOGLE* importCbInfoPtr =
5140             vk_find_struct<VkImportColorBufferGOOGLE>(pAllocateInfo);
5141         const VkImportBufferGOOGLE* importBufferInfoPtr =
5142             vk_find_struct<VkImportBufferGOOGLE>(pAllocateInfo);
5143 
5144         const VkCreateBlobGOOGLE* createBlobInfoPtr =
5145             vk_find_struct<VkCreateBlobGOOGLE>(pAllocateInfo);
5146 
5147 #ifdef _WIN32
5148         VkImportMemoryWin32HandleInfoKHR importWin32HandleInfo{
5149             VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
5150             0,
5151             VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT,
5152             static_cast<HANDLE>(NULL),
5153             L"",
5154         };
5155 #else
5156 
5157 #if defined(__QNX__)
5158         VkImportScreenBufferInfoQNX importScreenBufferInfo{
5159             VK_STRUCTURE_TYPE_IMPORT_SCREEN_BUFFER_INFO_QNX,
5160             0,
5161             static_cast<screen_buffer_t>(NULL),
5162         };
5163 #elif defined(__APPLE__)
5164         VkImportMemoryMetalHandleInfoEXT importInfoMetalHandle = {
5165             VK_STRUCTURE_TYPE_IMPORT_MEMORY_METAL_HANDLE_INFO_EXT,
5166             0,
5167             VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLHEAP_BIT_EXT,
5168             nullptr,
5169         };
5170 #endif
5171 
5172         VkImportMemoryFdInfoKHR importFdInfo{
5173             VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
5174             0,
5175             VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
5176             -1,
5177         };
5178 #endif
5179 
5180         void* mappedPtr = nullptr;
5181         // If required by the platform, wrap the descriptor received from VkEmulation for
5182         // a ColorBuffer or Buffer import as a ManagedDescriptor, so it will be closed
5183         // appropriately when it goes out of scope.
5184         ManagedDescriptor managedHandle;
5185         if (importCbInfoPtr) {
5186             bool colorBufferMemoryUsesDedicatedAlloc = false;
5187             if (!m_vkEmulation->getColorBufferAllocationInfo(
5188                     importCbInfoPtr->colorBuffer, &localAllocInfo.allocationSize,
5189                     &localAllocInfo.memoryTypeIndex, &colorBufferMemoryUsesDedicatedAlloc,
5190                     &mappedPtr)) {
5191                 if (mSnapshotState != SnapshotState::Loading) {
5192                     GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
5193                         << "Failed to get allocation info for ColorBuffer:"
5194                         << importCbInfoPtr->colorBuffer;
5195                 }
5196                 // During snapshot load there could be invalidated references to
5197                 // color buffers.
5198                 // Here we just create a placeholder for it, as it is not suppoed
5199                 // to be used.
5200                 importCbInfoPtr = nullptr;
5201             } else {
5202                 shouldUseDedicatedAllocInfo &= colorBufferMemoryUsesDedicatedAlloc;
5203 
5204                 if (!m_vkEmulation->getFeatures().GuestVulkanOnly.enabled) {
5205                     m_vkEmulation->getCallbacks().invalidateColorBuffer(
5206                         importCbInfoPtr->colorBuffer);
5207                 }
5208 
5209                 bool opaqueFd = true;
5210 
5211 #if defined(__APPLE__)
5212                 // Use metal object extension on MoltenVK mode for color buffer import,
5213                 // non-moltenVK path on MacOS will use FD handles
5214                 if (m_vkEmulation->supportsMoltenVk()) {
5215                     if (dedicatedAllocInfoPtr == nullptr || localDedicatedAllocInfo.image == VK_NULL_HANDLE) {
5216                         // TODO(b/351765838): This should not happen, but somehow the guest
5217                         // is not providing us the necessary information for video rendering.
5218                         localDedicatedAllocInfo = {
5219                             .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
5220                             .pNext = nullptr,
5221                             .image =
5222                                 m_vkEmulation->getColorBufferVkImage(importCbInfoPtr->colorBuffer),
5223                             .buffer = VK_NULL_HANDLE,
5224                         };
5225 
5226                         shouldUseDedicatedAllocInfo = true;
5227                     }
5228 
5229                     MTLResource_id cbExtMemoryHandle =
5230                         m_vkEmulation->getColorBufferMetalMemoryHandle(
5231                             importCbInfoPtr->colorBuffer);
5232 
5233                     if (cbExtMemoryHandle == nullptr) {
5234                         fprintf(stderr,
5235                                 "%s: VK_ERROR_OUT_OF_DEVICE_MEMORY: "
5236                                 "colorBuffer 0x%x does not have Vulkan external memory backing\n",
5237                                 __func__, importCbInfoPtr->colorBuffer);
5238                         return VK_ERROR_OUT_OF_DEVICE_MEMORY;
5239                     }
5240                     importInfoMetalHandle.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLHEAP_BIT_EXT;
5241                     importInfoMetalHandle.handle = cbExtMemoryHandle;
5242 
5243                     vk_append_struct(&structChainIter, &importInfoMetalHandle);
5244                     opaqueFd = false;
5245                 }
5246 #endif
5247 
5248                 if (opaqueFd && m_vkEmulation->supportsExternalMemoryImport()) {
5249                     auto dupHandleInfo =
5250                         m_vkEmulation->dupColorBufferExtMemoryHandle(importCbInfoPtr->colorBuffer);
5251                     if (!dupHandleInfo) {
5252                         ERR("Failed to duplicate external memory handle/descriptor for ColorBuffer "
5253                             "object, with internal handle: %d",
5254                             importCbInfoPtr->colorBuffer);
5255                         return VK_ERROR_OUT_OF_DEVICE_MEMORY;
5256                     }
5257 #if defined(_WIN32)
5258                     // Wrap the dup'd handle in a ManagedDescriptor, and let it close the underlying
5259                     // HANDLE when it goes out of scope. From the VkImportMemoryWin32HandleInfoKHR
5260                     // spec: Importing memory object payloads from Windows handles does not transfer
5261                     // ownership of the handle to the Vulkan implementation. For handle types
5262                     // defined as NT handles, the application must release handle ownership using
5263                     // the CloseHandle system call when the handle is no longer needed. For handle
5264                     // types defined as NT handles, the imported memory object holds a reference to
5265                     // its payload
5266                     managedHandle = ManagedDescriptor(static_cast<DescriptorType>(
5267                         reinterpret_cast<void*>(dupHandleInfo->handle)));
5268                     importWin32HandleInfo.handle =
5269                         managedHandle.get().value_or(static_cast<HANDLE>(NULL));
5270                     vk_append_struct(&structChainIter, &importWin32HandleInfo);
5271 #elif defined(__QNX__)
5272                     if (STREAM_HANDLE_TYPE_PLATFORM_SCREEN_BUFFER_QNX ==
5273                         dupHandleInfo->streamHandleType) {
5274                         importScreenBufferInfo.buffer = static_cast<screen_buffer_t>(
5275                             reinterpret_cast<void*>(dupHandleInfo->handle));
5276                         vk_append_struct(&structChainIter, &importScreenBufferInfo);
5277                     } else {
5278                         // TODO(aruby@blackberry.com): Fall through to the importFdInfo sequence
5279                         // below to support non-screenbuffer external object imports on QNX?
5280                         ERR("Stream mem handleType: 0x%x not support for ColorBuffer import",
5281                             dupHandleInfo->streamHandleType);
5282                         return VK_ERROR_OUT_OF_DEVICE_MEMORY;
5283                     }
5284 #else
5285                     importFdInfo.fd = static_cast<int>(dupHandleInfo->handle);
5286                     vk_append_struct(&structChainIter, &importFdInfo);
5287 #endif
5288                 }
5289             }
5290         } else if (importBufferInfoPtr) {
5291             bool bufferMemoryUsesDedicatedAlloc = false;
5292             if (!m_vkEmulation->getBufferAllocationInfo(
5293                     importBufferInfoPtr->buffer, &localAllocInfo.allocationSize,
5294                     &localAllocInfo.memoryTypeIndex, &bufferMemoryUsesDedicatedAlloc)) {
5295                 ERR("Failed to get Buffer:%d allocation info.", importBufferInfoPtr->buffer);
5296                 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
5297             }
5298 
5299             shouldUseDedicatedAllocInfo &= bufferMemoryUsesDedicatedAlloc;
5300 
5301             bool opaqueFd = true;
5302 #ifdef __APPLE__
5303             if (m_vkEmulation->supportsMoltenVk()) {
5304                 MTLResource_id bufferMetalMemoryHandle =
5305                     m_vkEmulation->getBufferMetalMemoryHandle(importBufferInfoPtr->buffer);
5306 
5307                 if (bufferMetalMemoryHandle == nullptr) {
5308                     fprintf(stderr,
5309                             "%s: VK_ERROR_OUT_OF_DEVICE_MEMORY: "
5310                             "buffer 0x%x does not have Vulkan external memory "
5311                             "backing\n",
5312                             __func__, importBufferInfoPtr->buffer);
5313                     return VK_ERROR_OUT_OF_DEVICE_MEMORY;
5314                 }
5315 
5316                 importInfoMetalHandle.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLHEAP_BIT_EXT;
5317                 importInfoMetalHandle.handle = bufferMetalMemoryHandle;
5318 
5319                 vk_append_struct(&structChainIter, &importInfoMetalHandle);
5320 
5321                 opaqueFd = false;
5322             }
5323 #endif
5324 
5325             if (opaqueFd && m_vkEmulation->supportsExternalMemoryImport()) {
5326                 auto dupHandleInfo =
5327                     m_vkEmulation->dupBufferExtMemoryHandle(importBufferInfoPtr->buffer);
5328                 if (!dupHandleInfo) {
5329                     ERR("Failed to duplicate external memory handle/descriptor for Buffer object, "
5330                         "with internal handle: %d",
5331                         importBufferInfoPtr->buffer);
5332                     return VK_ERROR_OUT_OF_DEVICE_MEMORY;
5333                 }
5334 
5335 #if defined(_WIN32)
5336                 // Wrap the dup'd handle in a ManagedDescriptor, and let it close the underlying
5337                 // HANDLE when it goes out of scope. From the VkImportMemoryWin32HandleInfoKHR
5338                 // spec: Importing memory object payloads from Windows handles does not transfer
5339                 // ownership of the handle to the Vulkan implementation. For handle types defined
5340                 // as NT handles, the application must release handle ownership using the
5341                 // CloseHandle system call when the handle is no longer needed. For handle types
5342                 // defined as NT handles, the imported memory object holds a reference to its
5343                 // payload
5344                 managedHandle = ManagedDescriptor(
5345                     static_cast<DescriptorType>(reinterpret_cast<void*>(dupHandleInfo->handle)));
5346                 importWin32HandleInfo.handle =
5347                     managedHandle.get().value_or(static_cast<HANDLE>(NULL));
5348                 vk_append_struct(&structChainIter, &importWin32HandleInfo);
5349 #elif defined(__QNX__)
5350                 if (STREAM_HANDLE_TYPE_PLATFORM_SCREEN_BUFFER_QNX == dupHandleInfo->streamHandleType) {
5351                     importScreenBufferInfo.buffer = static_cast<screen_buffer_t>(
5352                         reinterpret_cast<void*>(dupHandleInfo->handle));
5353                     vk_append_struct(&structChainIter, &importScreenBufferInfo);
5354                 } else {
5355                     // TODO(aruby@blackberry.com): Fall through to the importFdInfo sequence below
5356                     // to support non-screenbuffer external object imports on QNX?
5357                     ERR("Stream mem handleType: 0x%x not support for Buffer object import",
5358                         dupHandleInfo->streamHandleType);
5359                     return VK_ERROR_OUT_OF_DEVICE_MEMORY;
5360                 }
5361 #else
5362                 importFdInfo.fd = static_cast<int>(dupHandleInfo->handle);
5363                 vk_append_struct(&structChainIter, &importFdInfo);
5364 #endif
5365             }
5366         }
5367 
5368         uint32_t virtioGpuContextId = 0;
5369         VkMemoryPropertyFlags memoryPropertyFlags;
5370 
5371         bool deviceHasDmabufExt = false;
5372 
5373         // Map guest memory index to host memory index and lookup memory properties:
5374         {
5375             std::lock_guard<std::mutex> lock(mMutex);
5376 
5377             auto* physicalDevice = android::base::find(mDeviceToPhysicalDevice, device);
5378             if (!physicalDevice) {
5379                 // User app gave an invalid VkDevice, but we don't really want to crash here.
5380                 // We should allow invalid apps.
5381                 return VK_ERROR_DEVICE_LOST;
5382             }
5383             auto* physicalDeviceInfo = android::base::find(mPhysdevInfo, *physicalDevice);
5384             if (!physicalDeviceInfo) {
5385                 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
5386                     << "No physical device info available for " << *physicalDevice;
5387             }
5388 
5389             deviceHasDmabufExt =
5390                 hasDeviceExtension(device, VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME);
5391 
5392             const auto hostMemoryInfoOpt =
5393                 physicalDeviceInfo->memoryPropertiesHelper
5394                     ->getHostMemoryInfoFromGuestMemoryTypeIndex(localAllocInfo.memoryTypeIndex);
5395             if (!hostMemoryInfoOpt) {
5396                 return VK_ERROR_INCOMPATIBLE_DRIVER;
5397             }
5398             const auto& hostMemoryInfo = *hostMemoryInfoOpt;
5399 
5400             localAllocInfo.memoryTypeIndex = hostMemoryInfo.index;
5401             memoryPropertyFlags = hostMemoryInfo.memoryType.propertyFlags;
5402 
5403             auto virtioGpuContextIdOpt = getContextIdForDeviceLocked(device);
5404             if (!virtioGpuContextIdOpt) {
5405                 ERR("VkDevice:%p missing context id for vkAllocateMemory().");
5406                 return VK_ERROR_DEVICE_LOST;
5407             }
5408             virtioGpuContextId = *virtioGpuContextIdOpt;
5409         }
5410 
5411         if (shouldUseDedicatedAllocInfo) {
5412             vk_append_struct(&structChainIter, &localDedicatedAllocInfo);
5413         }
5414 
5415         const bool hostVisible = memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
5416 
5417         if (createBlobInfoPtr && createBlobInfoPtr->blobMem == STREAM_BLOB_MEM_GUEST &&
5418             (createBlobInfoPtr->blobFlags & STREAM_BLOB_FLAG_CREATE_GUEST_HANDLE)) {
5419             DescriptorType rawDescriptor;
5420             auto descriptorInfoOpt = ExternalObjectManager::get()->removeBlobDescriptorInfo(
5421                 virtioGpuContextId, createBlobInfoPtr->blobId);
5422             if (descriptorInfoOpt) {
5423                 auto rawDescriptorOpt = (*descriptorInfoOpt).descriptorInfo.descriptor.release();
5424                 if (rawDescriptorOpt) {
5425                     rawDescriptor = *rawDescriptorOpt;
5426                 } else {
5427                     ERR("Failed vkAllocateMemory: missing raw descriptor.");
5428                     return VK_ERROR_OUT_OF_DEVICE_MEMORY;
5429                 }
5430             } else {
5431                 ERR("Failed vkAllocateMemory: missing descriptor info.");
5432                 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
5433             }
5434 
5435 #if defined(_WIN32)
5436             importWin32HandleInfo.handle = rawDescriptor;
5437             vk_append_struct(&structChainIter, &importWin32HandleInfo);
5438 #else
5439             importFdInfo.fd = rawDescriptor;
5440             if (m_vkEmulation->supportsDmaBuf() && deviceHasDmabufExt) {
5441                 importFdInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
5442             }
5443             vk_append_struct(&structChainIter, &importFdInfo);
5444 #endif
5445         }
5446 
5447         const bool isImport = importCbInfoPtr || importBufferInfoPtr;
5448         const bool isExport = !isImport;
5449 
5450         std::optional<VkImportMemoryHostPointerInfoEXT> importHostInfo;
5451         std::optional<VkExportMemoryAllocateInfo> exportAllocateInfo;
5452 
5453         std::optional<SharedMemory> sharedMemory = std::nullopt;
5454         std::shared_ptr<PrivateMemory> privateMemory = {};
5455 
5456         if (isExport && hostVisible) {
5457             if (m_vkEmulation->getFeatures().SystemBlob.enabled) {
5458                 // Ensure size is page-aligned.
5459                 VkDeviceSize alignedSize = __ALIGN(localAllocInfo.allocationSize, kPageSizeforBlob);
5460                 if (alignedSize != localAllocInfo.allocationSize) {
5461                     ERR("Warning: Aligning allocation size from %llu to %llu",
5462                         static_cast<unsigned long long>(localAllocInfo.allocationSize),
5463                         static_cast<unsigned long long>(alignedSize));
5464                 }
5465                 localAllocInfo.allocationSize = alignedSize;
5466 
5467                 static std::atomic<uint64_t> uniqueShmemId = 0;
5468                 sharedMemory = SharedMemory("shared-memory-vk-" + std::to_string(uniqueShmemId++),
5469                                             localAllocInfo.allocationSize);
5470                 int ret = sharedMemory->create(0600);
5471                 if (ret) {
5472                     ERR("Failed to create system-blob host-visible memory, error: %d", ret);
5473                     return VK_ERROR_OUT_OF_HOST_MEMORY;
5474                 }
5475                 mappedPtr = sharedMemory->get();
5476                 int mappedPtrAlignment = reinterpret_cast<uintptr_t>(mappedPtr) % kPageSizeforBlob;
5477                 if (mappedPtrAlignment != 0) {
5478                     ERR("Warning: Mapped shared memory pointer is not aligned to page size, "
5479                         "alignment "
5480                         "is: %d",
5481                         mappedPtrAlignment);
5482                 }
5483                 importHostInfo = {
5484                     .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
5485                     .pNext = NULL,
5486                     .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
5487                     .pHostPointer = mappedPtr,
5488                 };
5489                 vk_append_struct(&structChainIter, &*importHostInfo);
5490             } else if (m_vkEmulation->getFeatures().ExternalBlob.enabled) {
5491                 VkExternalMemoryHandleTypeFlags handleTypes;
5492 
5493 #if defined(__APPLE__)
5494                 if (m_vkEmulation->supportsMoltenVk()) {
5495                     // Using a different handle type when in MoltenVK mode
5496                     handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLHEAP_BIT_EXT;
5497                 } else {
5498                     handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
5499                 }
5500 #elif defined(_WIN32)
5501                 handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
5502 #elif defined(__unix__)
5503                 handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
5504 #endif
5505 
5506 #ifdef __linux__
5507                 if (m_vkEmulation->supportsDmaBuf() && deviceHasDmabufExt) {
5508                     handleTypes |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
5509                 }
5510 #endif
5511 
5512                 exportAllocateInfo = {
5513                     .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
5514                     .pNext = NULL,
5515                     .handleTypes = handleTypes,
5516                 };
5517                 vk_append_struct(&structChainIter, &*exportAllocateInfo);
5518             } else if (m_vkEmulation->getFeatures().VulkanAllocateHostMemory.enabled &&
5519                        localAllocInfo.pNext == nullptr) {
5520                 if (!m_vkEmulation || !m_vkEmulation->supportsExternalMemoryHostProperties()) {
5521                     ERR("VK_EXT_EXTERNAL_MEMORY_HOST is not supported, cannot use "
5522                         "VulkanAllocateHostMemory");
5523                     return VK_ERROR_INCOMPATIBLE_DRIVER;
5524                 }
5525                 VkDeviceSize alignmentSize =
5526                     m_vkEmulation->externalMemoryHostProperties().minImportedHostPointerAlignment;
5527                 VkDeviceSize alignedSize = __ALIGN(localAllocInfo.allocationSize, alignmentSize);
5528                 localAllocInfo.allocationSize = alignedSize;
5529                 privateMemory =
5530                     std::make_shared<PrivateMemory>(alignmentSize, localAllocInfo.allocationSize);
5531                 mappedPtr = privateMemory->getAddr();
5532                 importHostInfo = {
5533                     .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
5534                     .pNext = NULL,
5535                     .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
5536                     .pHostPointer = mappedPtr,
5537                 };
5538 
5539                 VkMemoryHostPointerPropertiesEXT memoryHostPointerProperties = {
5540                     .sType = VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT,
5541                     .pNext = NULL,
5542                     .memoryTypeBits = 0,
5543                 };
5544 
5545                 vk->vkGetMemoryHostPointerPropertiesEXT(
5546                     device, VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, mappedPtr,
5547                     &memoryHostPointerProperties);
5548 
5549                 if (memoryHostPointerProperties.memoryTypeBits == 0) {
5550                     ERR("Cannot find suitable memory type for VulkanAllocateHostMemory");
5551                     return VK_ERROR_INCOMPATIBLE_DRIVER;
5552                 }
5553 
5554                 if (((1u << localAllocInfo.memoryTypeIndex) &
5555                      memoryHostPointerProperties.memoryTypeBits) == 0) {
5556                     // TODO Consider assigning the correct memory index earlier, instead of
5557                     // switching right before allocation.
5558 
5559                     // Look for the first available supported memory index and assign it.
5560                     for (uint32_t i = 0; i <= 31; ++i) {
5561                         if ((memoryHostPointerProperties.memoryTypeBits & (1u << i)) == 0) {
5562                             continue;
5563                         }
5564                         localAllocInfo.memoryTypeIndex = i;
5565                         break;
5566                     }
5567                     VERBOSE(
5568                         "Detected memoryTypeIndex violation on requested host memory import. "
5569                         "Switching "
5570                         "to a supported memory index %d",
5571                         localAllocInfo.memoryTypeIndex);
5572                 }
5573 
5574                 vk_append_struct(&structChainIter, &*importHostInfo);
5575             }
5576         }
5577 
5578         VkResult result = vk->vkAllocateMemory(device, &localAllocInfo, pAllocator, pMemory);
5579         if (result != VK_SUCCESS) {
5580             return result;
5581         }
5582 
5583         std::lock_guard<std::mutex> lock(mMutex);
5584 
5585         VALIDATE_NEW_HANDLE_INFO_ENTRY(mMemoryInfo, *pMemory);
5586         mMemoryInfo[*pMemory] = MemoryInfo();
5587         auto& memoryInfo = mMemoryInfo[*pMemory];
5588         memoryInfo.size = localAllocInfo.allocationSize;
5589         memoryInfo.device = device;
5590         memoryInfo.memoryIndex = localAllocInfo.memoryTypeIndex;
5591 
5592         if (importCbInfoPtr) {
5593             memoryInfo.boundColorBuffer = importCbInfoPtr->colorBuffer;
5594         }
5595 
5596         if (!hostVisible) {
5597             *pMemory = new_boxed_non_dispatchable_VkDeviceMemory(*pMemory);
5598             return result;
5599         }
5600 
5601         if (memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
5602             memoryInfo.caching = MAP_CACHE_CACHED;
5603         } else if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD) {
5604             memoryInfo.caching = MAP_CACHE_UNCACHED;
5605         } else if (memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
5606             memoryInfo.caching = MAP_CACHE_WC;
5607         }
5608 
5609         auto* deviceInfo = android::base::find(mDeviceInfo, device);
5610         if (!deviceInfo) return VK_ERROR_OUT_OF_HOST_MEMORY;
5611 
5612         // If gfxstream needs to be able to read from this memory, needToMap should be true.
5613         // When external blobs are off, we always want to map HOST_VISIBLE memory. Because, we run
5614         // in the same process as the guest.
5615         // When external blobs are on, we want to map memory only if a workaround is using it in
5616         // the gfxstream process. This happens when ASTC CPU emulation is on.
5617         bool needToMap =
5618             (!m_vkEmulation->getFeatures().ExternalBlob.enabled ||
5619              (deviceInfo->useAstcCpuDecompression && deviceInfo->emulateTextureAstc)) &&
5620             !createBlobInfoPtr;
5621 
5622         // Some cases provide a mappedPtr, so we only map if we still don't have a pointer here.
5623         if (!mappedPtr && needToMap) {
5624             memoryInfo.needUnmap = true;
5625             VkResult mapResult =
5626                 vk->vkMapMemory(device, *pMemory, 0, memoryInfo.size, 0, &memoryInfo.ptr);
5627             if (mapResult != VK_SUCCESS) {
5628                 freeMemoryLocked(device, vk, *pMemory, pAllocator);
5629                 *pMemory = VK_NULL_HANDLE;
5630                 return VK_ERROR_OUT_OF_HOST_MEMORY;
5631             }
5632         } else {
5633             // Since we didn't call vkMapMemory, unmapping is not needed (don't own mappedPtr).
5634             memoryInfo.needUnmap = false;
5635             memoryInfo.ptr = mappedPtr;
5636 
5637             if (createBlobInfoPtr) {
5638                 memoryInfo.blobId = createBlobInfoPtr->blobId;
5639             }
5640 
5641             // Always assign the shared memory into memoryInfo. If it was used, then it will have
5642             // ownership transferred.
5643             memoryInfo.sharedMemory = std::exchange(sharedMemory, std::nullopt);
5644 
5645             memoryInfo.privateMemory = privateMemory;
5646         }
5647 
5648         *pMemory = new_boxed_non_dispatchable_VkDeviceMemory(*pMemory);
5649 
5650         return result;
5651     }
5652 
destroyMemoryWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkDeviceMemory memory,MemoryInfo & memoryInfo,const VkAllocationCallbacks * pAllocator)5653     void destroyMemoryWithExclusiveInfo(VkDevice device, VulkanDispatch* deviceDispatch,
5654                                         VkDeviceMemory memory, MemoryInfo& memoryInfo,
5655                                         const VkAllocationCallbacks* pAllocator) {
5656         if (memoryInfo.directMapped) {
5657             // if direct mapped, we leave it up to the guest address space driver
5658             // to control the unmapping of kvm slot on the host side
5659             // in order to avoid situations where
5660             //
5661             // 1. we try to unmap here and deadlock
5662             //
5663             // 2. unmapping at the wrong time (possibility of a parallel call
5664             // to unmap vs. address space allocate and mapMemory leading to
5665             // mapping the same gpa twice)
5666             if (mUseOldMemoryCleanupPath) {
5667                 unmapMemoryAtGpa(memoryInfo.guestPhysAddr, memoryInfo.sizeToPage);
5668             }
5669         }
5670 
5671         if (memoryInfo.needUnmap && memoryInfo.ptr) {
5672             deviceDispatch->vkUnmapMemory(device, memory);
5673         }
5674 
5675         deviceDispatch->vkFreeMemory(device, memory, pAllocator);
5676     }
5677 
freeMemoryLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkDeviceMemory memory,const VkAllocationCallbacks * pAllocator)5678     void freeMemoryLocked(VkDevice device, VulkanDispatch* deviceDispatch, VkDeviceMemory memory,
5679                           const VkAllocationCallbacks* pAllocator) REQUIRES(mMutex) {
5680         auto memoryInfoIt = mMemoryInfo.find(memory);
5681         if (memoryInfoIt == mMemoryInfo.end()) return;
5682         auto& memoryInfo = memoryInfoIt->second;
5683 
5684         destroyMemoryWithExclusiveInfo(device, deviceDispatch, memory, memoryInfo, pAllocator);
5685 
5686         mMemoryInfo.erase(memoryInfoIt);
5687     }
5688 
on_vkFreeMemory(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkDeviceMemory memory,const VkAllocationCallbacks * pAllocator)5689     void on_vkFreeMemory(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
5690                          VkDevice boxed_device, VkDeviceMemory memory,
5691                          const VkAllocationCallbacks* pAllocator) {
5692         auto device = unbox_VkDevice(boxed_device);
5693         auto deviceDispatch = dispatch_VkDevice(boxed_device);
5694         if (!device || !deviceDispatch) return;
5695 
5696         std::lock_guard<std::mutex> lock(mMutex);
5697         freeMemoryLocked(device, deviceDispatch, memory, pAllocator);
5698     }
5699 
on_vkMapMemory(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice,VkDeviceMemory memory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)5700     VkResult on_vkMapMemory(android::base::BumpPool* pool, VkSnapshotApiCallInfo*, VkDevice,
5701                             VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size,
5702                             VkMemoryMapFlags flags, void** ppData) {
5703         std::lock_guard<std::mutex> lock(mMutex);
5704         return on_vkMapMemoryLocked(0, memory, offset, size, flags, ppData);
5705     }
on_vkMapMemoryLocked(VkDevice,VkDeviceMemory memory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)5706     VkResult on_vkMapMemoryLocked(VkDevice, VkDeviceMemory memory, VkDeviceSize offset,
5707                                   VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
5708         REQUIRES(mMutex) {
5709         auto* info = android::base::find(mMemoryInfo, memory);
5710         if (!info || !info->ptr) return VK_ERROR_MEMORY_MAP_FAILED;  // Invalid usage.
5711 
5712         *ppData = (void*)((uint8_t*)info->ptr + offset);
5713         return VK_SUCCESS;
5714     }
5715 
on_vkUnmapMemory(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice,VkDeviceMemory)5716     void on_vkUnmapMemory(android::base::BumpPool* pool, VkSnapshotApiCallInfo*, VkDevice,
5717                           VkDeviceMemory) {
5718         // no-op; user-level mapping does not correspond
5719         // to any operation here.
5720     }
5721 
getMappedHostPointer(VkDeviceMemory memory)5722     uint8_t* getMappedHostPointer(VkDeviceMemory memory) {
5723         std::lock_guard<std::mutex> lock(mMutex);
5724 
5725         auto* info = android::base::find(mMemoryInfo, memory);
5726         if (!info) return nullptr;
5727 
5728         return (uint8_t*)(info->ptr);
5729     }
5730 
getDeviceMemorySize(VkDeviceMemory memory)5731     VkDeviceSize getDeviceMemorySize(VkDeviceMemory memory) {
5732         std::lock_guard<std::mutex> lock(mMutex);
5733 
5734         auto* info = android::base::find(mMemoryInfo, memory);
5735         if (!info) return 0;
5736 
5737         return info->size;
5738     }
5739 
usingDirectMapping() const5740     bool usingDirectMapping() const {
5741         return m_vkEmulation->getFeatures().GlDirectMem.enabled ||
5742                m_vkEmulation->getFeatures().VirtioGpuNext.enabled;
5743     }
5744 
getHostFeatureSupport() const5745     HostFeatureSupport getHostFeatureSupport() const {
5746         HostFeatureSupport res;
5747 
5748         if (!m_vk) return res;
5749 
5750         res.supportsVulkan = m_vkEmulation != nullptr;
5751 
5752         if (!res.supportsVulkan) return res;
5753 
5754         const auto& props = m_vkEmulation->getPhysicalDeviceProperties();
5755 
5756         res.supportsVulkan1_1 = props.apiVersion >= VK_API_VERSION_1_1;
5757         res.useDeferredCommands = m_vkEmulation->deferredCommandsEnabled();
5758         res.useCreateResourcesWithRequirements =
5759             m_vkEmulation->createResourcesWithRequirementsEnabled();
5760 
5761         res.apiVersion = props.apiVersion;
5762         res.driverVersion = props.driverVersion;
5763         res.deviceID = props.deviceID;
5764         res.vendorID = props.vendorID;
5765         return res;
5766     }
5767 
hasInstanceExtension(VkInstance instance,const std::string & name)5768     bool hasInstanceExtension(VkInstance instance, const std::string& name) REQUIRES(mMutex) {
5769         auto* info = android::base::find(mInstanceInfo, instance);
5770         if (!info) return false;
5771 
5772         for (const auto& enabledName : info->enabledExtensionNames) {
5773             if (name == enabledName) return true;
5774         }
5775 
5776         return false;
5777     }
5778 
hasDeviceExtension(VkDevice device,const std::string & name)5779     bool hasDeviceExtension(VkDevice device, const std::string& name) REQUIRES(mMutex) {
5780         auto* info = android::base::find(mDeviceInfo, device);
5781         if (!info) return false;
5782 
5783         for (const auto& enabledName : info->enabledExtensionNames) {
5784             if (name == enabledName) return true;
5785         }
5786 
5787         return false;
5788     }
5789 
5790     // Returns whether a vector of VkExtensionProperties contains a particular extension
hasDeviceExtension(const std::vector<VkExtensionProperties> & properties,const char * name)5791     bool hasDeviceExtension(const std::vector<VkExtensionProperties>& properties,
5792                             const char* name) {
5793         for (const auto& prop : properties) {
5794             if (strcmp(prop.extensionName, name) == 0) return true;
5795         }
5796         return false;
5797     }
5798 
5799     // Convenience function to call vkEnumerateDeviceExtensionProperties and get the results as an
5800     // std::vector
enumerateDeviceExtensionProperties(VulkanDispatch * vk,VkPhysicalDevice physicalDevice,const char * pLayerName,std::vector<VkExtensionProperties> & properties)5801     VkResult enumerateDeviceExtensionProperties(VulkanDispatch* vk, VkPhysicalDevice physicalDevice,
5802                                                 const char* pLayerName,
5803                                                 std::vector<VkExtensionProperties>& properties) {
5804         uint32_t propertyCount = 0;
5805         VkResult result = vk->vkEnumerateDeviceExtensionProperties(physicalDevice, pLayerName,
5806                                                                    &propertyCount, nullptr);
5807         if (result != VK_SUCCESS) return result;
5808 
5809         properties.resize(propertyCount);
5810         return vk->vkEnumerateDeviceExtensionProperties(physicalDevice, pLayerName, &propertyCount,
5811                                                         properties.data());
5812     }
5813 
5814     // VK_ANDROID_native_buffer
on_vkGetSwapchainGrallocUsageANDROID(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice,VkFormat format,VkImageUsageFlags imageUsage,int * grallocUsage)5815     VkResult on_vkGetSwapchainGrallocUsageANDROID(android::base::BumpPool* pool,
5816                                                   VkSnapshotApiCallInfo*, VkDevice, VkFormat format,
5817                                                   VkImageUsageFlags imageUsage, int* grallocUsage) {
5818         getGralloc0Usage(format, imageUsage, grallocUsage);
5819         return VK_SUCCESS;
5820     }
5821 
on_vkGetSwapchainGrallocUsage2ANDROID(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice,VkFormat format,VkImageUsageFlags imageUsage,VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,uint64_t * grallocConsumerUsage,uint64_t * grallocProducerUsage)5822     VkResult on_vkGetSwapchainGrallocUsage2ANDROID(
5823         android::base::BumpPool* pool, VkSnapshotApiCallInfo*, VkDevice, VkFormat format,
5824         VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
5825         uint64_t* grallocConsumerUsage, uint64_t* grallocProducerUsage) {
5826         getGralloc1Usage(format, imageUsage, swapchainImageUsage, grallocConsumerUsage,
5827                          grallocProducerUsage);
5828         return VK_SUCCESS;
5829     }
5830 
on_vkAcquireImageANDROID(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkImage image,int nativeFenceFd,VkSemaphore semaphore,VkFence fence)5831     VkResult on_vkAcquireImageANDROID(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
5832                                       VkDevice boxed_device, VkImage image, int nativeFenceFd,
5833                                       VkSemaphore semaphore, VkFence fence) {
5834         auto device = unbox_VkDevice(boxed_device);
5835         auto vk = dispatch_VkDevice(boxed_device);
5836 
5837         std::lock_guard<std::mutex> lock(mMutex);
5838 
5839         auto* deviceInfo = android::base::find(mDeviceInfo, device);
5840         if (!deviceInfo) return VK_ERROR_INITIALIZATION_FAILED;
5841 
5842         auto* imageInfo = android::base::find(mImageInfo, image);
5843         if (!imageInfo) return VK_ERROR_INITIALIZATION_FAILED;
5844 
5845         VkQueue defaultQueue;
5846         uint32_t defaultQueueFamilyIndex;
5847         std::mutex* defaultQueueMutex;
5848         if (!getDefaultQueueForDeviceLocked(device, &defaultQueue, &defaultQueueFamilyIndex,
5849                                             &defaultQueueMutex)) {
5850             INFO("%s: can't get the default q", __func__);
5851             return VK_ERROR_INITIALIZATION_FAILED;
5852         }
5853 
5854         DeviceOpBuilder builder(*deviceInfo->deviceOpTracker);
5855 
5856         VkFence usedFence = fence;
5857         if (usedFence == VK_NULL_HANDLE) {
5858             usedFence = builder.CreateFenceForOp();
5859         }
5860 
5861         AndroidNativeBufferInfo* anbInfo = imageInfo->anbInfo.get();
5862 
5863         VkResult result =
5864             anbInfo->on_vkAcquireImageANDROID(m_vkEmulation, vk, device, defaultQueue, defaultQueueFamilyIndex,
5865                                               defaultQueueMutex, semaphore, usedFence);
5866         if (result != VK_SUCCESS) {
5867             return result;
5868         }
5869 
5870         DeviceOpWaitable aniCompletedWaitable = builder.OnQueueSubmittedWithFence(usedFence);
5871 
5872         if (semaphore != VK_NULL_HANDLE) {
5873             auto semaphoreInfo = android::base::find(mSemaphoreInfo, semaphore);
5874             if (semaphoreInfo != nullptr) {
5875                 semaphoreInfo->latestUse = aniCompletedWaitable;
5876             }
5877         }
5878         if (fence != VK_NULL_HANDLE) {
5879             auto fenceInfo = android::base::find(mFenceInfo, fence);
5880             if (fenceInfo != nullptr) {
5881                 fenceInfo->latestUse = aniCompletedWaitable;
5882             }
5883         }
5884 
5885         deviceInfo->deviceOpTracker->PollAndProcessGarbage();
5886 
5887         return VK_SUCCESS;
5888     }
5889 
on_vkQueueSignalReleaseImageANDROID(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkQueue boxed_queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image,int * pNativeFenceFd)5890     VkResult on_vkQueueSignalReleaseImageANDROID(android::base::BumpPool* pool,
5891                                                  VkSnapshotApiCallInfo*, VkQueue boxed_queue,
5892                                                  uint32_t waitSemaphoreCount,
5893                                                  const VkSemaphore* pWaitSemaphores, VkImage image,
5894                                                  int* pNativeFenceFd) {
5895         auto queue = unbox_VkQueue(boxed_queue);
5896         auto vk = dispatch_VkQueue(boxed_queue);
5897 
5898         std::lock_guard<std::mutex> lock(mMutex);
5899 
5900         auto* queueInfo = android::base::find(mQueueInfo, queue);
5901         if (!queueInfo) return VK_ERROR_INITIALIZATION_FAILED;
5902 
5903         if (mRenderDocWithMultipleVkInstances) {
5904             VkPhysicalDevice vkPhysicalDevice = mDeviceToPhysicalDevice.at(queueInfo->device);
5905             VkInstance vkInstance = mPhysicalDeviceToInstance.at(vkPhysicalDevice);
5906             mRenderDocWithMultipleVkInstances->onFrameDelimiter(vkInstance);
5907         }
5908 
5909         auto* imageInfo = android::base::find(mImageInfo, image);
5910         if (!imageInfo) return VK_ERROR_INITIALIZATION_FAILED;
5911 
5912         auto* anbInfo = imageInfo->anbInfo.get();
5913         if (anbInfo->isUsingNativeImage()) {
5914             // vkQueueSignalReleaseImageANDROID() is only called by the Android framework's
5915             // implementation of vkQueuePresentKHR(). The guest application is responsible for
5916             // transitioning the image layout of the image passed to vkQueuePresentKHR() to
5917             // VK_IMAGE_LAYOUT_PRESENT_SRC_KHR before the call. If the host is using native
5918             // Vulkan images where `image` is backed with the same memory as its ColorBuffer,
5919             // then we need to update the tracked layout for that ColorBuffer.
5920             m_vkEmulation->setColorBufferCurrentLayout(anbInfo->getColorBufferHandle(),
5921                                         VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
5922         }
5923 
5924         return anbInfo->on_vkQueueSignalReleaseImageANDROID(
5925             m_vkEmulation, vk, queueInfo->queueFamilyIndex, queue, queueInfo->queueMutex.get(),
5926             waitSemaphoreCount, pWaitSemaphores, pNativeFenceFd);
5927     }
5928 
on_vkMapMemoryIntoAddressSpaceGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkDeviceMemory memory,uint64_t * pAddress)5929     VkResult on_vkMapMemoryIntoAddressSpaceGOOGLE(android::base::BumpPool* pool,
5930                                                   VkSnapshotApiCallInfo*, VkDevice boxed_device,
5931                                                   VkDeviceMemory memory, uint64_t* pAddress) {
5932         auto device = unbox_VkDevice(boxed_device);
5933         auto vk = dispatch_VkDevice(boxed_device);
5934 
5935         if (!m_vkEmulation->getFeatures().GlDirectMem.enabled) {
5936             fprintf(stderr,
5937                     "FATAL: Tried to use direct mapping "
5938                     "while GlDirectMem is not enabled!\n");
5939         }
5940 
5941         std::lock_guard<std::mutex> lock(mMutex);
5942 
5943         if (mLogging) {
5944             INFO("%s: deviceMemory: 0x%llx pAddress: 0x%llx", __func__,
5945                     (unsigned long long)memory, (unsigned long long)(*pAddress));
5946         }
5947 
5948         if (!mapHostVisibleMemoryToGuestPhysicalAddressLocked(vk, device, memory, *pAddress)) {
5949             return VK_ERROR_OUT_OF_HOST_MEMORY;
5950         }
5951 
5952         auto* info = android::base::find(mMemoryInfo, memory);
5953         if (!info) return VK_ERROR_INITIALIZATION_FAILED;
5954 
5955         *pAddress = (uint64_t)(uintptr_t)info->ptr;
5956 
5957         return VK_SUCCESS;
5958     }
5959 
vkGetBlobInternal(VkDevice boxed_device,VkDeviceMemory memory,uint64_t hostBlobId)5960     VkResult vkGetBlobInternal(VkDevice boxed_device, VkDeviceMemory memory, uint64_t hostBlobId) {
5961         auto device = unbox_VkDevice(boxed_device);
5962         auto vk = dispatch_VkDevice(boxed_device);
5963 
5964         std::lock_guard<std::mutex> lock(mMutex);
5965 
5966         auto virtioGpuContextIdOpt = getContextIdForDeviceLocked(device);
5967         if (!virtioGpuContextIdOpt) {
5968             ERR("VkDevice:%p missing context id for vkAllocateMemory().");
5969             return VK_ERROR_OUT_OF_HOST_MEMORY;
5970         }
5971         const uint32_t virtioGpuContextId = *virtioGpuContextIdOpt;
5972 
5973         auto* info = android::base::find(mMemoryInfo, memory);
5974         if (!info) return VK_ERROR_OUT_OF_HOST_MEMORY;
5975 
5976         hostBlobId = (info->blobId && !hostBlobId) ? info->blobId : hostBlobId;
5977 
5978         if (m_vkEmulation->getFeatures().SystemBlob.enabled && info->sharedMemory.has_value()) {
5979             // We transfer ownership of the shared memory handle to the descriptor info.
5980             // The memory itself is destroyed only when all processes unmap / release their
5981             // handles.
5982             ExternalObjectManager::get()->addBlobDescriptorInfo(
5983                 virtioGpuContextId, hostBlobId, info->sharedMemory->releaseHandle(),
5984                 STREAM_HANDLE_TYPE_MEM_SHM, info->caching, std::nullopt);
5985         } else if (m_vkEmulation->getFeatures().ExternalBlob.enabled) {
5986 #ifdef __APPLE__
5987             if (m_vkEmulation->supportsMoltenVk()) {
5988                 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
5989                     << "ExternalBlob feature is not supported with MoltenVK";
5990             }
5991 #endif
5992 
5993             struct VulkanInfo vulkanInfo = {
5994                 .memoryIndex = info->memoryIndex,
5995             };
5996 
5997             auto deviceUuidOpt = m_vkEmulation->getDeviceUuid();
5998             if (deviceUuidOpt) {
5999                 memcpy(vulkanInfo.deviceUUID, deviceUuidOpt->data(), sizeof(vulkanInfo.deviceUUID));
6000             }
6001             auto driverUuidOpt = m_vkEmulation->getDriverUuid();
6002             if (driverUuidOpt) {
6003                 memcpy(vulkanInfo.driverUUID, driverUuidOpt->data(), sizeof(vulkanInfo.driverUUID));
6004             }
6005 
6006             if (snapshotsEnabled()) {
6007                 VkResult mapResult = vk->vkMapMemory(device, memory, 0, info->size, 0, &info->ptr);
6008                 if (mapResult != VK_SUCCESS) {
6009                     return VK_ERROR_OUT_OF_HOST_MEMORY;
6010                 }
6011 
6012                 info->needUnmap = true;
6013             }
6014 
6015             auto exportedMemoryOpt = m_vkEmulation->exportMemoryHandle(device, memory);
6016             if (!exportedMemoryOpt) {
6017                 return VK_ERROR_OUT_OF_HOST_MEMORY;
6018             }
6019             auto& exportedMemory = *exportedMemoryOpt;
6020             ExternalObjectManager::get()->addBlobDescriptorInfo(
6021                 virtioGpuContextId, hostBlobId, std::move(exportedMemory.descriptor),
6022                 exportedMemory.streamHandleType, info->caching,
6023                 std::optional<VulkanInfo>(vulkanInfo));
6024         } else if (!info->needUnmap) {
6025             VkResult mapResult = vk->vkMapMemory(device, memory, 0, info->size, 0, &info->ptr);
6026             if (mapResult != VK_SUCCESS) {
6027                 return VK_ERROR_OUT_OF_HOST_MEMORY;
6028             }
6029 
6030             info->needUnmap = true;
6031         }
6032 
6033         if (info->needUnmap) {
6034             uint64_t hva = (uint64_t)(uintptr_t)(info->ptr);
6035             uint64_t alignedHva = hva & kPageMaskForBlob;
6036 
6037             if (hva != alignedHva) {
6038                 ERR("Mapping non page-size (0x%" PRIx64
6039                     ") aligned host virtual address:%p "
6040                     "using the aligned host virtual address:%p. The underlying resources "
6041                     "using this blob may be corrupted/offset.",
6042                     kPageSizeforBlob, hva, alignedHva);
6043             }
6044             ExternalObjectManager::get()->addMapping(virtioGpuContextId, hostBlobId,
6045                                                      (void*)(uintptr_t)alignedHva, info->caching);
6046             info->virtioGpuMapped = true;
6047             info->hostmemId = hostBlobId;
6048         }
6049 
6050         return VK_SUCCESS;
6051     }
6052 
on_vkGetBlobGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkDeviceMemory memory)6053     VkResult on_vkGetBlobGOOGLE(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6054                                 VkDevice boxed_device, VkDeviceMemory memory) {
6055         return vkGetBlobInternal(boxed_device, memory, 0);
6056     }
6057 
on_vkGetMemoryHostAddressInfoGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkDeviceMemory memory,uint64_t * pAddress,uint64_t * pSize,uint64_t * pHostmemId)6058     VkResult on_vkGetMemoryHostAddressInfoGOOGLE(android::base::BumpPool* pool,
6059                                                  VkSnapshotApiCallInfo*, VkDevice boxed_device,
6060                                                  VkDeviceMemory memory, uint64_t* pAddress,
6061                                                  uint64_t* pSize, uint64_t* pHostmemId) {
6062         uint64_t hostBlobId = sNextHostBlobId++;
6063         *pHostmemId = hostBlobId;
6064         return vkGetBlobInternal(boxed_device, memory, hostBlobId);
6065     }
6066 
on_vkFreeMemorySyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkDeviceMemory memory,const VkAllocationCallbacks * pAllocator)6067     VkResult on_vkFreeMemorySyncGOOGLE(android::base::BumpPool* pool,
6068                                        VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
6069                                        VkDeviceMemory memory,
6070                                        const VkAllocationCallbacks* pAllocator) {
6071         on_vkFreeMemory(pool, snapshotInfo, boxed_device, memory, pAllocator);
6072 
6073         return VK_SUCCESS;
6074     }
6075 
on_vkAllocateCommandBuffers(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkCommandBufferAllocateInfo * pAllocateInfo,VkCommandBuffer * pCommandBuffers)6076     VkResult on_vkAllocateCommandBuffers(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6077                                          VkDevice boxed_device,
6078                                          const VkCommandBufferAllocateInfo* pAllocateInfo,
6079                                          VkCommandBuffer* pCommandBuffers) {
6080         auto device = unbox_VkDevice(boxed_device);
6081         auto vk = dispatch_VkDevice(boxed_device);
6082 
6083         VkResult result = vk->vkAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
6084 
6085         if (result != VK_SUCCESS) {
6086             return result;
6087         }
6088 
6089         std::lock_guard<std::mutex> lock(mMutex);
6090 
6091         auto* deviceInfo = android::base::find(mDeviceInfo, device);
6092         auto* commandPoolInfo = android::base::find(mCommandPoolInfo, pAllocateInfo->commandPool);
6093         if (!deviceInfo || !commandPoolInfo) {
6094             ERR("Cannot allocate command buffers, dependency not found! (%p, %p)", deviceInfo,
6095                 commandPoolInfo);
6096             return VK_ERROR_UNKNOWN;
6097         }
6098 
6099         for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
6100             VALIDATE_NEW_HANDLE_INFO_ENTRY(mCommandBufferInfo, pCommandBuffers[i]);
6101             mCommandBufferInfo[pCommandBuffers[i]] = CommandBufferInfo();
6102             mCommandBufferInfo[pCommandBuffers[i]].device = device;
6103             mCommandBufferInfo[pCommandBuffers[i]].debugUtilsHelper = deviceInfo->debugUtilsHelper;
6104             mCommandBufferInfo[pCommandBuffers[i]].cmdPool = pAllocateInfo->commandPool;
6105             auto boxed = new_boxed_VkCommandBuffer(pCommandBuffers[i], vk,
6106                                                    false /* does not own dispatch */);
6107             mCommandBufferInfo[pCommandBuffers[i]].boxed = boxed;
6108 
6109             commandPoolInfo->cmdBuffers.insert(pCommandBuffers[i]);
6110 
6111             pCommandBuffers[i] = (VkCommandBuffer)boxed;
6112         }
6113         return result;
6114     }
6115 
on_vkCreateCommandPool(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkCommandPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkCommandPool * pCommandPool)6116     VkResult on_vkCreateCommandPool(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6117                                     VkDevice boxed_device,
6118                                     const VkCommandPoolCreateInfo* pCreateInfo,
6119                                     const VkAllocationCallbacks* pAllocator,
6120                                     VkCommandPool* pCommandPool) {
6121         auto device = unbox_VkDevice(boxed_device);
6122         auto vk = dispatch_VkDevice(boxed_device);
6123         if (!pCreateInfo) {
6124             WARN("%s: Invalid parameter.", __func__);
6125             return VK_ERROR_OUT_OF_HOST_MEMORY;
6126         }
6127 
6128         VkCommandPoolCreateInfo localCI = *pCreateInfo;
6129         if (localCI.flags & VK_COMMAND_POOL_CREATE_PROTECTED_BIT) {
6130             // Protected memory is not supported on emulators. Override feature
6131             // information to mark as unsupported (see b/329845987).
6132             localCI.flags &= ~VK_COMMAND_POOL_CREATE_PROTECTED_BIT;
6133             VERBOSE("Changed VK_COMMAND_POOL_CREATE_PROTECTED_BIT, new flags = %d", localCI.flags);
6134         }
6135 
6136         VkResult result = vk->vkCreateCommandPool(device, &localCI, pAllocator, pCommandPool);
6137         if (result != VK_SUCCESS) {
6138             return result;
6139         }
6140         std::lock_guard<std::mutex> lock(mMutex);
6141         VALIDATE_NEW_HANDLE_INFO_ENTRY(mCommandPoolInfo, *pCommandPool);
6142         mCommandPoolInfo[*pCommandPool] = CommandPoolInfo();
6143         auto& cmdPoolInfo = mCommandPoolInfo[*pCommandPool];
6144         cmdPoolInfo.device = device;
6145 
6146         *pCommandPool = new_boxed_non_dispatchable_VkCommandPool(*pCommandPool);
6147         cmdPoolInfo.boxed = *pCommandPool;
6148 
6149         return result;
6150     }
6151 
destroyCommandPoolWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkCommandPool commandPool,CommandPoolInfo & commandPoolInfo,std::unordered_map<VkCommandBuffer,CommandBufferInfo> & commandBufferInfos,const VkAllocationCallbacks * pAllocator)6152     void destroyCommandPoolWithExclusiveInfo(
6153         VkDevice device, VulkanDispatch* deviceDispatch, VkCommandPool commandPool,
6154         CommandPoolInfo& commandPoolInfo,
6155         std::unordered_map<VkCommandBuffer, CommandBufferInfo>& commandBufferInfos,
6156         const VkAllocationCallbacks* pAllocator) {
6157         for (const VkCommandBuffer commandBuffer : commandPoolInfo.cmdBuffers) {
6158             auto iterInInfos = commandBufferInfos.find(commandBuffer);
6159             if (iterInInfos != commandBufferInfos.end()) {
6160                 commandBufferInfos.erase(iterInInfos);
6161             } else {
6162                 ERR("Cannot find command buffer reference (%p).",
6163                     commandBuffer);
6164             }
6165         }
6166 
6167         deviceDispatch->vkDestroyCommandPool(device, commandPool, pAllocator);
6168     }
6169 
destroyCommandPoolLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkCommandPool commandPool,const VkAllocationCallbacks * pAllocator)6170     void destroyCommandPoolLocked(VkDevice device, VulkanDispatch* deviceDispatch,
6171                                   VkCommandPool commandPool,
6172                                   const VkAllocationCallbacks* pAllocator) REQUIRES(mMutex) {
6173         auto commandPoolInfoIt = mCommandPoolInfo.find(commandPool);
6174         if (commandPoolInfoIt == mCommandPoolInfo.end()) return;
6175         auto& commandPoolInfo = commandPoolInfoIt->second;
6176 
6177         destroyCommandPoolWithExclusiveInfo(device, deviceDispatch, commandPool, commandPoolInfo,
6178                                             mCommandBufferInfo, pAllocator);
6179 
6180         mCommandPoolInfo.erase(commandPoolInfoIt);
6181     }
6182 
on_vkDestroyCommandPool(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkCommandPool commandPool,const VkAllocationCallbacks * pAllocator)6183     void on_vkDestroyCommandPool(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6184                                  VkDevice boxed_device, VkCommandPool commandPool,
6185                                  const VkAllocationCallbacks* pAllocator) {
6186         auto device = unbox_VkDevice(boxed_device);
6187         auto deviceDispatch = dispatch_VkDevice(boxed_device);
6188 
6189         std::lock_guard<std::mutex> lock(mMutex);
6190         destroyCommandPoolLocked(device, deviceDispatch, commandPool, pAllocator);
6191     }
6192 
on_vkResetCommandPool(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkCommandPool commandPool,VkCommandPoolResetFlags flags)6193     VkResult on_vkResetCommandPool(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6194                                    VkDevice boxed_device, VkCommandPool commandPool,
6195                                    VkCommandPoolResetFlags flags) {
6196         auto device = unbox_VkDevice(boxed_device);
6197         auto vk = dispatch_VkDevice(boxed_device);
6198 
6199         VkResult result = vk->vkResetCommandPool(device, commandPool, flags);
6200         if (result != VK_SUCCESS) {
6201             return result;
6202         }
6203         return result;
6204     }
6205 
on_vkCmdExecuteCommands(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)6206     void on_vkCmdExecuteCommands(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6207                                  VkCommandBuffer boxed_commandBuffer, uint32_t commandBufferCount,
6208                                  const VkCommandBuffer* pCommandBuffers) {
6209         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
6210         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
6211 
6212         vk->vkCmdExecuteCommands(commandBuffer, commandBufferCount, pCommandBuffers);
6213         std::lock_guard<std::mutex> lock(mMutex);
6214         CommandBufferInfo& cmdBuffer = mCommandBufferInfo[commandBuffer];
6215         cmdBuffer.subCmds.insert(cmdBuffer.subCmds.end(), pCommandBuffers,
6216                                  pCommandBuffers + commandBufferCount);
6217     }
6218 
dispatchVkQueueSubmit(VulkanDispatch * vk,VkQueue unboxed_queue,uint32_t submitCount,const VkSubmitInfo * pSubmits,VkFence fence)6219     VkResult dispatchVkQueueSubmit(VulkanDispatch* vk, VkQueue unboxed_queue, uint32_t submitCount,
6220                                    const VkSubmitInfo* pSubmits, VkFence fence) {
6221         return vk->vkQueueSubmit(unboxed_queue, submitCount, pSubmits, fence);
6222     }
6223 
dispatchVkQueueSubmit(VulkanDispatch * vk,VkQueue unboxed_queue,uint32_t submitCount,const VkSubmitInfo2 * pSubmits,VkFence fence)6224     VkResult dispatchVkQueueSubmit(VulkanDispatch* vk, VkQueue unboxed_queue, uint32_t submitCount,
6225                                    const VkSubmitInfo2* pSubmits, VkFence fence) {
6226         return vk->vkQueueSubmit2(unboxed_queue, submitCount, pSubmits, fence);
6227     }
6228 
getCommandBufferCount(const VkSubmitInfo & submitInfo)6229     int getCommandBufferCount(const VkSubmitInfo& submitInfo) {
6230         return submitInfo.commandBufferCount;
6231     }
6232 
getCommandBuffer(const VkSubmitInfo & submitInfo,int idx)6233     VkCommandBuffer getCommandBuffer(const VkSubmitInfo& submitInfo, int idx) {
6234         return submitInfo.pCommandBuffers[idx];
6235     }
6236 
getCommandBufferCount(const VkSubmitInfo2 & submitInfo)6237     int getCommandBufferCount(const VkSubmitInfo2& submitInfo) {
6238         return submitInfo.commandBufferInfoCount;
6239     }
6240 
getCommandBuffer(const VkSubmitInfo2 & submitInfo,int idx)6241     VkCommandBuffer getCommandBuffer(const VkSubmitInfo2& submitInfo, int idx) {
6242         return submitInfo.pCommandBufferInfos[idx].commandBuffer;
6243     }
6244 
getWaitSemaphoreCount(const VkSubmitInfo & pSubmit)6245     uint32_t getWaitSemaphoreCount(const VkSubmitInfo& pSubmit) {
6246         return pSubmit.waitSemaphoreCount;
6247     }
getWaitSemaphoreCount(const VkSubmitInfo2 & pSubmit)6248     uint32_t getWaitSemaphoreCount(const VkSubmitInfo2& pSubmit) {
6249         return pSubmit.waitSemaphoreInfoCount;
6250     }
getWaitSemaphore(const VkSubmitInfo & pSubmit,int i)6251     VkSemaphore getWaitSemaphore(const VkSubmitInfo& pSubmit, int i) {
6252         return pSubmit.pWaitSemaphores[i];
6253     }
getWaitSemaphore(const VkSubmitInfo2 & pSubmit,int i)6254     VkSemaphore getWaitSemaphore(const VkSubmitInfo2& pSubmit, int i) {
6255         return pSubmit.pWaitSemaphoreInfos[i].semaphore;
6256     }
6257 
getSignalSemaphoreCount(const VkSubmitInfo & pSubmit)6258     uint32_t getSignalSemaphoreCount(const VkSubmitInfo& pSubmit) {
6259         return pSubmit.signalSemaphoreCount;
6260     }
getSignalSemaphoreCount(const VkSubmitInfo2 & pSubmit)6261     uint32_t getSignalSemaphoreCount(const VkSubmitInfo2& pSubmit) {
6262         return pSubmit.signalSemaphoreInfoCount;
6263     }
getSignalSemaphore(const VkSubmitInfo & pSubmit,int i)6264     VkSemaphore getSignalSemaphore(const VkSubmitInfo& pSubmit, int i) {
6265         return pSubmit.pSignalSemaphores[i];
6266     }
getSignalSemaphore(const VkSubmitInfo2 & pSubmit,int i)6267     VkSemaphore getSignalSemaphore(const VkSubmitInfo2& pSubmit, int i) {
6268         return pSubmit.pSignalSemaphoreInfos[i].semaphore;
6269     }
6270 
6271     template <typename VkSubmitInfoType>
on_vkQueueSubmit(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkQueue boxed_queue,uint32_t submitCount,const VkSubmitInfoType * pSubmits,VkFence fence)6272     VkResult on_vkQueueSubmit(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6273                               VkQueue boxed_queue, uint32_t submitCount,
6274                               const VkSubmitInfoType* pSubmits, VkFence fence) {
6275         auto queue = unbox_VkQueue(boxed_queue);
6276         auto vk = dispatch_VkQueue(boxed_queue);
6277 
6278         std::unordered_set<HandleType> acquiredColorBuffers;
6279         std::unordered_set<HandleType> releasedColorBuffers;
6280         if (!m_vkEmulation->getFeatures().GuestVulkanOnly.enabled) {
6281             {
6282                 std::lock_guard<std::mutex> lock(mMutex);
6283                 for (uint32_t i = 0; i < submitCount; i++) {
6284                     for (int j = 0; j < getCommandBufferCount(pSubmits[i]); j++) {
6285                         VkCommandBuffer cmdBuffer = getCommandBuffer(pSubmits[i], j);
6286                         CommandBufferInfo* cmdBufferInfo =
6287                             android::base::find(mCommandBufferInfo, cmdBuffer);
6288                         if (!cmdBufferInfo) {
6289                             continue;
6290                         }
6291                         for (auto descriptorSet : cmdBufferInfo->allDescriptorSets) {
6292                             auto descriptorSetInfo =
6293                                 android::base::find(mDescriptorSetInfo, descriptorSet);
6294                             if (!descriptorSetInfo) {
6295                                 continue;
6296                             }
6297                             for (auto& writes : descriptorSetInfo->allWrites) {
6298                                 for (const auto& write : writes) {
6299                                     bool isValid = true;
6300                                     for (const auto& alive : write.alives) {
6301                                         isValid &= !alive.expired();
6302                                     }
6303                                     if (isValid && write.boundColorBuffer.has_value()) {
6304                                         acquiredColorBuffers.insert(write.boundColorBuffer.value());
6305                                     }
6306                                 }
6307                             }
6308                         }
6309 
6310                         acquiredColorBuffers.merge(cmdBufferInfo->acquiredColorBuffers);
6311                         releasedColorBuffers.merge(cmdBufferInfo->releasedColorBuffers);
6312                         for (const auto& ite : cmdBufferInfo->cbLayouts) {
6313                             m_vkEmulation->setColorBufferCurrentLayout(ite.first, ite.second);
6314                         }
6315                     }
6316                 }
6317             }
6318 
6319             for (HandleType cb : acquiredColorBuffers) {
6320                 m_vkEmulation->getCallbacks().invalidateColorBuffer(cb);
6321             }
6322         }
6323 
6324         VkDevice device = VK_NULL_HANDLE;
6325         std::mutex* queueMutex = nullptr;
6326 
6327         {
6328             std::lock_guard<std::mutex> lock(mMutex);
6329             auto* queueInfo = android::base::find(mQueueInfo, queue);
6330             if (!queueInfo) {
6331                 ERR("vkQueueSubmit cannot find queue info for %p", queue);
6332                 return VK_ERROR_INITIALIZATION_FAILED;
6333             }
6334             device = queueInfo->device;
6335             queueMutex = queueInfo->queueMutex.get();
6336         }
6337 
6338         // Unsafe to release when snapshot enabled.
6339         // Snapshot load might fail to find the shader modules if we release them here.
6340         if (!snapshotsEnabled()) {
6341             processDelayedRemovesForDevice(device);
6342         }
6343 
6344         VkFence usedFence = fence;
6345         DeviceOpWaitable queueCompletedWaitable;
6346         {
6347             std::lock_guard<std::mutex> lock(mMutex);
6348 
6349             auto* deviceInfo = android::base::find(mDeviceInfo, device);
6350             if (!deviceInfo) return VK_ERROR_INITIALIZATION_FAILED;
6351             DeviceOpBuilder builder(*deviceInfo->deviceOpTracker);
6352 
6353             if (VK_NULL_HANDLE == usedFence) {
6354                 // Note: This fence will be managed by the DeviceOpTracker after the
6355                 // OnQueueSubmittedWithFence call, so it does not need to be destroyed in the scope
6356                 // of this queueSubmit
6357                 usedFence = builder.CreateFenceForOp();
6358             }
6359             queueCompletedWaitable = builder.OnQueueSubmittedWithFence(usedFence);
6360 
6361             deviceInfo->deviceOpTracker->PollAndProcessGarbage();
6362         }
6363 
6364         std::lock_guard<std::mutex> queueLock(*queueMutex);
6365         auto result = dispatchVkQueueSubmit(vk, queue, submitCount, pSubmits, usedFence);
6366 
6367         if (result != VK_SUCCESS) {
6368             WARN("dispatchVkQueueSubmit failed: %s [%d]", string_VkResult(result), result);
6369             return result;
6370         }
6371         {
6372             std::lock_guard<std::mutex> lock(mMutex);
6373             // Update image layouts
6374             for (uint32_t i = 0; i < submitCount; i++) {
6375                 for (int j = 0; j < getCommandBufferCount(pSubmits[i]); j++) {
6376                     VkCommandBuffer cmdBuffer = getCommandBuffer(pSubmits[i], j);
6377                     CommandBufferInfo* cmdBufferInfo =
6378                         android::base::find(mCommandBufferInfo, cmdBuffer);
6379                     if (!cmdBufferInfo) {
6380                         continue;
6381                     }
6382                     for (const auto& ite : cmdBufferInfo->imageLayouts) {
6383                         auto imageIte = mImageInfo.find(ite.first);
6384                         if (imageIte == mImageInfo.end()) {
6385                             continue;
6386                         }
6387                         imageIte->second.layout = ite.second;
6388                     }
6389                 }
6390             }
6391             // Update latestUse for all wait/signal semaphores, to ensure that they
6392             // are never asynchronously destroyed before the queue submissions referencing
6393             // them have completed
6394             for (uint32_t i = 0; i < submitCount; i++) {
6395                 for (uint32_t j = 0; j < getWaitSemaphoreCount(pSubmits[i]); j++) {
6396                     SemaphoreInfo* semaphoreInfo =
6397                         android::base::find(mSemaphoreInfo, getWaitSemaphore(pSubmits[i], j));
6398                     if (semaphoreInfo) {
6399                         semaphoreInfo->latestUse = queueCompletedWaitable;
6400                     }
6401                 }
6402                 for (uint32_t j = 0; j < getSignalSemaphoreCount(pSubmits[i]); j++) {
6403                     SemaphoreInfo* semaphoreInfo =
6404                         android::base::find(mSemaphoreInfo, getSignalSemaphore(pSubmits[i], j));
6405                     if (semaphoreInfo) {
6406                         semaphoreInfo->latestUse = queueCompletedWaitable;
6407                     }
6408                 }
6409             }
6410 
6411             // After vkQueueSubmit is called, we can signal the conditional variable
6412             // in FenceInfo, so that other threads (e.g. SyncThread) can call
6413             // waitForFence() on this fence.
6414             auto* fenceInfo = android::base::find(mFenceInfo, fence);
6415             if (fenceInfo) {
6416                 {
6417                     std::unique_lock<std::mutex> fenceLock(fenceInfo->mutex);
6418                     fenceInfo->state = FenceInfo::State::kWaitable;
6419                 }
6420                 fenceInfo->cv.notify_all();
6421                 // Also update the latestUse waitable for this fence, to ensure
6422                 // it is not asynchronously destroyed before all the waitables
6423                 // referencing it
6424                 fenceInfo->latestUse = queueCompletedWaitable;
6425             }
6426         }
6427         if (!releasedColorBuffers.empty()) {
6428             result = vk->vkWaitForFences(device, 1, &usedFence, VK_TRUE, /* 1 sec */ 1000000000L);
6429             if (result != VK_SUCCESS) {
6430                 ERR("vkWaitForFences failed: %s [%d]", string_VkResult(result), result);
6431                 return result;
6432             }
6433 
6434             for (HandleType cb : releasedColorBuffers) {
6435                 m_vkEmulation->getCallbacks().flushColorBuffer(cb);
6436             }
6437         }
6438 
6439         return result;
6440     }
6441 
on_vkQueueWaitIdle(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkQueue boxed_queue)6442     VkResult on_vkQueueWaitIdle(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6443                                 VkQueue boxed_queue) {
6444         auto queue = unbox_VkQueue(boxed_queue);
6445         auto vk = dispatch_VkQueue(boxed_queue);
6446 
6447         if (!queue) return VK_SUCCESS;
6448 
6449         std::mutex* queueMutex;
6450         {
6451             std::lock_guard<std::mutex> lock(mMutex);
6452             auto* queueInfo = android::base::find(mQueueInfo, queue);
6453             if (!queueInfo) return VK_SUCCESS;
6454             queueMutex = queueInfo->queueMutex.get();
6455         }
6456 
6457         // TODO(b/379862480): register and track gpu workload to wait only for the
6458         // necessary work when the virtual graphics queue is enabled, ie. not any
6459         // other fences/work. It should not hold the queue lock/ql while waiting to allow
6460         // submissions and other operations on the virtualized queue
6461 
6462         std::lock_guard<std::mutex> queueLock(*queueMutex);
6463         return vk->vkQueueWaitIdle(queue);
6464     }
6465 
on_vkResetCommandBuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,VkCommandBufferResetFlags flags)6466     VkResult on_vkResetCommandBuffer(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6467                                      VkCommandBuffer boxed_commandBuffer,
6468                                      VkCommandBufferResetFlags flags) {
6469         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
6470         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
6471 
6472         m_vkEmulation->getDeviceLostHelper().onResetCommandBuffer(commandBuffer);
6473 
6474         VkResult result = vk->vkResetCommandBuffer(commandBuffer, flags);
6475         if (VK_SUCCESS == result) {
6476             std::lock_guard<std::mutex> lock(mMutex);
6477             auto& bufferInfo = mCommandBufferInfo[commandBuffer];
6478             bufferInfo.reset();
6479         }
6480         return result;
6481     }
6482 
freeCommandBufferWithExclusiveInfos(VkDevice device,VulkanDispatch * deviceDispatch,VkCommandBuffer commandBuffer,CommandBufferInfo & commandBufferInfo,std::unordered_map<VkCommandPool,CommandPoolInfo> & commandPoolInfos)6483     void freeCommandBufferWithExclusiveInfos(
6484         VkDevice device, VulkanDispatch* deviceDispatch, VkCommandBuffer commandBuffer,
6485         CommandBufferInfo& commandBufferInfo,
6486         std::unordered_map<VkCommandPool, CommandPoolInfo>& commandPoolInfos) {
6487         auto commandPool = commandBufferInfo.cmdPool;
6488 
6489         auto commandPoolInfoIt = commandPoolInfos.find(commandPool);
6490         if (commandPoolInfoIt == commandPoolInfos.end()) return;
6491         auto& commandPoolInfo = commandPoolInfoIt->second;
6492 
6493         auto iterInPool = commandPoolInfo.cmdBuffers.find(commandBuffer);
6494         if (iterInPool != commandPoolInfo.cmdBuffers.end()) {
6495             commandPoolInfo.cmdBuffers.erase(iterInPool);
6496         } else {
6497             ERR("Cannot find command buffer reference (%p) in the pool.", commandBuffer);
6498         }
6499 
6500         // Note delete_VkCommandBuffer(cmdBufferInfoIt->second.boxed); currently done in decoder.
6501 
6502         deviceDispatch->vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
6503     }
6504 
freeCommandBufferLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkCommandPool commandPool,VkCommandBuffer commandBuffer)6505     void freeCommandBufferLocked(VkDevice device, VulkanDispatch* deviceDispatch,
6506                                  VkCommandPool commandPool, VkCommandBuffer commandBuffer)
6507         REQUIRES(mMutex) {
6508         auto commandBufferInfoIt = mCommandBufferInfo.find(commandBuffer);
6509         if (commandBufferInfoIt == mCommandBufferInfo.end()) {
6510             WARN("freeCommandBufferLocked cannot find %p", commandBuffer);
6511             return;
6512         }
6513         auto& commandBufferInfo = commandBufferInfoIt->second;
6514 
6515         freeCommandBufferWithExclusiveInfos(device, deviceDispatch, commandBuffer,
6516                                             commandBufferInfo, mCommandPoolInfo);
6517 
6518         mCommandBufferInfo.erase(commandBufferInfoIt);
6519     }
6520 
on_vkFreeCommandBuffers(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkCommandPool commandPool,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)6521     void on_vkFreeCommandBuffers(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6522                                  VkDevice boxed_device, VkCommandPool commandPool,
6523                                  uint32_t commandBufferCount,
6524                                  const VkCommandBuffer* pCommandBuffers) {
6525         auto device = unbox_VkDevice(boxed_device);
6526         auto deviceDispatch = dispatch_VkDevice(boxed_device);
6527         if (!device || !deviceDispatch) return;
6528 
6529         for (uint32_t i = 0; i < commandBufferCount; i++) {
6530             m_vkEmulation->getDeviceLostHelper().onFreeCommandBuffer(pCommandBuffers[i]);
6531         }
6532 
6533         std::lock_guard<std::mutex> lock(mMutex);
6534         for (uint32_t i = 0; i < commandBufferCount; i++) {
6535             freeCommandBufferLocked(device, deviceDispatch, commandPool, pCommandBuffers[i]);
6536         }
6537     }
6538 
on_vkGetPhysicalDeviceExternalSemaphoreProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkPhysicalDevice boxed_physicalDevice,const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,VkExternalSemaphoreProperties * pExternalSemaphoreProperties)6539     void on_vkGetPhysicalDeviceExternalSemaphoreProperties(
6540         android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6541         VkPhysicalDevice boxed_physicalDevice,
6542         const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
6543         VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
6544         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
6545 
6546         if (!physicalDevice) {
6547             return;
6548         }
6549 
6550         if (m_vkEmulation->getFeatures().VulkanExternalSync.enabled) {
6551             // Cannot forward this call to driver because nVidia linux driver crahses on it.
6552             switch (pExternalSemaphoreInfo->handleType) {
6553                 case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
6554                     pExternalSemaphoreProperties->exportFromImportedHandleTypes =
6555                         VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
6556                     pExternalSemaphoreProperties->compatibleHandleTypes =
6557                         VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
6558                     pExternalSemaphoreProperties->externalSemaphoreFeatures =
6559                         VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |
6560                         VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
6561                     return;
6562                 case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
6563                     pExternalSemaphoreProperties->exportFromImportedHandleTypes =
6564                         VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
6565                     pExternalSemaphoreProperties->compatibleHandleTypes =
6566                         VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
6567                     pExternalSemaphoreProperties->externalSemaphoreFeatures =
6568                         VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |
6569                         VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
6570                     return;
6571                 default:
6572                     break;
6573             }
6574         }
6575 
6576         pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
6577         pExternalSemaphoreProperties->compatibleHandleTypes = 0;
6578         pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
6579     }
6580 
on_vkCreateDescriptorUpdateTemplate(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate)6581     VkResult on_vkCreateDescriptorUpdateTemplate(
6582         android::base::BumpPool* pool, VkSnapshotApiCallInfo*, VkDevice boxed_device,
6583         const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
6584         const VkAllocationCallbacks* pAllocator,
6585         VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
6586         auto device = unbox_VkDevice(boxed_device);
6587         auto vk = dispatch_VkDevice(boxed_device);
6588 
6589         auto descriptorUpdateTemplateInfo = calcLinearizedDescriptorUpdateTemplateInfo(pCreateInfo);
6590 
6591         VkResult res =
6592             vk->vkCreateDescriptorUpdateTemplate(device, &descriptorUpdateTemplateInfo.createInfo,
6593                                                  pAllocator, pDescriptorUpdateTemplate);
6594 
6595         if (res == VK_SUCCESS) {
6596             registerDescriptorUpdateTemplate(*pDescriptorUpdateTemplate,
6597                                              descriptorUpdateTemplateInfo);
6598             *pDescriptorUpdateTemplate =
6599                 new_boxed_non_dispatchable_VkDescriptorUpdateTemplate(*pDescriptorUpdateTemplate);
6600         }
6601 
6602         return res;
6603     }
6604 
on_vkCreateDescriptorUpdateTemplateKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate)6605     VkResult on_vkCreateDescriptorUpdateTemplateKHR(
6606         android::base::BumpPool* pool, VkSnapshotApiCallInfo*, VkDevice boxed_device,
6607         const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
6608         const VkAllocationCallbacks* pAllocator,
6609         VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
6610         auto device = unbox_VkDevice(boxed_device);
6611         auto vk = dispatch_VkDevice(boxed_device);
6612 
6613         auto descriptorUpdateTemplateInfo = calcLinearizedDescriptorUpdateTemplateInfo(pCreateInfo);
6614 
6615         VkResult res = vk->vkCreateDescriptorUpdateTemplateKHR(
6616             device, &descriptorUpdateTemplateInfo.createInfo, pAllocator,
6617             pDescriptorUpdateTemplate);
6618 
6619         if (res == VK_SUCCESS) {
6620             registerDescriptorUpdateTemplate(*pDescriptorUpdateTemplate,
6621                                              descriptorUpdateTemplateInfo);
6622             *pDescriptorUpdateTemplate =
6623                 new_boxed_non_dispatchable_VkDescriptorUpdateTemplate(*pDescriptorUpdateTemplate);
6624         }
6625 
6626         return res;
6627     }
6628 
on_vkDestroyDescriptorUpdateTemplate(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkDescriptorUpdateTemplate descriptorUpdateTemplate,const VkAllocationCallbacks * pAllocator)6629     void on_vkDestroyDescriptorUpdateTemplate(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6630                                               VkDevice boxed_device,
6631                                               VkDescriptorUpdateTemplate descriptorUpdateTemplate,
6632                                               const VkAllocationCallbacks* pAllocator) {
6633         auto device = unbox_VkDevice(boxed_device);
6634         auto vk = dispatch_VkDevice(boxed_device);
6635 
6636         vk->vkDestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator);
6637 
6638         unregisterDescriptorUpdateTemplate(descriptorUpdateTemplate);
6639     }
6640 
on_vkDestroyDescriptorUpdateTemplateKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkDescriptorUpdateTemplate descriptorUpdateTemplate,const VkAllocationCallbacks * pAllocator)6641     void on_vkDestroyDescriptorUpdateTemplateKHR(
6642         android::base::BumpPool* pool, VkSnapshotApiCallInfo*, VkDevice boxed_device,
6643         VkDescriptorUpdateTemplate descriptorUpdateTemplate,
6644         const VkAllocationCallbacks* pAllocator) {
6645         auto device = unbox_VkDevice(boxed_device);
6646         auto vk = dispatch_VkDevice(boxed_device);
6647 
6648         vk->vkDestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
6649 
6650         unregisterDescriptorUpdateTemplate(descriptorUpdateTemplate);
6651     }
6652 
on_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkDescriptorSet descriptorSet,VkDescriptorUpdateTemplate descriptorUpdateTemplate,uint32_t imageInfoCount,uint32_t bufferInfoCount,uint32_t bufferViewCount,const uint32_t * pImageInfoEntryIndices,const uint32_t * pBufferInfoEntryIndices,const uint32_t * pBufferViewEntryIndices,const VkDescriptorImageInfo * pImageInfos,const VkDescriptorBufferInfo * pBufferInfos,const VkBufferView * pBufferViews)6653     void on_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(
6654         android::base::BumpPool* pool, VkSnapshotApiCallInfo*, VkDevice boxed_device,
6655         VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
6656         uint32_t imageInfoCount, uint32_t bufferInfoCount, uint32_t bufferViewCount,
6657         const uint32_t* pImageInfoEntryIndices, const uint32_t* pBufferInfoEntryIndices,
6658         const uint32_t* pBufferViewEntryIndices, const VkDescriptorImageInfo* pImageInfos,
6659         const VkDescriptorBufferInfo* pBufferInfos, const VkBufferView* pBufferViews) {
6660         auto device = unbox_VkDevice(boxed_device);
6661         auto vk = dispatch_VkDevice(boxed_device);
6662 
6663         std::lock_guard<std::mutex> lock(mMutex);
6664         auto* info = android::base::find(mDescriptorUpdateTemplateInfo, descriptorUpdateTemplate);
6665         if (!info) return;
6666 
6667         memcpy(info->data.data() + info->imageInfoStart, pImageInfos,
6668                imageInfoCount * sizeof(VkDescriptorImageInfo));
6669         memcpy(info->data.data() + info->bufferInfoStart, pBufferInfos,
6670                bufferInfoCount * sizeof(VkDescriptorBufferInfo));
6671         memcpy(info->data.data() + info->bufferViewStart, pBufferViews,
6672                bufferViewCount * sizeof(VkBufferView));
6673 
6674         vk->vkUpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate,
6675                                               info->data.data());
6676     }
6677 
on_vkUpdateDescriptorSetWithTemplateSized2GOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkDescriptorSet descriptorSet,VkDescriptorUpdateTemplate descriptorUpdateTemplate,uint32_t imageInfoCount,uint32_t bufferInfoCount,uint32_t bufferViewCount,uint32_t inlineUniformBlockCount,const uint32_t * pImageInfoEntryIndices,const uint32_t * pBufferInfoEntryIndices,const uint32_t * pBufferViewEntryIndices,const VkDescriptorImageInfo * pImageInfos,const VkDescriptorBufferInfo * pBufferInfos,const VkBufferView * pBufferViews,const uint8_t * pInlineUniformBlockData)6678     void on_vkUpdateDescriptorSetWithTemplateSized2GOOGLE(
6679         android::base::BumpPool* pool, VkSnapshotApiCallInfo*, VkDevice boxed_device,
6680         VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
6681         uint32_t imageInfoCount, uint32_t bufferInfoCount, uint32_t bufferViewCount,
6682         uint32_t inlineUniformBlockCount, const uint32_t* pImageInfoEntryIndices,
6683         const uint32_t* pBufferInfoEntryIndices, const uint32_t* pBufferViewEntryIndices,
6684         const VkDescriptorImageInfo* pImageInfos, const VkDescriptorBufferInfo* pBufferInfos,
6685         const VkBufferView* pBufferViews, const uint8_t* pInlineUniformBlockData) {
6686         auto device = unbox_VkDevice(boxed_device);
6687         auto vk = dispatch_VkDevice(boxed_device);
6688 
6689         std::lock_guard<std::mutex> lock(mMutex);
6690         auto* info = android::base::find(mDescriptorUpdateTemplateInfo, descriptorUpdateTemplate);
6691         if (!info) return;
6692 
6693         memcpy(info->data.data() + info->imageInfoStart, pImageInfos,
6694                imageInfoCount * sizeof(VkDescriptorImageInfo));
6695         memcpy(info->data.data() + info->bufferInfoStart, pBufferInfos,
6696                bufferInfoCount * sizeof(VkDescriptorBufferInfo));
6697         memcpy(info->data.data() + info->bufferViewStart, pBufferViews,
6698                bufferViewCount * sizeof(VkBufferView));
6699         memcpy(info->data.data() + info->inlineUniformBlockStart, pInlineUniformBlockData,
6700                inlineUniformBlockCount);
6701 
6702         vk->vkUpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate,
6703                                               info->data.data());
6704     }
6705 
hostSyncCommandBuffer(const char * tag,VkCommandBuffer boxed_commandBuffer,uint32_t needHostSync,uint32_t sequenceNumber)6706     void hostSyncCommandBuffer(const char* tag, VkCommandBuffer boxed_commandBuffer,
6707                                uint32_t needHostSync, uint32_t sequenceNumber) {
6708         auto nextDeadline = []() {
6709             return android::base::getUnixTimeUs() + 10000;  // 10 ms
6710         };
6711 
6712         auto timeoutDeadline = android::base::getUnixTimeUs() + 5000000;  // 5 s
6713 
6714         OrderMaintenanceInfo* order = ordmaint_VkCommandBuffer(boxed_commandBuffer);
6715         if (!order) return;
6716 
6717         AutoLock lock(order->lock);
6718 
6719         if (needHostSync) {
6720             while (
6721                 (sequenceNumber - __atomic_load_n(&order->sequenceNumber, __ATOMIC_ACQUIRE) != 1)) {
6722                 auto waitUntilUs = nextDeadline();
6723                 order->cv.timedWait(&order->lock, waitUntilUs);
6724 
6725                 if (timeoutDeadline < android::base::getUnixTimeUs()) {
6726                     break;
6727                 }
6728             }
6729         }
6730 
6731         __atomic_store_n(&order->sequenceNumber, sequenceNumber, __ATOMIC_RELEASE);
6732         order->cv.signal();
6733         releaseOrderMaintInfo(order);
6734     }
6735 
on_vkCommandBufferHostSyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer commandBuffer,uint32_t needHostSync,uint32_t sequenceNumber)6736     void on_vkCommandBufferHostSyncGOOGLE(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6737                                           VkCommandBuffer commandBuffer, uint32_t needHostSync,
6738                                           uint32_t sequenceNumber) {
6739         this->hostSyncCommandBuffer("hostSync", commandBuffer, needHostSync, sequenceNumber);
6740     }
6741 
hostSyncQueue(const char * tag,VkQueue boxed_queue,uint32_t needHostSync,uint32_t sequenceNumber)6742     void hostSyncQueue(const char* tag, VkQueue boxed_queue, uint32_t needHostSync,
6743                        uint32_t sequenceNumber) {
6744         auto nextDeadline = []() {
6745             return android::base::getUnixTimeUs() + 10000;  // 10 ms
6746         };
6747 
6748         auto timeoutDeadline = android::base::getUnixTimeUs() + 5000000;  // 5 s
6749 
6750         OrderMaintenanceInfo* order = ordmaint_VkQueue(boxed_queue);
6751         if (!order) return;
6752 
6753         AutoLock lock(order->lock);
6754 
6755         if (needHostSync) {
6756             while (
6757                 (sequenceNumber - __atomic_load_n(&order->sequenceNumber, __ATOMIC_ACQUIRE) != 1)) {
6758                 auto waitUntilUs = nextDeadline();
6759                 order->cv.timedWait(&order->lock, waitUntilUs);
6760 
6761                 if (timeoutDeadline < android::base::getUnixTimeUs()) {
6762                     break;
6763                 }
6764             }
6765         }
6766 
6767         __atomic_store_n(&order->sequenceNumber, sequenceNumber, __ATOMIC_RELEASE);
6768         order->cv.signal();
6769         releaseOrderMaintInfo(order);
6770     }
6771 
on_vkQueueHostSyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkQueue queue,uint32_t needHostSync,uint32_t sequenceNumber)6772     void on_vkQueueHostSyncGOOGLE(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6773                                   VkQueue queue, uint32_t needHostSync, uint32_t sequenceNumber) {
6774         this->hostSyncQueue("hostSyncQueue", queue, needHostSync, sequenceNumber);
6775     }
6776 
on_vkCreateImageWithRequirementsGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage,VkMemoryRequirements * pMemoryRequirements)6777     VkResult on_vkCreateImageWithRequirementsGOOGLE(
6778         android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
6779         const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
6780         VkImage* pImage, VkMemoryRequirements* pMemoryRequirements) {
6781         if (pMemoryRequirements) {
6782             memset(pMemoryRequirements, 0, sizeof(*pMemoryRequirements));
6783         }
6784 
6785         VkResult imageCreateRes =
6786             on_vkCreateImage(pool, snapshotInfo, boxed_device, pCreateInfo, pAllocator, pImage);
6787 
6788         if (imageCreateRes != VK_SUCCESS) {
6789             return imageCreateRes;
6790         }
6791 
6792         on_vkGetImageMemoryRequirements(pool, snapshotInfo, boxed_device, unbox_VkImage(*pImage),
6793                                         pMemoryRequirements);
6794 
6795         return imageCreateRes;
6796     }
6797 
on_vkCreateBufferWithRequirementsGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer,VkMemoryRequirements * pMemoryRequirements)6798     VkResult on_vkCreateBufferWithRequirementsGOOGLE(
6799         android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
6800         const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
6801         VkBuffer* pBuffer, VkMemoryRequirements* pMemoryRequirements) {
6802         if (pMemoryRequirements) {
6803             memset(pMemoryRequirements, 0, sizeof(*pMemoryRequirements));
6804         }
6805 
6806         VkResult bufferCreateRes =
6807             on_vkCreateBuffer(pool, snapshotInfo, boxed_device, pCreateInfo, pAllocator, pBuffer);
6808 
6809         if (bufferCreateRes != VK_SUCCESS) {
6810             return bufferCreateRes;
6811         }
6812 
6813         on_vkGetBufferMemoryRequirements(pool, snapshotInfo, boxed_device, unbox_VkBuffer(*pBuffer),
6814                                          pMemoryRequirements);
6815 
6816         return bufferCreateRes;
6817     }
6818 
on_vkBeginCommandBuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,const VkCommandBufferBeginInfo * pBeginInfo,const VkDecoderContext & context)6819     VkResult on_vkBeginCommandBuffer(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6820                                      VkCommandBuffer boxed_commandBuffer,
6821                                      const VkCommandBufferBeginInfo* pBeginInfo,
6822                                      const VkDecoderContext& context) {
6823         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
6824         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
6825         VkResult result = vk->vkBeginCommandBuffer(commandBuffer, pBeginInfo);
6826 
6827         if (result != VK_SUCCESS) {
6828             return result;
6829         }
6830 
6831         m_vkEmulation->getDeviceLostHelper().onBeginCommandBuffer(commandBuffer, vk);
6832 
6833         std::lock_guard<std::mutex> lock(mMutex);
6834 
6835         auto* commandBufferInfo = android::base::find(mCommandBufferInfo, commandBuffer);
6836         if (!commandBufferInfo) return VK_ERROR_UNKNOWN;
6837         commandBufferInfo->reset();
6838 
6839         if (context.processName) {
6840             commandBufferInfo->debugUtilsHelper.cmdBeginDebugLabel(commandBuffer, "Process %s",
6841                                                                    context.processName);
6842         }
6843 
6844         return VK_SUCCESS;
6845     }
6846 
on_vkBeginCommandBufferAsyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer boxed_commandBuffer,const VkCommandBufferBeginInfo * pBeginInfo,const VkDecoderContext & context)6847     VkResult on_vkBeginCommandBufferAsyncGOOGLE(android::base::BumpPool* pool,
6848                                                 VkSnapshotApiCallInfo* snapshotInfo,
6849                                                 VkCommandBuffer boxed_commandBuffer,
6850                                                 const VkCommandBufferBeginInfo* pBeginInfo,
6851                                                 const VkDecoderContext& context) {
6852         return this->on_vkBeginCommandBuffer(pool, snapshotInfo, boxed_commandBuffer, pBeginInfo,
6853                                              context);
6854     }
6855 
on_vkEndCommandBuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,const VkDecoderContext & context)6856     VkResult on_vkEndCommandBuffer(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6857                                    VkCommandBuffer boxed_commandBuffer,
6858                                    const VkDecoderContext& context) {
6859         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
6860         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
6861 
6862         m_vkEmulation->getDeviceLostHelper().onEndCommandBuffer(commandBuffer, vk);
6863 
6864         std::lock_guard<std::mutex> lock(mMutex);
6865 
6866         auto* commandBufferInfo = android::base::find(mCommandBufferInfo, commandBuffer);
6867         if (!commandBufferInfo) return VK_ERROR_UNKNOWN;
6868 
6869         if (context.processName) {
6870             commandBufferInfo->debugUtilsHelper.cmdEndDebugLabel(commandBuffer);
6871         }
6872 
6873         return vk->vkEndCommandBuffer(commandBuffer);
6874     }
6875 
on_vkEndCommandBufferAsyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer boxed_commandBuffer,const VkDecoderContext & context)6876     void on_vkEndCommandBufferAsyncGOOGLE(android::base::BumpPool* pool,
6877                                           VkSnapshotApiCallInfo* snapshotInfo,
6878                                           VkCommandBuffer boxed_commandBuffer,
6879                                           const VkDecoderContext& context) {
6880         on_vkEndCommandBuffer(pool, snapshotInfo, boxed_commandBuffer, context);
6881     }
6882 
on_vkResetCommandBufferAsyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer boxed_commandBuffer,VkCommandBufferResetFlags flags)6883     void on_vkResetCommandBufferAsyncGOOGLE(android::base::BumpPool* pool,
6884                                             VkSnapshotApiCallInfo* snapshotInfo,
6885                                             VkCommandBuffer boxed_commandBuffer,
6886                                             VkCommandBufferResetFlags flags) {
6887         on_vkResetCommandBuffer(pool, snapshotInfo, boxed_commandBuffer, flags);
6888     }
6889 
on_vkCmdBindPipeline(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipeline pipeline)6890     void on_vkCmdBindPipeline(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6891                               VkCommandBuffer boxed_commandBuffer,
6892                               VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) {
6893         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
6894         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
6895         vk->vkCmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
6896         if (pipelineBindPoint == VK_PIPELINE_BIND_POINT_COMPUTE) {
6897             std::lock_guard<std::mutex> lock(mMutex);
6898             auto* cmdBufferInfo = android::base::find(mCommandBufferInfo, commandBuffer);
6899             if (cmdBufferInfo) {
6900                 cmdBufferInfo->computePipeline = pipeline;
6901             }
6902         }
6903     }
6904 
on_vkCmdBindDescriptorSets(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipelineLayout layout,uint32_t firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets,uint32_t dynamicOffsetCount,const uint32_t * pDynamicOffsets)6905     void on_vkCmdBindDescriptorSets(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6906                                     VkCommandBuffer boxed_commandBuffer,
6907                                     VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
6908                                     uint32_t firstSet, uint32_t descriptorSetCount,
6909                                     const VkDescriptorSet* pDescriptorSets,
6910                                     uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets) {
6911         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
6912         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
6913         vk->vkCmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet,
6914                                     descriptorSetCount, pDescriptorSets, dynamicOffsetCount,
6915                                     pDynamicOffsets);
6916         if (descriptorSetCount) {
6917             std::lock_guard<std::mutex> lock(mMutex);
6918             auto* cmdBufferInfo = android::base::find(mCommandBufferInfo, commandBuffer);
6919             if (cmdBufferInfo) {
6920                 cmdBufferInfo->descriptorLayout = layout;
6921 
6922                 cmdBufferInfo->allDescriptorSets.insert(pDescriptorSets,
6923                                                         pDescriptorSets + descriptorSetCount);
6924                 cmdBufferInfo->firstSet = firstSet;
6925                 cmdBufferInfo->currentDescriptorSets.assign(pDescriptorSets,
6926                                                             pDescriptorSets + descriptorSetCount);
6927                 cmdBufferInfo->dynamicOffsets.assign(pDynamicOffsets,
6928                                                      pDynamicOffsets + dynamicOffsetCount);
6929             }
6930         }
6931     }
6932 
on_vkCreateRenderPass(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkRenderPassCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)6933     VkResult on_vkCreateRenderPass(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6934                                    VkDevice boxed_device, const VkRenderPassCreateInfo* pCreateInfo,
6935                                    const VkAllocationCallbacks* pAllocator,
6936                                    VkRenderPass* pRenderPass) {
6937         auto device = unbox_VkDevice(boxed_device);
6938         auto vk = dispatch_VkDevice(boxed_device);
6939         VkRenderPassCreateInfo createInfo;
6940         bool needReformat = false;
6941         std::lock_guard<std::mutex> lock(mMutex);
6942 
6943         auto* deviceInfo = android::base::find(mDeviceInfo, device);
6944         if (!deviceInfo) return VK_ERROR_OUT_OF_HOST_MEMORY;
6945         if (deviceInfo->emulateTextureEtc2 || deviceInfo->emulateTextureAstc) {
6946             for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
6947                 if (deviceInfo->needEmulatedDecompression(pCreateInfo->pAttachments[i].format)) {
6948                     needReformat = true;
6949                     break;
6950                 }
6951             }
6952         }
6953         std::vector<VkAttachmentDescription> attachments;
6954         if (needReformat) {
6955             createInfo = *pCreateInfo;
6956             attachments.assign(pCreateInfo->pAttachments,
6957                                pCreateInfo->pAttachments + pCreateInfo->attachmentCount);
6958             createInfo.pAttachments = attachments.data();
6959             for (auto& attachment : attachments) {
6960                 attachment.format = CompressedImageInfo::getOutputFormat(attachment.format);
6961             }
6962             pCreateInfo = &createInfo;
6963         }
6964         VkResult res = vk->vkCreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
6965         if (res != VK_SUCCESS) {
6966             return res;
6967         }
6968 
6969         VALIDATE_NEW_HANDLE_INFO_ENTRY(mRenderPassInfo, *pRenderPass);
6970         auto& renderPassInfo = mRenderPassInfo[*pRenderPass];
6971         renderPassInfo.device = device;
6972 
6973         *pRenderPass = new_boxed_non_dispatchable_VkRenderPass(*pRenderPass);
6974 
6975         return res;
6976     }
6977 
on_vkCreateRenderPass2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkRenderPassCreateInfo2 * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)6978     VkResult on_vkCreateRenderPass2(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
6979                                     VkDevice boxed_device,
6980                                     const VkRenderPassCreateInfo2* pCreateInfo,
6981                                     const VkAllocationCallbacks* pAllocator,
6982                                     VkRenderPass* pRenderPass) {
6983         auto device = unbox_VkDevice(boxed_device);
6984         auto vk = dispatch_VkDevice(boxed_device);
6985         std::lock_guard<std::mutex> lock(mMutex);
6986 
6987         VkResult res = vk->vkCreateRenderPass2(device, pCreateInfo, pAllocator, pRenderPass);
6988         if (res != VK_SUCCESS) {
6989             return res;
6990         }
6991 
6992         VALIDATE_NEW_HANDLE_INFO_ENTRY(mRenderPassInfo, *pRenderPass);
6993         auto& renderPassInfo = mRenderPassInfo[*pRenderPass];
6994         renderPassInfo.device = device;
6995 
6996         *pRenderPass = new_boxed_non_dispatchable_VkRenderPass(*pRenderPass);
6997 
6998         return res;
6999     }
7000 
destroyRenderPassWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkRenderPass renderPass,RenderPassInfo & renderPassInfo,const VkAllocationCallbacks * pAllocator)7001     void destroyRenderPassWithExclusiveInfo(VkDevice device, VulkanDispatch* deviceDispatch,
7002                                             VkRenderPass renderPass, RenderPassInfo& renderPassInfo,
7003                                             const VkAllocationCallbacks* pAllocator) {
7004         deviceDispatch->vkDestroyRenderPass(device, renderPass, pAllocator);
7005     }
7006 
destroyRenderPassLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkRenderPass renderPass,const VkAllocationCallbacks * pAllocator)7007     void destroyRenderPassLocked(VkDevice device, VulkanDispatch* deviceDispatch,
7008                                  VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator)
7009         REQUIRES(mMutex) {
7010         auto renderPassInfoIt = mRenderPassInfo.find(renderPass);
7011         if (renderPassInfoIt == mRenderPassInfo.end()) return;
7012         auto& renderPassInfo = renderPassInfoIt->second;
7013 
7014         destroyRenderPassWithExclusiveInfo(device, deviceDispatch, renderPass, renderPassInfo,
7015                                            pAllocator);
7016 
7017         mRenderPassInfo.erase(renderPass);
7018     }
7019 
on_vkDestroyRenderPass(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkRenderPass renderPass,const VkAllocationCallbacks * pAllocator)7020     void on_vkDestroyRenderPass(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
7021                                 VkDevice boxed_device, VkRenderPass renderPass,
7022                                 const VkAllocationCallbacks* pAllocator) {
7023         auto device = unbox_VkDevice(boxed_device);
7024         auto deviceDispatch = dispatch_VkDevice(boxed_device);
7025 
7026         std::lock_guard<std::mutex> lock(mMutex);
7027         destroyRenderPassLocked(device, deviceDispatch, renderPass, pAllocator);
7028     }
7029 
registerRenderPassBeginInfo(VkCommandBuffer commandBuffer,const VkRenderPassBeginInfo * pRenderPassBegin)7030     bool registerRenderPassBeginInfo(VkCommandBuffer commandBuffer,
7031                                      const VkRenderPassBeginInfo* pRenderPassBegin) {
7032         if (!pRenderPassBegin) {
7033             ERR("pRenderPassBegin is null");
7034             return false;
7035         }
7036 
7037         std::lock_guard<std::mutex> lock(mMutex);
7038         CommandBufferInfo* cmdBufferInfo = android::base::find(mCommandBufferInfo, commandBuffer);
7039         if (!cmdBufferInfo) {
7040             ERR("VkCommandBuffer=%p not found in mCommandBufferInfo", commandBuffer);
7041             return false;
7042         }
7043 
7044         FramebufferInfo* fbInfo =
7045             android::base::find(mFramebufferInfo, pRenderPassBegin->framebuffer);
7046         if (!fbInfo) {
7047             ERR("pRenderPassBegin->framebuffer=%p not found in mFbInfo",
7048                 pRenderPassBegin->framebuffer);
7049             return false;
7050         }
7051 
7052         cmdBufferInfo->releasedColorBuffers.insert(fbInfo->attachedColorBuffers.begin(),
7053                                                    fbInfo->attachedColorBuffers.end());
7054         return true;
7055     }
7056 
on_vkCmdBeginRenderPass(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,const VkRenderPassBeginInfo * pRenderPassBegin,VkSubpassContents contents)7057     void on_vkCmdBeginRenderPass(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
7058                                  VkCommandBuffer boxed_commandBuffer,
7059                                  const VkRenderPassBeginInfo* pRenderPassBegin,
7060                                  VkSubpassContents contents) {
7061         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
7062         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
7063         if (registerRenderPassBeginInfo(commandBuffer, pRenderPassBegin)) {
7064             vk->vkCmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
7065         }
7066     }
7067 
on_vkCmdBeginRenderPass2(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,const VkRenderPassBeginInfo * pRenderPassBegin,const VkSubpassBeginInfo * pSubpassBeginInfo)7068     void on_vkCmdBeginRenderPass2(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
7069                                   VkCommandBuffer boxed_commandBuffer,
7070                                   const VkRenderPassBeginInfo* pRenderPassBegin,
7071                                   const VkSubpassBeginInfo* pSubpassBeginInfo) {
7072         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
7073         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
7074         if (registerRenderPassBeginInfo(commandBuffer, pRenderPassBegin)) {
7075             vk->vkCmdBeginRenderPass2(commandBuffer, pRenderPassBegin, pSubpassBeginInfo);
7076         }
7077     }
7078 
on_vkCmdBeginRenderPass2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer boxed_commandBuffer,const VkRenderPassBeginInfo * pRenderPassBegin,const VkSubpassBeginInfo * pSubpassBeginInfo)7079     void on_vkCmdBeginRenderPass2KHR(android::base::BumpPool* pool,
7080                                      VkSnapshotApiCallInfo* snapshotInfo,
7081                                      VkCommandBuffer boxed_commandBuffer,
7082                                      const VkRenderPassBeginInfo* pRenderPassBegin,
7083                                      const VkSubpassBeginInfo* pSubpassBeginInfo) {
7084         on_vkCmdBeginRenderPass2(pool, snapshotInfo, boxed_commandBuffer, pRenderPassBegin,
7085                                  pSubpassBeginInfo);
7086     }
7087 
on_vkCmdCopyQueryPoolResults(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkCommandBuffer boxed_commandBuffer,VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize stride,VkQueryResultFlags flags)7088     void on_vkCmdCopyQueryPoolResults(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
7089                                       VkCommandBuffer boxed_commandBuffer, VkQueryPool queryPool,
7090                                       uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer,
7091                                       VkDeviceSize dstOffset, VkDeviceSize stride,
7092                                       VkQueryResultFlags flags) {
7093         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
7094         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
7095 
7096         {
7097             std::lock_guard<std::mutex> lock(mMutex);
7098 
7099             if (queryCount == 1 && stride == 0) {
7100                 // Some drivers don't seem to handle stride==0 very well.
7101                 // In fact, the spec does not say what should happen with stride==0.
7102                 // So we just use the largest stride possible.
7103                 stride = mBufferInfo[dstBuffer].size - dstOffset;
7104             }
7105         }
7106 
7107         vk->vkCmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer,
7108                                       dstOffset, stride, flags);
7109     }
7110 
on_vkCreateFramebuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkFramebufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkFramebuffer * pFramebuffer)7111     VkResult on_vkCreateFramebuffer(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
7112                                     VkDevice boxed_device,
7113                                     const VkFramebufferCreateInfo* pCreateInfo,
7114                                     const VkAllocationCallbacks* pAllocator,
7115                                     VkFramebuffer* pFramebuffer) {
7116         auto device = unbox_VkDevice(boxed_device);
7117         auto deviceDispatch = dispatch_VkDevice(boxed_device);
7118 
7119         VkResult result =
7120             deviceDispatch->vkCreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer);
7121         if (result != VK_SUCCESS) {
7122             return result;
7123         }
7124 
7125         std::lock_guard<std::mutex> lock(mMutex);
7126 
7127         VALIDATE_NEW_HANDLE_INFO_ENTRY(mFramebufferInfo, *pFramebuffer);
7128         auto& framebufferInfo = mFramebufferInfo[*pFramebuffer];
7129         framebufferInfo.device = device;
7130 
7131         if ((pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT) == 0) {
7132             // b/327522469
7133             // Track the Colorbuffers that would be written to.
7134             // It might be better to check for VK_QUEUE_FAMILY_EXTERNAL in pipeline barrier.
7135             // But the guest does not always add it to pipeline barrier.
7136             for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
7137                 auto* imageViewInfo = android::base::find(mImageViewInfo, pCreateInfo->pAttachments[i]);
7138                 if (imageViewInfo->boundColorBuffer.has_value()) {
7139                     framebufferInfo.attachedColorBuffers.push_back(
7140                         imageViewInfo->boundColorBuffer.value());
7141                 }
7142             }
7143         }
7144 
7145         *pFramebuffer = new_boxed_non_dispatchable_VkFramebuffer(*pFramebuffer);
7146 
7147         return result;
7148     }
7149 
destroyFramebufferWithExclusiveInfo(VkDevice device,VulkanDispatch * deviceDispatch,VkFramebuffer framebuffer,FramebufferInfo & framebufferInfo,const VkAllocationCallbacks * pAllocator)7150     void destroyFramebufferWithExclusiveInfo(VkDevice device, VulkanDispatch* deviceDispatch,
7151                                              VkFramebuffer framebuffer,
7152                                              FramebufferInfo& framebufferInfo,
7153                                              const VkAllocationCallbacks* pAllocator) {
7154         deviceDispatch->vkDestroyFramebuffer(device, framebuffer, pAllocator);
7155     }
7156 
destroyFramebufferLocked(VkDevice device,VulkanDispatch * deviceDispatch,VkFramebuffer framebuffer,const VkAllocationCallbacks * pAllocator)7157     void destroyFramebufferLocked(VkDevice device, VulkanDispatch* deviceDispatch,
7158                                   VkFramebuffer framebuffer,
7159                                   const VkAllocationCallbacks* pAllocator) REQUIRES(mMutex) {
7160         auto framebufferInfoIt = mFramebufferInfo.find(framebuffer);
7161         if (framebufferInfoIt == mFramebufferInfo.end()) return;
7162         auto& framebufferInfo = framebufferInfoIt->second;
7163 
7164         destroyFramebufferWithExclusiveInfo(device, deviceDispatch, framebuffer, framebufferInfo,
7165                                             pAllocator);
7166 
7167         mFramebufferInfo.erase(framebuffer);
7168     }
7169 
on_vkDestroyFramebuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkFramebuffer framebuffer,const VkAllocationCallbacks * pAllocator)7170     void on_vkDestroyFramebuffer(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
7171                                  VkDevice boxed_device, VkFramebuffer framebuffer,
7172                                  const VkAllocationCallbacks* pAllocator) {
7173         auto device = unbox_VkDevice(boxed_device);
7174         auto deviceDispatch = dispatch_VkDevice(boxed_device);
7175 
7176         std::lock_guard<std::mutex> lock(mMutex);
7177         destroyFramebufferLocked(device, deviceDispatch, framebuffer, pAllocator);
7178     }
7179 
on_vkQueueBindSparse(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkQueue boxed_queue,uint32_t bindInfoCount,const VkBindSparseInfo * pBindInfo,VkFence fence)7180     VkResult on_vkQueueBindSparse(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
7181                                   VkQueue boxed_queue, uint32_t bindInfoCount,
7182                                   const VkBindSparseInfo* pBindInfo, VkFence fence) {
7183         // If pBindInfo contains VkTimelineSemaphoreSubmitInfo, then it's
7184         // possible the host driver isn't equipped to deal with them yet.  To
7185         // work around this, send empty vkQueueSubmits before and after the
7186         // call to vkQueueBindSparse that contain the right values for
7187         // wait/signal semaphores and contains the user's
7188         // VkTimelineSemaphoreSubmitInfo structure, following the *submission
7189         // order* implied by the indices of pBindInfo.
7190 
7191         // TODO: Detect if we are running on a driver that supports timeline
7192         // semaphore signal/wait operations in vkQueueBindSparse
7193         const bool needTimelineSubmitInfoWorkaround = true;
7194         (void)needTimelineSubmitInfoWorkaround;
7195 
7196         bool hasTimelineSemaphoreSubmitInfo = false;
7197 
7198         for (uint32_t i = 0; i < bindInfoCount; ++i) {
7199             const VkTimelineSemaphoreSubmitInfoKHR* tsSi =
7200                 vk_find_struct<VkTimelineSemaphoreSubmitInfoKHR>(pBindInfo + i);
7201             if (tsSi) {
7202                 hasTimelineSemaphoreSubmitInfo = true;
7203             }
7204         }
7205 
7206         auto queue = unbox_VkQueue(boxed_queue);
7207         auto vk = dispatch_VkQueue(boxed_queue);
7208 
7209         if (!hasTimelineSemaphoreSubmitInfo) {
7210             (void)pool;
7211             return vk->vkQueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
7212         } else {
7213             std::vector<VkPipelineStageFlags> waitDstStageMasks;
7214             VkTimelineSemaphoreSubmitInfoKHR currTsSi = {
7215                 VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, 0, 0, nullptr, 0, nullptr,
7216             };
7217 
7218             VkSubmitInfo currSi = {
7219                 VK_STRUCTURE_TYPE_SUBMIT_INFO,
7220                 &currTsSi,
7221                 0,
7222                 nullptr,
7223                 nullptr,
7224                 0,
7225                 nullptr,  // No commands
7226                 0,
7227                 nullptr,
7228             };
7229 
7230             VkBindSparseInfo currBi;
7231 
7232             VkResult res;
7233 
7234             for (uint32_t i = 0; i < bindInfoCount; ++i) {
7235                 const VkTimelineSemaphoreSubmitInfoKHR* tsSi =
7236                     vk_find_struct<VkTimelineSemaphoreSubmitInfoKHR>(pBindInfo + i);
7237                 if (!tsSi) {
7238                     res = vk->vkQueueBindSparse(queue, 1, pBindInfo + i, fence);
7239                     if (VK_SUCCESS != res) return res;
7240                     continue;
7241                 }
7242 
7243                 currTsSi.waitSemaphoreValueCount = tsSi->waitSemaphoreValueCount;
7244                 currTsSi.pWaitSemaphoreValues = tsSi->pWaitSemaphoreValues;
7245                 currTsSi.signalSemaphoreValueCount = 0;
7246                 currTsSi.pSignalSemaphoreValues = nullptr;
7247 
7248                 currSi.waitSemaphoreCount = pBindInfo[i].waitSemaphoreCount;
7249                 currSi.pWaitSemaphores = pBindInfo[i].pWaitSemaphores;
7250                 waitDstStageMasks.resize(pBindInfo[i].waitSemaphoreCount,
7251                                          VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
7252                 currSi.pWaitDstStageMask = waitDstStageMasks.data();
7253 
7254                 currSi.signalSemaphoreCount = 0;
7255                 currSi.pSignalSemaphores = nullptr;
7256 
7257                 res = vk->vkQueueSubmit(queue, 1, &currSi, nullptr);
7258                 if (VK_SUCCESS != res) return res;
7259 
7260                 currBi = pBindInfo[i];
7261 
7262                 vk_struct_chain_remove(tsSi, &currBi);
7263 
7264                 currBi.waitSemaphoreCount = 0;
7265                 currBi.pWaitSemaphores = nullptr;
7266                 currBi.signalSemaphoreCount = 0;
7267                 currBi.pSignalSemaphores = nullptr;
7268 
7269                 res = vk->vkQueueBindSparse(queue, 1, &currBi, nullptr);
7270                 if (VK_SUCCESS != res) return res;
7271 
7272                 currTsSi.waitSemaphoreValueCount = 0;
7273                 currTsSi.pWaitSemaphoreValues = nullptr;
7274                 currTsSi.signalSemaphoreValueCount = tsSi->signalSemaphoreValueCount;
7275                 currTsSi.pSignalSemaphoreValues = tsSi->pSignalSemaphoreValues;
7276 
7277                 currSi.waitSemaphoreCount = 0;
7278                 currSi.pWaitSemaphores = nullptr;
7279                 currSi.signalSemaphoreCount = pBindInfo[i].signalSemaphoreCount;
7280                 currSi.pSignalSemaphores = pBindInfo[i].pSignalSemaphores;
7281 
7282                 res =
7283                     vk->vkQueueSubmit(queue, 1, &currSi, i == bindInfoCount - 1 ? fence : nullptr);
7284                 if (VK_SUCCESS != res) return res;
7285             }
7286 
7287             return VK_SUCCESS;
7288         }
7289     }
7290 
on_vkQueuePresentKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkQueue boxed_queue,const VkPresentInfoKHR * pPresentInfo)7291     VkResult on_vkQueuePresentKHR(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
7292                                   VkQueue boxed_queue, const VkPresentInfoKHR* pPresentInfo) {
7293         // Note that on Android guests, this call will actually be handled
7294         // with vkQueueSignalReleaseImageANDROID
7295         auto queue = unbox_VkQueue(boxed_queue);
7296         auto vk = dispatch_VkQueue(boxed_queue);
7297 
7298         return vk->vkQueuePresentKHR(queue, pPresentInfo);
7299     }
7300 
on_vkGetLinearImageLayoutGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkFormat format,VkDeviceSize * pOffset,VkDeviceSize * pRowPitchAlignment)7301     void on_vkGetLinearImageLayoutGOOGLE(android::base::BumpPool* pool,
7302                                          VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
7303                                          VkFormat format, VkDeviceSize* pOffset,
7304                                          VkDeviceSize* pRowPitchAlignment) {
7305         VkDeviceSize offset = 0u;
7306         VkDeviceSize rowPitchAlignment = UINT_MAX;
7307 
7308         bool needToPopulate = false;
7309         {
7310             std::lock_guard<std::mutex> lock(mMutex);
7311 
7312             auto it = mPerFormatLinearImageProperties.find(format);
7313             if (it == mPerFormatLinearImageProperties.end()) {
7314                 needToPopulate = true;
7315             } else {
7316                 const auto& properties = it->second;
7317                 offset = properties.offset;
7318                 rowPitchAlignment = properties.rowPitchAlignment;
7319             }
7320         }
7321 
7322         if (needToPopulate) {
7323             for (uint32_t width = 64; width <= 256; width++) {
7324                 LinearImageCreateInfo linearImageCreateInfo = {
7325                     .extent =
7326                         {
7327                             .width = width,
7328                             .height = 64,
7329                             .depth = 1,
7330                         },
7331                     .format = format,
7332                     .usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
7333                 };
7334 
7335                 VkDeviceSize currOffset = 0u;
7336                 VkDeviceSize currRowPitchAlignment = UINT_MAX;
7337 
7338                 VkImageCreateInfo defaultVkImageCreateInfo = linearImageCreateInfo.toDefaultVk();
7339                 on_vkGetLinearImageLayout2GOOGLE(pool, snapshotInfo, boxed_device,
7340                                                  &defaultVkImageCreateInfo, &currOffset,
7341                                                  &currRowPitchAlignment);
7342 
7343                 offset = currOffset;
7344                 rowPitchAlignment = std::min(currRowPitchAlignment, rowPitchAlignment);
7345             }
7346 
7347             std::lock_guard<std::mutex> lock(mMutex);
7348 
7349             mPerFormatLinearImageProperties[format] = LinearImageProperties{
7350                 .offset = offset,
7351                 .rowPitchAlignment = rowPitchAlignment,
7352             };
7353         }
7354 
7355         if (pOffset) {
7356             *pOffset = offset;
7357         }
7358         if (pRowPitchAlignment) {
7359             *pRowPitchAlignment = rowPitchAlignment;
7360         }
7361     }
7362 
on_vkGetLinearImageLayout2GOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,const VkImageCreateInfo * pCreateInfo,VkDeviceSize * pOffset,VkDeviceSize * pRowPitchAlignment)7363     void on_vkGetLinearImageLayout2GOOGLE(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
7364                                           VkDevice boxed_device,
7365                                           const VkImageCreateInfo* pCreateInfo,
7366                                           VkDeviceSize* pOffset, VkDeviceSize* pRowPitchAlignment)
7367         EXCLUDES(mMutex) {
7368         VkDeviceSize offset = 0u;
7369         VkDeviceSize rowPitchAlignment = UINT_MAX;
7370 
7371         LinearImageCreateInfo linearImageCreateInfo = {
7372             .extent = pCreateInfo->extent,
7373             .format = pCreateInfo->format,
7374             .usage = pCreateInfo->usage,
7375         };
7376 
7377         bool needToPopulate = false;
7378         {
7379             std::lock_guard<std::mutex> lock(mMutex);
7380 
7381             auto it = mLinearImageProperties.find(linearImageCreateInfo);
7382             if (it == mLinearImageProperties.end()) {
7383                 needToPopulate = true;
7384             } else {
7385                 const auto& properties = it->second;
7386                 offset = properties.offset;
7387                 rowPitchAlignment = properties.rowPitchAlignment;
7388             }
7389         }
7390 
7391         if (needToPopulate) {
7392             auto device = unbox_VkDevice(boxed_device);
7393             auto vk = dispatch_VkDevice(boxed_device);
7394 
7395             VkImageSubresource subresource = {
7396                 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
7397                 .mipLevel = 0,
7398                 .arrayLayer = 0,
7399             };
7400 
7401             VkImage image;
7402             VkSubresourceLayout subresourceLayout;
7403 
7404             VkImageCreateInfo defaultVkImageCreateInfo = linearImageCreateInfo.toDefaultVk();
7405             VkResult result = vk->vkCreateImage(device, &defaultVkImageCreateInfo, nullptr, &image);
7406             if (result != VK_SUCCESS) {
7407                 INFO("vkCreateImage failed. size: (%u x %u) result: %d",
7408                         linearImageCreateInfo.extent.width, linearImageCreateInfo.extent.height,
7409                         result);
7410                 return;
7411             }
7412             vk->vkGetImageSubresourceLayout(device, image, &subresource, &subresourceLayout);
7413             vk->vkDestroyImage(device, image, nullptr);
7414 
7415             offset = subresourceLayout.offset;
7416             uint64_t rowPitch = subresourceLayout.rowPitch;
7417             rowPitchAlignment = rowPitch & (~rowPitch + 1);
7418 
7419             std::lock_guard<std::mutex> lock(mMutex);
7420 
7421             mLinearImageProperties[linearImageCreateInfo] = {
7422                 .offset = offset,
7423                 .rowPitchAlignment = rowPitchAlignment,
7424             };
7425         }
7426 
7427         if (pOffset != nullptr) {
7428             *pOffset = offset;
7429         }
7430         if (pRowPitchAlignment != nullptr) {
7431             *pRowPitchAlignment = rowPitchAlignment;
7432         }
7433     }
7434 
7435 #include "VkSubDecoder.cpp"
7436 
on_vkQueueFlushCommandsGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkQueue queue,VkCommandBuffer boxed_commandBuffer,VkDeviceSize dataSize,const void * pData,const VkDecoderContext & context)7437     void on_vkQueueFlushCommandsGOOGLE(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
7438                                        VkQueue queue, VkCommandBuffer boxed_commandBuffer,
7439                                        VkDeviceSize dataSize, const void* pData,
7440                                        const VkDecoderContext& context) {
7441         (void)queue;
7442 
7443         VkCommandBuffer commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
7444         VulkanDispatch* vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
7445         VulkanMemReadingStream* readStream = readstream_VkCommandBuffer(boxed_commandBuffer);
7446         subDecode(readStream, vk, boxed_commandBuffer, commandBuffer, dataSize, pData, context);
7447     }
7448 
on_vkQueueFlushCommandsFromAuxMemoryGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkQueue queue,VkCommandBuffer commandBuffer,VkDeviceMemory deviceMemory,VkDeviceSize dataOffset,VkDeviceSize dataSize,const VkDecoderContext & context)7449     void on_vkQueueFlushCommandsFromAuxMemoryGOOGLE(android::base::BumpPool* pool,
7450                                                     VkSnapshotApiCallInfo*, VkQueue queue,
7451                                                     VkCommandBuffer commandBuffer,
7452                                                     VkDeviceMemory deviceMemory,
7453                                                     VkDeviceSize dataOffset, VkDeviceSize dataSize,
7454                                                     const VkDecoderContext& context) {
7455         // TODO : implement
7456     }
getOrAllocateDescriptorSetFromPoolAndIdLocked(VulkanDispatch * vk,VkDevice device,VkDescriptorPool pool,VkDescriptorSetLayout setLayout,uint64_t poolId,uint32_t pendingAlloc,bool * didAlloc)7457     VkDescriptorSet getOrAllocateDescriptorSetFromPoolAndIdLocked(
7458         VulkanDispatch* vk, VkDevice device, VkDescriptorPool pool, VkDescriptorSetLayout setLayout,
7459         uint64_t poolId, uint32_t pendingAlloc, bool* didAlloc) REQUIRES(mMutex) {
7460         auto* poolInfo = android::base::find(mDescriptorPoolInfo, pool);
7461         if (!poolInfo) {
7462             GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
7463                 << "descriptor pool " << pool << " not found ";
7464         }
7465 
7466         BoxedHandleInfo* setHandleInfo = sBoxedHandleManager.get(poolId);
7467 
7468         if (setHandleInfo->underlying) {
7469             if (pendingAlloc) {
7470                 VkDescriptorSet allocedSet;
7471                 vk->vkFreeDescriptorSets(device, pool, 1,
7472                                          (VkDescriptorSet*)(&setHandleInfo->underlying));
7473                 VkDescriptorSetAllocateInfo dsAi = {
7474                     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 0, pool, 1, &setLayout,
7475                 };
7476                 vk->vkAllocateDescriptorSets(device, &dsAi, &allocedSet);
7477                 setHandleInfo->underlying = (uint64_t)allocedSet;
7478                 initDescriptorSetInfoLocked(device, pool, setLayout, poolId, allocedSet);
7479                 *didAlloc = true;
7480                 return allocedSet;
7481             } else {
7482                 *didAlloc = false;
7483                 return (VkDescriptorSet)(setHandleInfo->underlying);
7484             }
7485         } else {
7486             if (pendingAlloc) {
7487                 VkDescriptorSet allocedSet;
7488                 VkDescriptorSetAllocateInfo dsAi = {
7489                     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 0, pool, 1, &setLayout,
7490                 };
7491                 vk->vkAllocateDescriptorSets(device, &dsAi, &allocedSet);
7492                 setHandleInfo->underlying = (uint64_t)allocedSet;
7493                 initDescriptorSetInfoLocked(device, pool, setLayout, poolId, allocedSet);
7494                 *didAlloc = true;
7495                 return allocedSet;
7496             } else {
7497                 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
7498                     << "descriptor pool " << pool << " wanted to get set with id 0x" << std::hex
7499                     << poolId;
7500                 return nullptr;
7501             }
7502         }
7503     }
7504 
on_vkQueueCommitDescriptorSetUpdatesGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue boxed_queue,uint32_t descriptorPoolCount,const VkDescriptorPool * pDescriptorPools,uint32_t descriptorSetCount,const VkDescriptorSetLayout * pDescriptorSetLayouts,const uint64_t * pDescriptorSetPoolIds,const uint32_t * pDescriptorSetWhichPool,const uint32_t * pDescriptorSetPendingAllocation,const uint32_t * pDescriptorWriteStartingIndices,uint32_t pendingDescriptorWriteCount,const VkWriteDescriptorSet * pPendingDescriptorWrites)7505     void on_vkQueueCommitDescriptorSetUpdatesGOOGLE(
7506         android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkQueue boxed_queue,
7507         uint32_t descriptorPoolCount, const VkDescriptorPool* pDescriptorPools,
7508         uint32_t descriptorSetCount, const VkDescriptorSetLayout* pDescriptorSetLayouts,
7509         const uint64_t* pDescriptorSetPoolIds, const uint32_t* pDescriptorSetWhichPool,
7510         const uint32_t* pDescriptorSetPendingAllocation,
7511         const uint32_t* pDescriptorWriteStartingIndices, uint32_t pendingDescriptorWriteCount,
7512         const VkWriteDescriptorSet* pPendingDescriptorWrites) {
7513         std::lock_guard<std::mutex> lock(mMutex);
7514 
7515         VkDevice device;
7516 
7517         auto queue = unbox_VkQueue(boxed_queue);
7518         auto vk = dispatch_VkQueue(boxed_queue);
7519 
7520         auto* queueInfo = android::base::find(mQueueInfo, queue);
7521         if (queueInfo) {
7522             device = queueInfo->device;
7523         } else {
7524             GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
7525                 << "queue " << queue << "(boxed: " << boxed_queue << ") with no device registered";
7526         }
7527         on_vkQueueCommitDescriptorSetUpdatesGOOGLELocked(
7528             pool, snapshotInfo, vk, device, descriptorPoolCount, pDescriptorPools,
7529             descriptorSetCount, pDescriptorSetLayouts, pDescriptorSetPoolIds,
7530             pDescriptorSetWhichPool, pDescriptorSetPendingAllocation,
7531             pDescriptorWriteStartingIndices, pendingDescriptorWriteCount, pPendingDescriptorWrites);
7532     }
7533 
on_vkQueueCommitDescriptorSetUpdatesGOOGLELocked(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VulkanDispatch * vk,VkDevice device,uint32_t descriptorPoolCount,const VkDescriptorPool * pDescriptorPools,uint32_t descriptorSetCount,const VkDescriptorSetLayout * pDescriptorSetLayouts,const uint64_t * pDescriptorSetPoolIds,const uint32_t * pDescriptorSetWhichPool,const uint32_t * pDescriptorSetPendingAllocation,const uint32_t * pDescriptorWriteStartingIndices,uint32_t pendingDescriptorWriteCount,const VkWriteDescriptorSet * pPendingDescriptorWrites)7534     void on_vkQueueCommitDescriptorSetUpdatesGOOGLELocked(
7535         android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VulkanDispatch* vk,
7536         VkDevice device, uint32_t descriptorPoolCount, const VkDescriptorPool* pDescriptorPools,
7537         uint32_t descriptorSetCount, const VkDescriptorSetLayout* pDescriptorSetLayouts,
7538         const uint64_t* pDescriptorSetPoolIds, const uint32_t* pDescriptorSetWhichPool,
7539         const uint32_t* pDescriptorSetPendingAllocation,
7540         const uint32_t* pDescriptorWriteStartingIndices, uint32_t pendingDescriptorWriteCount,
7541         const VkWriteDescriptorSet* pPendingDescriptorWrites) REQUIRES(mMutex) {
7542         std::vector<VkDescriptorSet> setsToUpdate(descriptorSetCount, nullptr);
7543 
7544         bool didAlloc = false;
7545 
7546         for (uint32_t i = 0; i < descriptorSetCount; ++i) {
7547             uint64_t poolId = pDescriptorSetPoolIds[i];
7548             uint32_t whichPool = pDescriptorSetWhichPool[i];
7549             uint32_t pendingAlloc = pDescriptorSetPendingAllocation[i];
7550             bool didAllocThisTime;
7551             setsToUpdate[i] = getOrAllocateDescriptorSetFromPoolAndIdLocked(
7552                 vk, device, pDescriptorPools[whichPool], pDescriptorSetLayouts[i], poolId,
7553                 pendingAlloc, &didAllocThisTime);
7554 
7555             if (didAllocThisTime) didAlloc = true;
7556         }
7557 
7558         if (didAlloc) {
7559             std::vector<VkWriteDescriptorSet> writeDescriptorSetsForHostDriver(
7560                 pendingDescriptorWriteCount);
7561             memcpy(writeDescriptorSetsForHostDriver.data(), pPendingDescriptorWrites,
7562                    pendingDescriptorWriteCount * sizeof(VkWriteDescriptorSet));
7563 
7564             for (uint32_t i = 0; i < descriptorSetCount; ++i) {
7565                 uint32_t writeStartIndex = pDescriptorWriteStartingIndices[i];
7566                 uint32_t writeEndIndex;
7567                 if (i == descriptorSetCount - 1) {
7568                     writeEndIndex = pendingDescriptorWriteCount;
7569                 } else {
7570                     writeEndIndex = pDescriptorWriteStartingIndices[i + 1];
7571                 }
7572                 for (uint32_t j = writeStartIndex; j < writeEndIndex; ++j) {
7573                     writeDescriptorSetsForHostDriver[j].dstSet = setsToUpdate[i];
7574                 }
7575             }
7576             this->on_vkUpdateDescriptorSetsImpl(
7577                 pool, snapshotInfo, vk, device, (uint32_t)writeDescriptorSetsForHostDriver.size(),
7578                 writeDescriptorSetsForHostDriver.data(), 0, nullptr);
7579         } else {
7580             this->on_vkUpdateDescriptorSetsImpl(pool, snapshotInfo, vk, device,
7581                                                 pendingDescriptorWriteCount,
7582                                                 pPendingDescriptorWrites, 0, nullptr);
7583         }
7584     }
7585 
on_vkCollectDescriptorPoolIdsGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice device,VkDescriptorPool descriptorPool,uint32_t * pPoolIdCount,uint64_t * pPoolIds)7586     void on_vkCollectDescriptorPoolIdsGOOGLE(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
7587                                              VkDevice device, VkDescriptorPool descriptorPool,
7588                                              uint32_t* pPoolIdCount, uint64_t* pPoolIds) {
7589         std::lock_guard<std::mutex> lock(mMutex);
7590         auto& info = mDescriptorPoolInfo[descriptorPool];
7591         *pPoolIdCount = (uint32_t)info.poolIds.size();
7592 
7593         if (pPoolIds) {
7594             for (uint32_t i = 0; i < info.poolIds.size(); ++i) {
7595                 pPoolIds[i] = info.poolIds[i];
7596             }
7597         }
7598     }
7599 
on_vkCreateSamplerYcbcrConversion(android::base::BumpPool *,VkSnapshotApiCallInfo * info,VkDevice boxed_device,const VkSamplerYcbcrConversionCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSamplerYcbcrConversion * pYcbcrConversion)7600     VkResult on_vkCreateSamplerYcbcrConversion(
7601         android::base::BumpPool*, VkSnapshotApiCallInfo* info, VkDevice boxed_device,
7602         const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
7603         const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion) {
7604         if (m_vkEmulation->isYcbcrEmulationEnabled() &&
7605             !m_vkEmulation->supportsSamplerYcbcrConversion()) {
7606             *pYcbcrConversion = new_boxed_non_dispatchable_VkSamplerYcbcrConversion(
7607                 (VkSamplerYcbcrConversion)((uintptr_t)0xffff0000ull));
7608             return VK_SUCCESS;
7609         }
7610         auto device = unbox_VkDevice(boxed_device);
7611         auto vk = dispatch_VkDevice(boxed_device);
7612         VkResult res =
7613             vk->vkCreateSamplerYcbcrConversion(device, pCreateInfo, pAllocator, pYcbcrConversion);
7614         if (res != VK_SUCCESS) {
7615             return res;
7616         }
7617         *pYcbcrConversion = new_boxed_non_dispatchable_VkSamplerYcbcrConversion(*pYcbcrConversion);
7618         return VK_SUCCESS;
7619     }
7620 
on_vkDestroySamplerYcbcrConversion(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkDevice boxed_device,VkSamplerYcbcrConversion ycbcrConversion,const VkAllocationCallbacks * pAllocator)7621     void on_vkDestroySamplerYcbcrConversion(android::base::BumpPool* pool, VkSnapshotApiCallInfo*,
7622                                             VkDevice boxed_device,
7623                                             VkSamplerYcbcrConversion ycbcrConversion,
7624                                             const VkAllocationCallbacks* pAllocator) {
7625         if (m_vkEmulation->isYcbcrEmulationEnabled() &&
7626             !m_vkEmulation->supportsSamplerYcbcrConversion()) {
7627             return;
7628         }
7629         auto device = unbox_VkDevice(boxed_device);
7630         auto vk = dispatch_VkDevice(boxed_device);
7631         vk->vkDestroySamplerYcbcrConversion(device, ycbcrConversion, pAllocator);
7632         return;
7633     }
7634 
on_vkEnumeratePhysicalDeviceGroups(android::base::BumpPool * pool,VkSnapshotApiCallInfo *,VkInstance boxed_instance,uint32_t * pPhysicalDeviceGroupCount,VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties)7635     VkResult on_vkEnumeratePhysicalDeviceGroups(
7636         android::base::BumpPool* pool, VkSnapshotApiCallInfo*, VkInstance boxed_instance,
7637         uint32_t* pPhysicalDeviceGroupCount,
7638         VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
7639         auto instance = unbox_VkInstance(boxed_instance);
7640         auto vk = dispatch_VkInstance(boxed_instance);
7641 
7642         std::vector<VkPhysicalDevice> physicalDevices;
7643         auto res = GetPhysicalDevices(instance, vk, physicalDevices);
7644         if (res != VK_SUCCESS) {
7645             return res;
7646         }
7647 
7648         {
7649             std::lock_guard<std::mutex> lock(mMutex);
7650             FilterPhysicalDevicesLocked(instance, vk, physicalDevices);
7651         }
7652 
7653         const uint32_t requestedCount = pPhysicalDeviceGroupCount ? *pPhysicalDeviceGroupCount : 0;
7654         const uint32_t availableCount = static_cast<uint32_t>(physicalDevices.size());
7655 
7656         if (pPhysicalDeviceGroupCount) {
7657             *pPhysicalDeviceGroupCount = availableCount;
7658         }
7659         if (pPhysicalDeviceGroupCount && pPhysicalDeviceGroupProperties) {
7660             for (uint32_t i = 0; i < std::min(requestedCount, availableCount); ++i) {
7661                 pPhysicalDeviceGroupProperties[i] = VkPhysicalDeviceGroupProperties{
7662                     .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES,
7663                     .pNext = nullptr,
7664                     .physicalDeviceCount = 1,
7665                     .physicalDevices =
7666                         {
7667                             unboxed_to_boxed_VkPhysicalDevice(physicalDevices[i]),
7668                         },
7669                     .subsetAllocation = VK_FALSE,
7670                 };
7671             }
7672             if (requestedCount < availableCount) {
7673                 return VK_INCOMPLETE;
7674             }
7675         }
7676 
7677         return VK_SUCCESS;
7678     }
7679 
on_DeviceLost()7680     void on_DeviceLost() {
7681         m_vkEmulation->getDeviceLostHelper().onDeviceLost();
7682         GFXSTREAM_ABORT(FatalError(VK_ERROR_DEVICE_LOST));
7683     }
7684 
on_CheckOutOfMemory(VkResult result,uint32_t opCode,const VkDecoderContext & context,std::optional<uint64_t> allocationSize=std::nullopt)7685     void on_CheckOutOfMemory(VkResult result, uint32_t opCode, const VkDecoderContext& context,
7686                              std::optional<uint64_t> allocationSize = std::nullopt) {
7687         if (result == VK_ERROR_OUT_OF_HOST_MEMORY || result == VK_ERROR_OUT_OF_DEVICE_MEMORY ||
7688             result == VK_ERROR_OUT_OF_POOL_MEMORY) {
7689             context.metricsLogger->logMetricEvent(
7690                 MetricEventVulkanOutOfMemory{.vkResultCode = result,
7691                                              .opCode = std::make_optional(opCode),
7692                                              .allocationSize = allocationSize});
7693         }
7694     }
7695 
waitForFences(VkDevice unboxed_device,VulkanDispatch * vk,uint32_t fenceCount,const VkFence * pFences,VkBool32 waitAll,uint64_t timeout,bool checkWaitState)7696     VkResult waitForFences(VkDevice unboxed_device, VulkanDispatch* vk, uint32_t fenceCount,
7697                            const VkFence* pFences, VkBool32 waitAll, uint64_t timeout, bool checkWaitState) {
7698         if (!fenceCount) {
7699             return VK_SUCCESS;
7700         }
7701 
7702         const auto startTime = std::chrono::system_clock::now();
7703         for (uint32_t i = 0; i < fenceCount; i++) {
7704             VkFence fence = pFences[i];
7705             {
7706                 std::mutex* fenceMutex = nullptr;
7707                 std::condition_variable* cv = nullptr;
7708                 {
7709                     std::lock_guard<std::mutex> lock(mMutex);
7710                     auto* fenceInfo = android::base::find(mFenceInfo, fence);
7711                     if (!fenceInfo) {
7712                         ERR("%s: Invalid fence information! (%p)", __func__, fence);
7713                         return VK_ERROR_OUT_OF_DEVICE_MEMORY;
7714                     }
7715 
7716                     if (unboxed_device != fenceInfo->device || vk != fenceInfo->vk) {
7717                         ERR("%s: Invalid fence device! (%p, %p, %p)", __func__, fence,
7718                             unboxed_device, fenceInfo->device);
7719                         return VK_ERROR_OUT_OF_HOST_MEMORY;
7720                     }
7721 
7722                     fenceMutex = &fenceInfo->mutex;
7723                     cv = &fenceInfo->cv;
7724                 }
7725 
7726                 // Vulkan specs require fences of vkQueueSubmit to be *externally
7727                 // synchronized*, i.e. we cannot submit a queue while waiting for the
7728                 // fence in another thread. For threads that call this function, they
7729                 // have to wait until a vkQueueSubmit() using this fence is called
7730                 // before calling vkWaitForFences(). So we use a conditional variable
7731                 // and mutex for thread synchronization.
7732                 //
7733                 // See:
7734                 // https://www.khronos.org/registry/vulkan/specs/1.2/html/vkspec.html#fundamentals-threadingbehavior
7735                 // https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/issues/519
7736 
7737                 // Current implementation does not respect waitAll here.
7738                 if (checkWaitState) {
7739                     std::unique_lock<std::mutex> lock(*fenceMutex);
7740                     cv->wait(lock, [this, fence] {
7741                         std::lock_guard<std::mutex> lock(mMutex);
7742                         auto* fenceInfo = android::base::find(mFenceInfo, fence);
7743                         if (!fenceInfo) {
7744                             GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
7745                                 << "Fence was destroyed while waiting.";
7746                         }
7747 
7748                         // Block vkWaitForFences calls until the fence is waitable
7749                         // Should also allow 'kWaiting' stage as the user can call
7750                         // vkWaitForFences multiple times on the same fence.
7751                         if (fenceInfo->state == FenceInfo::State::kNotWaitable) {
7752                             return false;
7753                         }
7754                         fenceInfo->state = FenceInfo::State::kWaiting;
7755                         return true;
7756                     });
7757                 }
7758             }
7759         }
7760 
7761         const auto endTime = std::chrono::system_clock::now();
7762         const uint64_t timePassed = std::chrono::nanoseconds(endTime - startTime).count();
7763         const uint64_t timeoutLeft = (timeout > timePassed) ? timeout - timePassed : 0;
7764         return vk->vkWaitForFences(unboxed_device, fenceCount, pFences, waitAll, timeoutLeft);
7765     }
7766 
waitForFence(VkFence fence,uint64_t timeout)7767     VkResult waitForFence(VkFence fence, uint64_t timeout) {
7768         VkDevice device;
7769         VulkanDispatch* vk;
7770         {
7771             std::lock_guard<std::mutex> lock(mMutex);
7772             auto* fenceInfo = android::base::find(mFenceInfo, fence);
7773             if (!fenceInfo) {
7774                 // No fence, could be a semaphore.
7775                 // TODO: Async wait for semaphores
7776                 return VK_SUCCESS;
7777             }
7778 
7779             device = fenceInfo->device;
7780             vk = fenceInfo->vk;
7781         }
7782 
7783         return waitForFences(device, vk, 1, &fence, true, timeout, true);
7784     }
7785 
7786 
registerQsriCallback(VkImage boxed_image,VkQsriTimeline::Callback callback)7787     AsyncResult registerQsriCallback(VkImage boxed_image, VkQsriTimeline::Callback callback) {
7788         std::lock_guard<std::mutex> lock(mMutex);
7789 
7790         VkImage image = try_unbox_VkImage(boxed_image);
7791         if (image == VK_NULL_HANDLE) return AsyncResult::FAIL_AND_CALLBACK_NOT_SCHEDULED;
7792 
7793         auto imageInfoIt = mImageInfo.find(image);
7794         if (imageInfoIt == mImageInfo.end()) return AsyncResult::FAIL_AND_CALLBACK_NOT_SCHEDULED;
7795         auto& imageInfo = imageInfoIt->second;
7796 
7797         auto* anbInfo = imageInfo.anbInfo.get();
7798         if (!anbInfo) {
7799             ERR("Attempted to register QSRI callback on VkImage:%p without ANB info.", image);
7800             return AsyncResult::FAIL_AND_CALLBACK_NOT_SCHEDULED;
7801         }
7802         return anbInfo->registerQsriCallback(image, std::move(callback));
7803     }
7804 
7805 #define GUEST_EXTERNAL_MEMORY_HANDLE_TYPES                                \
7806     (VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID | \
7807      VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA)
7808 
7809     // Transforms
7810     // If adding a new transform here, please check if it needs to be used in VkDecoderTestDispatch
7811 
transformImpl_VkExternalMemoryProperties_tohost(const VkExternalMemoryProperties * props,uint32_t count)7812     void transformImpl_VkExternalMemoryProperties_tohost(const VkExternalMemoryProperties* props,
7813                                                          uint32_t count) {
7814         VkExternalMemoryProperties* mut = (VkExternalMemoryProperties*)props;
7815         for (uint32_t i = 0; i < count; ++i) {
7816             mut[i] = m_vkEmulation->transformExternalMemoryProperties_tohost(mut[i]);
7817         }
7818     }
transformImpl_VkExternalMemoryProperties_fromhost(const VkExternalMemoryProperties * props,uint32_t count)7819     void transformImpl_VkExternalMemoryProperties_fromhost(const VkExternalMemoryProperties* props,
7820                                                            uint32_t count) {
7821         VkExternalMemoryProperties* mut = (VkExternalMemoryProperties*)props;
7822         for (uint32_t i = 0; i < count; ++i) {
7823             mut[i] = m_vkEmulation->transformExternalMemoryProperties_fromhost(
7824                 mut[i], GUEST_EXTERNAL_MEMORY_HANDLE_TYPES);
7825         }
7826     }
7827 
transformImpl_VkImageCreateInfo_tohost(const VkImageCreateInfo * pImageCreateInfos,uint32_t count)7828     void transformImpl_VkImageCreateInfo_tohost(const VkImageCreateInfo* pImageCreateInfos,
7829                                                 uint32_t count) {
7830         for (uint32_t i = 0; i < count; i++) {
7831             VkImageCreateInfo& imageCreateInfo =
7832                 const_cast<VkImageCreateInfo&>(pImageCreateInfos[i]);
7833             VkExternalMemoryImageCreateInfo* pExternalMemoryImageCi =
7834                 vk_find_struct<VkExternalMemoryImageCreateInfo>(&imageCreateInfo);
7835             bool importAndroidHardwareBuffer =
7836                 pExternalMemoryImageCi &&
7837                 (pExternalMemoryImageCi->handleTypes &
7838                  VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID);
7839             const VkNativeBufferANDROID* pNativeBufferANDROID =
7840                 vk_find_struct<VkNativeBufferANDROID>(&imageCreateInfo);
7841 
7842             if (pExternalMemoryImageCi && pExternalMemoryImageCi->handleTypes &
7843                                               VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT) {
7844                 pExternalMemoryImageCi->handleTypes |=
7845                     m_vkEmulation->getDefaultExternalMemoryHandleType();
7846             }
7847 
7848             // If the VkImage is going to bind to a ColorBuffer, we have to make sure the VkImage
7849             // that backs the ColorBuffer is created with identical parameters. From the spec: If
7850             // two aliases are both images that were created with identical creation parameters,
7851             // both were created with the VK_IMAGE_CREATE_ALIAS_BIT flag set, and both are bound
7852             // identically to memory except for VkBindImageMemoryDeviceGroupInfo::pDeviceIndices and
7853             // VkBindImageMemoryDeviceGroupInfo::pSplitInstanceBindRegions, then they interpret the
7854             // contents of the memory in consistent ways, and data written to one alias can be read
7855             // by the other alias. ... Aliases created by binding the same memory to resources in
7856             // multiple Vulkan instances or external APIs using external memory handle export and
7857             // import mechanisms interpret the contents of the memory in consistent ways, and data
7858             // written to one alias can be read by the other alias. Otherwise, the aliases interpret
7859             // the contents of the memory differently, ...
7860             std::unique_ptr<VkImageCreateInfo> colorBufferVkImageCi = nullptr;
7861             const char* importSourceDebug = "";
7862             VkFormat resolvedFormat = VK_FORMAT_UNDEFINED;
7863             // Use UNORM formats for SRGB format requests.
7864             switch (imageCreateInfo.format) {
7865                 case VK_FORMAT_R8G8B8A8_SRGB:
7866                     resolvedFormat = VK_FORMAT_R8G8B8A8_UNORM;
7867                     break;
7868                 case VK_FORMAT_R8G8B8_SRGB:
7869                     resolvedFormat = VK_FORMAT_R8G8B8_UNORM;
7870                     break;
7871                 case VK_FORMAT_B8G8R8A8_SRGB:
7872                     resolvedFormat = VK_FORMAT_B8G8R8A8_UNORM;
7873                     break;
7874                 case VK_FORMAT_R8_SRGB:
7875                     resolvedFormat = VK_FORMAT_R8_UNORM;
7876                     break;
7877                 default:
7878                     resolvedFormat = imageCreateInfo.format;
7879             }
7880             if (importAndroidHardwareBuffer) {
7881                 // For AHardwareBufferImage binding, we can't know which ColorBuffer this
7882                 // to-be-created VkImage will bind to, so we try our best to infer the creation
7883                 // parameters.
7884                 colorBufferVkImageCi = m_vkEmulation->generateColorBufferVkImageCreateInfo(
7885                     resolvedFormat, imageCreateInfo.extent.width, imageCreateInfo.extent.height,
7886                     imageCreateInfo.tiling);
7887                 importSourceDebug = "AHardwareBuffer";
7888             } else if (pNativeBufferANDROID) {
7889                 // For native buffer binding, we can query the creation parameters from handle.
7890                 uint32_t cbHandle = *static_cast<const uint32_t*>(pNativeBufferANDROID->handle);
7891 
7892                 const auto colorBufferInfoOpt = m_vkEmulation->getColorBufferInfo(cbHandle);
7893                 if (colorBufferInfoOpt) {
7894                     const auto& colorBufferInfo = *colorBufferInfoOpt;
7895                     colorBufferVkImageCi =
7896                         std::make_unique<VkImageCreateInfo>(colorBufferInfo.imageCreateInfoShallow);
7897                 } else {
7898                     ERR("Unknown ColorBuffer handle: %" PRIu32 ".", cbHandle);
7899                 }
7900                 importSourceDebug = "NativeBufferANDROID";
7901             }
7902             if (!colorBufferVkImageCi) {
7903                 continue;
7904             }
7905             imageCreateInfo.format = resolvedFormat;
7906             if (imageCreateInfo.flags & (~colorBufferVkImageCi->flags)) {
7907                 ERR("The VkImageCreateInfo to import %s contains unsupported VkImageCreateFlags. "
7908                     "All supported VkImageCreateFlags are %s, the input VkImageCreateInfo requires "
7909                     "support for %s.",
7910                     importSourceDebug,
7911                     string_VkImageCreateFlags(colorBufferVkImageCi->flags).c_str()?:"",
7912                     string_VkImageCreateFlags(imageCreateInfo.flags).c_str()?:"");
7913             }
7914             imageCreateInfo.flags |= colorBufferVkImageCi->flags;
7915             if (imageCreateInfo.imageType != colorBufferVkImageCi->imageType) {
7916                 ERR("The VkImageCreateInfo to import %s has an unexpected VkImageType: %s, %s "
7917                     "expected.",
7918                     importSourceDebug, string_VkImageType(imageCreateInfo.imageType),
7919                     string_VkImageType(colorBufferVkImageCi->imageType));
7920             }
7921             if (imageCreateInfo.extent.depth != colorBufferVkImageCi->extent.depth) {
7922                 ERR("The VkImageCreateInfo to import %s has an unexpected VkExtent::depth: %" PRIu32
7923                     ", %" PRIu32 " expected.",
7924                     importSourceDebug, imageCreateInfo.extent.depth,
7925                     colorBufferVkImageCi->extent.depth);
7926             }
7927             if (imageCreateInfo.mipLevels != colorBufferVkImageCi->mipLevels) {
7928                 ERR("The VkImageCreateInfo to import %s has an unexpected mipLevels: %" PRIu32
7929                     ", %" PRIu32 " expected.",
7930                     importSourceDebug, imageCreateInfo.mipLevels,
7931                     colorBufferVkImageCi->mipLevels);
7932             }
7933             if (imageCreateInfo.arrayLayers != colorBufferVkImageCi->arrayLayers) {
7934                 ERR("The VkImageCreateInfo to import %s has an unexpected arrayLayers: %" PRIu32
7935                     ", %" PRIu32 " expected.",
7936                     importSourceDebug, imageCreateInfo.arrayLayers,
7937                     colorBufferVkImageCi->arrayLayers);
7938             }
7939             if (imageCreateInfo.samples != colorBufferVkImageCi->samples) {
7940                 ERR("The VkImageCreateInfo to import %s has an unexpected VkSampleCountFlagBits: "
7941                     "%s, %s expected.",
7942                     importSourceDebug, string_VkSampleCountFlagBits(imageCreateInfo.samples),
7943                     string_VkSampleCountFlagBits(colorBufferVkImageCi->samples));
7944             }
7945             if (imageCreateInfo.usage & (~colorBufferVkImageCi->usage)) {
7946                 ERR("The VkImageCreateInfo to import %s contains unsupported VkImageUsageFlags. "
7947                     "All supported VkImageUsageFlags are %s, the input VkImageCreateInfo requires "
7948                     "support for %s.",
7949                     importSourceDebug,
7950                     string_VkImageUsageFlags(colorBufferVkImageCi->usage).c_str()?:"",
7951                     string_VkImageUsageFlags(imageCreateInfo.usage).c_str()?:"");
7952             }
7953             imageCreateInfo.usage |= colorBufferVkImageCi->usage;
7954             // For the AndroidHardwareBuffer binding case VkImageCreateInfo::sharingMode isn't
7955             // filled in generateColorBufferVkImageCreateInfo, and
7956             // VkImageCreateInfo::{format,extent::{width, height}, tiling} are guaranteed to match.
7957             if (importAndroidHardwareBuffer) {
7958                 continue;
7959             }
7960             if (resolvedFormat != colorBufferVkImageCi->format) {
7961                 ERR("The VkImageCreateInfo to import %s contains unexpected VkFormat:"
7962                     "%s [%d]. %s [%d] expected.",
7963                     importSourceDebug, string_VkFormat(imageCreateInfo.format),
7964                     imageCreateInfo.format, string_VkFormat(colorBufferVkImageCi->format),
7965                     colorBufferVkImageCi->format);
7966             }
7967             if (imageCreateInfo.extent.width != colorBufferVkImageCi->extent.width) {
7968                 ERR("The VkImageCreateInfo to import %s contains unexpected VkExtent::width: "
7969                     "%" PRIu32 ". %" PRIu32 " expected.",
7970                     importSourceDebug, imageCreateInfo.extent.width,
7971                     colorBufferVkImageCi->extent.width);
7972             }
7973             if (imageCreateInfo.extent.height != colorBufferVkImageCi->extent.height) {
7974                 ERR("The VkImageCreateInfo to import %s contains unexpected VkExtent::height: "
7975                     "%" PRIu32 ". %" PRIu32 " expected.",
7976                     importSourceDebug, imageCreateInfo.extent.height,
7977                     colorBufferVkImageCi->extent.height);
7978             }
7979             if (imageCreateInfo.tiling != colorBufferVkImageCi->tiling) {
7980                 ERR("The VkImageCreateInfo to import %s contains unexpected VkImageTiling: %s. %s "
7981                     "expected.",
7982                     importSourceDebug, string_VkImageTiling(imageCreateInfo.tiling),
7983                     string_VkImageTiling(colorBufferVkImageCi->tiling));
7984             }
7985             if (imageCreateInfo.sharingMode != colorBufferVkImageCi->sharingMode) {
7986                 ERR("The VkImageCreateInfo to import %s contains unexpected VkSharingMode: %s. %s "
7987                     "expected.",
7988                     importSourceDebug, string_VkSharingMode(imageCreateInfo.sharingMode),
7989                     string_VkSharingMode(colorBufferVkImageCi->sharingMode));
7990             }
7991         }
7992     }
7993 
transformImpl_VkImageCreateInfo_fromhost(const VkImageCreateInfo *,uint32_t)7994     void transformImpl_VkImageCreateInfo_fromhost(const VkImageCreateInfo*, uint32_t) {
7995         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Not yet implemented.";
7996     }
7997 
7998 #define DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(type, field)                                      \
7999     void transformImpl_##type##_tohost(const type* props, uint32_t count) {                     \
8000         type* mut = (type*)props;                                                               \
8001         for (uint32_t i = 0; i < count; ++i) {                                                  \
8002             mut[i].field =                                                                      \
8003                 (VkExternalMemoryHandleTypeFlagBits)                                            \
8004                     m_vkEmulation->transformExternalMemoryHandleTypeFlags_tohost(mut[i].field); \
8005         }                                                                                       \
8006     }                                                                                           \
8007     void transformImpl_##type##_fromhost(const type* props, uint32_t count) {                   \
8008         type* mut = (type*)props;                                                               \
8009         for (uint32_t i = 0; i < count; ++i) {                                                  \
8010             mut[i].field = (VkExternalMemoryHandleTypeFlagBits)                                 \
8011                                m_vkEmulation->transformExternalMemoryHandleTypeFlags_fromhost(  \
8012                                    mut[i].field, GUEST_EXTERNAL_MEMORY_HANDLE_TYPES);           \
8013         }                                                                                       \
8014     }
8015 
8016 #define DEFINE_EXTERNAL_MEMORY_PROPERTIES_TRANSFORM(type)                                 \
8017     void transformImpl_##type##_tohost(const type* props, uint32_t count) {               \
8018         type* mut = (type*)props;                                                         \
8019         for (uint32_t i = 0; i < count; ++i) {                                            \
8020             mut[i].externalMemoryProperties =                                             \
8021                 m_vkEmulation->transformExternalMemoryProperties_tohost(                  \
8022                     mut[i].externalMemoryProperties);                                     \
8023         }                                                                                 \
8024     }                                                                                     \
8025     void transformImpl_##type##_fromhost(const type* props, uint32_t count) {             \
8026         type* mut = (type*)props;                                                         \
8027         for (uint32_t i = 0; i < count; ++i) {                                            \
8028             mut[i].externalMemoryProperties =                                             \
8029                 m_vkEmulation->transformExternalMemoryProperties_fromhost(                \
8030                     mut[i].externalMemoryProperties, GUEST_EXTERNAL_MEMORY_HANDLE_TYPES); \
8031         }                                                                                 \
8032     }
8033 
DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(VkPhysicalDeviceExternalImageFormatInfo,handleType)8034     DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(VkPhysicalDeviceExternalImageFormatInfo, handleType)
8035     DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(VkPhysicalDeviceExternalBufferInfo, handleType)
8036     DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(VkExternalMemoryImageCreateInfo, handleTypes)
8037     DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(VkExternalMemoryBufferCreateInfo, handleTypes)
8038     DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(VkExportMemoryAllocateInfo, handleTypes)
8039     DEFINE_EXTERNAL_MEMORY_PROPERTIES_TRANSFORM(VkExternalImageFormatProperties)
8040     DEFINE_EXTERNAL_MEMORY_PROPERTIES_TRANSFORM(VkExternalBufferProperties)
8041 
8042     BoxedHandle newGlobalHandle(const BoxedHandleInfo& item, BoxedHandleTypeTag typeTag) {
8043         return sBoxedHandleManager.add(item, typeTag);
8044     }
8045 
snapshot()8046     VkDecoderSnapshot* snapshot() { return &mSnapshot; }
8047 
isSnapshotCurrentlyLoading() const8048     bool isSnapshotCurrentlyLoading() const { return mSnapshotState == SnapshotState::Loading; }
8049 
8050    private:
isEmulatedInstanceExtension(const char * name) const8051     bool isEmulatedInstanceExtension(const char* name) const {
8052         for (auto emulatedExt : kEmulatedInstanceExtensions) {
8053             if (!strcmp(emulatedExt, name)) return true;
8054         }
8055         return false;
8056     }
8057 
isEmulatedDeviceExtension(const char * name) const8058     bool isEmulatedDeviceExtension(const char* name) const {
8059         for (auto emulatedExt : kEmulatedDeviceExtensions) {
8060             if (!strcmp(emulatedExt, name)) return true;
8061         }
8062         return false;
8063     }
8064 
supportEmulatedCompressedImageFormatProperty(VkFormat compressedFormat,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags)8065     bool supportEmulatedCompressedImageFormatProperty(VkFormat compressedFormat, VkImageType type,
8066                                                       VkImageTiling tiling, VkImageUsageFlags usage,
8067                                                       VkImageCreateFlags flags) {
8068         // BUG: 139193497
8069         return !(usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && !(type == VK_IMAGE_TYPE_1D);
8070     }
8071 
filteredDeviceExtensionNames(VulkanDispatch * vk,VkPhysicalDevice physicalDevice,uint32_t count,const char * const * extNames)8072     std::vector<const char*> filteredDeviceExtensionNames(VulkanDispatch* vk,
8073                                                           VkPhysicalDevice physicalDevice,
8074                                                           uint32_t count,
8075                                                           const char* const* extNames) {
8076         std::vector<const char*> res;
8077         std::vector<VkExtensionProperties> properties;
8078         VkResult result;
8079 
8080         for (uint32_t i = 0; i < count; ++i) {
8081             auto extName = extNames[i];
8082             if (!isEmulatedDeviceExtension(extName)) {
8083                 res.push_back(extName);
8084                 continue;
8085             }
8086         }
8087 
8088         result = enumerateDeviceExtensionProperties(vk, physicalDevice, nullptr, properties);
8089         if (result != VK_SUCCESS) {
8090             VKDGS_LOG("failed to enumerate device extensions");
8091             return res;
8092         }
8093 
8094         std::vector<const char*> hostAlwaysDeviceExtensions = {
8095             VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
8096             VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME,
8097             VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
8098             VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME,
8099             VK_KHR_SWAPCHAIN_EXTENSION_NAME,
8100             // TODO(b/378686769): Enable private data extension where available to
8101             // mitigate the issues with duplicated vulkan handles. This should be
8102             // removed once the issue is properly resolved.
8103             VK_EXT_PRIVATE_DATA_EXTENSION_NAME,
8104             // It is not uncommon for a guest app flow to expect to use
8105             // VK_EXT_IMAGE_DRM_FORMAT_MODIFIER without actually enabling it in the
8106             // ppEnabledExtensionNames. Mesa WSI (in Linux) does this, because it has certain
8107             // assumptions about the Vulkan loader architecture it is using. However, depending on
8108             // the host's Vulkan loader architecture, this could in NULL function pointer access
8109             // (i.e. on vkGetImageDrmFormatModifierPropertiesEXT()). So just enable it if it's
8110             // available.
8111             VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME,
8112 #ifdef _WIN32
8113             VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
8114             VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME,
8115 #elif defined(__QNX__)
8116             VK_QNX_EXTERNAL_MEMORY_SCREEN_BUFFER_EXTENSION_NAME,
8117             // EXT_queue_family_foreign is an extension dependency of
8118             // VK_QNX_external_memory_screen_buffer
8119             VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME,
8120             VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
8121 #elif __unix__
8122             VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
8123             VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
8124 #endif
8125         };
8126 
8127 #if defined(__APPLE__)
8128         if (m_vkEmulation->supportsMoltenVk()) {
8129             hostAlwaysDeviceExtensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME);
8130             hostAlwaysDeviceExtensions.push_back(VK_EXT_METAL_OBJECTS_EXTENSION_NAME);
8131             hostAlwaysDeviceExtensions.push_back(VK_EXT_EXTERNAL_MEMORY_METAL_EXTENSION_NAME);
8132         } else {
8133             // Non-MoltenVK path, use memory_fd
8134             hostAlwaysDeviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
8135         }
8136 #endif
8137 
8138 #if defined(__linux__)
8139         // A dma-buf is a Linux kernel construct, commonly used with open-source DRM drivers.
8140         // See https://docs.kernel.org/driver-api/dma-buf.html for details.
8141         if (m_vkEmulation->supportsDmaBuf()) {
8142             hostAlwaysDeviceExtensions.push_back(VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME);
8143         }
8144 #endif
8145 
8146         // Enable all the device extensions that should always be enabled on the host (if available)
8147         for (auto extName : hostAlwaysDeviceExtensions) {
8148             if (hasDeviceExtension(properties, extName)) {
8149                 res.push_back(extName);
8150             }
8151         }
8152 
8153         return res;
8154     }
8155 
filteredInstanceExtensionNames(uint32_t count,const char * const * extNames)8156     std::vector<const char*> filteredInstanceExtensionNames(uint32_t count,
8157                                                             const char* const* extNames) {
8158         std::vector<const char*> res;
8159         for (uint32_t i = 0; i < count; ++i) {
8160             auto extName = extNames[i];
8161             if (!isEmulatedInstanceExtension(extName)) {
8162                 res.push_back(extName);
8163             }
8164         }
8165 
8166         if (m_vkEmulation->supportsExternalMemoryCapabilities()) {
8167             res.push_back(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME);
8168         }
8169 
8170         if (m_vkEmulation->supportsExternalSemaphoreCapabilities()) {
8171             res.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
8172         }
8173 
8174         if (m_vkEmulation->supportsExternalFenceCapabilities()) {
8175             res.push_back(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME);
8176         }
8177 
8178         if (m_vkEmulation->debugUtilsEnabled()) {
8179             res.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
8180         }
8181 
8182         if (m_vkEmulation->supportsSurfaces()) {
8183             res.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
8184         }
8185 
8186 #if defined(__APPLE__)
8187         if (m_vkEmulation->supportsMoltenVk()) {
8188             res.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME);
8189             res.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
8190         }
8191 #endif
8192 
8193         return res;
8194     }
8195 
getDefaultQueueForDeviceLocked(VkDevice device,VkQueue * queue,uint32_t * queueFamilyIndex,std::mutex ** queueMutex)8196     bool getDefaultQueueForDeviceLocked(VkDevice device, VkQueue* queue, uint32_t* queueFamilyIndex,
8197                                         std::mutex** queueMutex) REQUIRES(mMutex) {
8198         auto* deviceInfo = android::base::find(mDeviceInfo, device);
8199         if (!deviceInfo) return false;
8200 
8201         auto zeroIt = deviceInfo->queues.find(0);
8202         if (zeroIt == deviceInfo->queues.end() || zeroIt->second.empty()) {
8203             // Get the first queue / queueFamilyIndex
8204             // that does show up.
8205             for (const auto& it : deviceInfo->queues) {
8206                 auto index = it.first;
8207                 for (auto& deviceQueue : it.second) {
8208                     *queue = deviceQueue;
8209                     *queueFamilyIndex = index;
8210                     *queueMutex = mQueueInfo.at(deviceQueue).queueMutex.get();
8211                     return true;
8212                 }
8213             }
8214             // Didn't find anything, fail.
8215             return false;
8216         } else {
8217             // Use queue family index 0.
8218             *queue = zeroIt->second[0];
8219             *queueFamilyIndex = 0;
8220             *queueMutex = mQueueInfo.at(zeroIt->second[0]).queueMutex.get();
8221             return true;
8222         }
8223 
8224         return false;
8225     }
8226 
updateImageMemorySizeLocked(VkDevice device,VkImage image,VkMemoryRequirements * pMemoryRequirements)8227     void updateImageMemorySizeLocked(VkDevice device, VkImage image,
8228                                      VkMemoryRequirements* pMemoryRequirements) REQUIRES(mMutex) {
8229         auto* deviceInfo = android::base::find(mDeviceInfo, device);
8230         if (!deviceInfo->emulateTextureEtc2 && !deviceInfo->emulateTextureAstc) {
8231             return;
8232         }
8233         auto* imageInfo = android::base::find(mImageInfo, image);
8234         if (!imageInfo) return;
8235         CompressedImageInfo& cmpInfo = imageInfo->cmpInfo;
8236         if (!deviceInfo->needEmulatedDecompression(cmpInfo)) {
8237             return;
8238         }
8239         *pMemoryRequirements = cmpInfo.getMemoryRequirements();
8240     }
8241 
8242     // Whether the VkInstance associated with this physical device was created by ANGLE
isAngleInstanceLocked(VkPhysicalDevice physicalDevice,VulkanDispatch * vk)8243     bool isAngleInstanceLocked(VkPhysicalDevice physicalDevice, VulkanDispatch* vk)
8244         REQUIRES(mMutex) {
8245         VkInstance* instance = android::base::find(mPhysicalDeviceToInstance, physicalDevice);
8246         if (!instance) return false;
8247         InstanceInfo* instanceInfo = android::base::find(mInstanceInfo, *instance);
8248         if (!instanceInfo) return false;
8249         return instanceInfo->isAngle;
8250     }
8251 
enableEmulatedEtc2Locked(VkPhysicalDevice physicalDevice,VulkanDispatch * vk)8252     bool enableEmulatedEtc2Locked(VkPhysicalDevice physicalDevice, VulkanDispatch* vk)
8253         REQUIRES(mMutex) {
8254         if (!m_vkEmulation->isEtc2EmulationEnabled()) return false;
8255 
8256         // Don't enable ETC2 emulation for ANGLE, let it do its own emulation.
8257         return !isAngleInstanceLocked(physicalDevice, vk);
8258     }
8259 
enableEmulatedAstcLocked(VkPhysicalDevice physicalDevice,VulkanDispatch * vk)8260     bool enableEmulatedAstcLocked(VkPhysicalDevice physicalDevice, VulkanDispatch* vk)
8261         REQUIRES(mMutex) {
8262         if (m_vkEmulation->getAstcLdrEmulationMode() == AstcEmulationMode::Disabled) {
8263             return false;
8264         }
8265 
8266         // Don't enable ASTC emulation for ANGLE, let it do its own emulation.
8267         return !isAngleInstanceLocked(physicalDevice, vk);
8268     }
8269 
needEmulatedEtc2(VkPhysicalDevice physicalDevice,VulkanDispatch * vk)8270     bool needEmulatedEtc2(VkPhysicalDevice physicalDevice, VulkanDispatch* vk) EXCLUDES(mMutex) {
8271         {
8272             std::lock_guard<std::mutex> lock(mMutex);
8273             if (!enableEmulatedEtc2Locked(physicalDevice, vk)) {
8274                 return false;
8275             }
8276         }
8277 
8278         VkPhysicalDeviceFeatures feature;
8279         vk->vkGetPhysicalDeviceFeatures(physicalDevice, &feature);
8280         return !feature.textureCompressionETC2;
8281     }
8282 
needEmulatedAstc(VkPhysicalDevice physicalDevice,VulkanDispatch * vk)8283     bool needEmulatedAstc(VkPhysicalDevice physicalDevice, VulkanDispatch* vk) EXCLUDES(mMutex) {
8284         {
8285             std::lock_guard<std::mutex> lock(mMutex);
8286             if (!enableEmulatedAstcLocked(physicalDevice, vk)) {
8287                 return false;
8288             }
8289         }
8290         VkPhysicalDeviceFeatures feature;
8291         vk->vkGetPhysicalDeviceFeatures(physicalDevice, &feature);
8292         return !feature.textureCompressionASTC_LDR;
8293     }
8294 
getSupportedFenceHandleTypes(VulkanDispatch * vk,VkPhysicalDevice physicalDevice,uint32_t * supportedFenceHandleTypes)8295     void getSupportedFenceHandleTypes(VulkanDispatch* vk, VkPhysicalDevice physicalDevice,
8296                                       uint32_t* supportedFenceHandleTypes) {
8297         if (!m_vkEmulation->supportsExternalFenceCapabilities()) {
8298             return;
8299         }
8300 
8301         VkExternalFenceHandleTypeFlagBits handleTypes[] = {
8302             VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR,
8303             VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT,
8304             VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
8305         };
8306 
8307         for (auto handleType : handleTypes) {
8308             VkExternalFenceProperties externalFenceProps;
8309             externalFenceProps.sType = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES;
8310             externalFenceProps.pNext = nullptr;
8311 
8312             VkPhysicalDeviceExternalFenceInfo externalFenceInfo = {
8313                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, nullptr, handleType};
8314 
8315             vk->vkGetPhysicalDeviceExternalFenceProperties(physicalDevice, &externalFenceInfo,
8316                                                            &externalFenceProps);
8317 
8318             if ((externalFenceProps.externalFenceFeatures &
8319                  (VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT)) == 0) {
8320                 continue;
8321             }
8322 
8323             if ((externalFenceProps.externalFenceFeatures &
8324                  (VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT)) == 0) {
8325                 continue;
8326             }
8327 
8328             *supportedFenceHandleTypes |= handleType;
8329         }
8330     }
8331 
getSupportedSemaphoreHandleTypes(VulkanDispatch * vk,VkPhysicalDevice physicalDevice,uint32_t * supportedBinarySemaphoreHandleTypes)8332     void getSupportedSemaphoreHandleTypes(VulkanDispatch* vk, VkPhysicalDevice physicalDevice,
8333                                           uint32_t* supportedBinarySemaphoreHandleTypes) {
8334         if (!m_vkEmulation->supportsExternalSemaphoreCapabilities()) {
8335             return;
8336         }
8337 
8338         VkExternalSemaphoreHandleTypeFlagBits handleTypes[] = {
8339             VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR,
8340             VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
8341             VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
8342         };
8343 
8344         for (auto handleType : handleTypes) {
8345             VkExternalSemaphoreProperties externalSemaphoreProps;
8346             externalSemaphoreProps.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES;
8347             externalSemaphoreProps.pNext = nullptr;
8348 
8349             VkPhysicalDeviceExternalSemaphoreInfo externalSemaphoreInfo = {
8350                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, nullptr, handleType};
8351 
8352             vk->vkGetPhysicalDeviceExternalSemaphoreProperties(
8353                 physicalDevice, &externalSemaphoreInfo, &externalSemaphoreProps);
8354 
8355             if ((externalSemaphoreProps.externalSemaphoreFeatures &
8356                  (VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT)) == 0) {
8357                 continue;
8358             }
8359 
8360             if ((externalSemaphoreProps.externalSemaphoreFeatures &
8361                  (VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT)) == 0) {
8362                 continue;
8363             }
8364 
8365             *supportedBinarySemaphoreHandleTypes |= handleType;
8366         }
8367     }
8368 
supportsSwapchainMaintenance1(VkPhysicalDevice physicalDevice,VulkanDispatch * vk)8369     bool supportsSwapchainMaintenance1(VkPhysicalDevice physicalDevice, VulkanDispatch* vk) {
8370         bool hasGetPhysicalDeviceFeatures2 = false;
8371         bool hasGetPhysicalDeviceFeatures2KHR = false;
8372 
8373         {
8374             std::lock_guard<std::mutex> lock(mMutex);
8375 
8376             auto* physdevInfo = android::base::find(mPhysdevInfo, physicalDevice);
8377             if (!physdevInfo) {
8378                 return false;
8379             }
8380 
8381             auto instance = mPhysicalDeviceToInstance[physicalDevice];
8382             auto* instanceInfo = android::base::find(mInstanceInfo, instance);
8383             if (!instanceInfo) {
8384                 return false;
8385             }
8386 
8387             if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
8388                 physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
8389                 hasGetPhysicalDeviceFeatures2 = true;
8390             } else if (hasInstanceExtension(instance,
8391                                             VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
8392                 hasGetPhysicalDeviceFeatures2KHR = true;
8393             } else {
8394                 return false;
8395             }
8396         }
8397 
8398         VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchainMaintenance1Features = {
8399             .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT,
8400             .pNext = nullptr,
8401             .swapchainMaintenance1 = VK_FALSE,
8402         };
8403         VkPhysicalDeviceFeatures2 features2 = {
8404             .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
8405             .pNext = &swapchainMaintenance1Features,
8406         };
8407         if (hasGetPhysicalDeviceFeatures2) {
8408             vk->vkGetPhysicalDeviceFeatures2(physicalDevice, &features2);
8409         } else if (hasGetPhysicalDeviceFeatures2KHR) {
8410             vk->vkGetPhysicalDeviceFeatures2KHR(physicalDevice, &features2);
8411         } else {
8412             return false;
8413         }
8414 
8415         return swapchainMaintenance1Features.swapchainMaintenance1 == VK_TRUE;
8416     }
8417 
isEmulatedCompressedTexture(VkFormat format,VkPhysicalDevice physicalDevice,VulkanDispatch * vk)8418     bool isEmulatedCompressedTexture(VkFormat format, VkPhysicalDevice physicalDevice,
8419                                      VulkanDispatch* vk) EXCLUDES(mMutex) {
8420         return (gfxstream::vk::isEtc2(format) && needEmulatedEtc2(physicalDevice, vk)) ||
8421                (gfxstream::vk::isAstc(format) && needEmulatedAstc(physicalDevice, vk));
8422     }
8423 
8424     static const VkFormatFeatureFlags kEmulatedTextureBufferFeatureMask =
8425         VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
8426         VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
8427 
8428     static const VkFormatFeatureFlags kEmulatedTextureOptimalTilingMask =
8429         VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
8430         VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
8431         VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
8432 
maskFormatPropertiesForEmulatedTextures(VkFormatProperties * pFormatProp)8433     void maskFormatPropertiesForEmulatedTextures(VkFormatProperties* pFormatProp) {
8434         pFormatProp->linearTilingFeatures &= kEmulatedTextureBufferFeatureMask;
8435         pFormatProp->optimalTilingFeatures &= kEmulatedTextureOptimalTilingMask;
8436         pFormatProp->bufferFeatures &= kEmulatedTextureBufferFeatureMask;
8437     }
8438 
maskFormatPropertiesForEmulatedTextures(VkFormatProperties2 * pFormatProp)8439     void maskFormatPropertiesForEmulatedTextures(VkFormatProperties2* pFormatProp) {
8440         pFormatProp->formatProperties.linearTilingFeatures &= kEmulatedTextureBufferFeatureMask;
8441         pFormatProp->formatProperties.optimalTilingFeatures &= kEmulatedTextureOptimalTilingMask;
8442         pFormatProp->formatProperties.bufferFeatures &= kEmulatedTextureBufferFeatureMask;
8443     }
8444 
maskImageFormatPropertiesForEmulatedTextures(VkImageFormatProperties * pProperties)8445     void maskImageFormatPropertiesForEmulatedTextures(VkImageFormatProperties* pProperties) {
8446         // dEQP-VK.api.info.image_format_properties.2d.optimal#etc2_r8g8b8_unorm_block
8447         pProperties->sampleCounts &= VK_SAMPLE_COUNT_1_BIT;
8448     }
8449 
8450     template <class VkFormatProperties1or2>
getPhysicalDeviceFormatPropertiesCore(std::function<void (VkPhysicalDevice,VkFormat,VkFormatProperties1or2 *)> getPhysicalDeviceFormatPropertiesFunc,VulkanDispatch * vk,VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties1or2 * pFormatProperties)8451     void getPhysicalDeviceFormatPropertiesCore(
8452         std::function<void(VkPhysicalDevice, VkFormat, VkFormatProperties1or2*)>
8453             getPhysicalDeviceFormatPropertiesFunc,
8454         VulkanDispatch* vk, VkPhysicalDevice physicalDevice, VkFormat format,
8455         VkFormatProperties1or2* pFormatProperties) EXCLUDES(mMutex) {
8456         if (isEmulatedCompressedTexture(format, physicalDevice, vk)) {
8457             getPhysicalDeviceFormatPropertiesFunc(
8458                 physicalDevice, CompressedImageInfo::getOutputFormat(format),
8459                 pFormatProperties);
8460             maskFormatPropertiesForEmulatedTextures(pFormatProperties);
8461             return;
8462         }
8463         getPhysicalDeviceFormatPropertiesFunc(physicalDevice, format, pFormatProperties);
8464     }
8465 
8466     template <typename VkHandleToInfoMap,
8467               typename VkHandleType = typename std::decay_t<VkHandleToInfoMap>::key_type>
extractInfosWithDeviceInto(VkDevice device,VkHandleToInfoMap & inputMap,VkHandleToInfoMap & outputMap)8468     void extractInfosWithDeviceInto(VkDevice device, VkHandleToInfoMap& inputMap,
8469                                     VkHandleToInfoMap& outputMap) {
8470         for (auto it = inputMap.begin(); it != inputMap.end();) {
8471             // "Extracting a node invalidates only the iterators to the extracted element ..."
8472             auto current = it++;
8473 
8474             auto& info = current->second;
8475             if (info.device == device) {
8476                 outputMap.insert(inputMap.extract(current));
8477             }
8478         }
8479     }
8480 
extractDeviceAndDependenciesLocked(VkDevice device,InstanceObjects::DeviceObjects & deviceObjects)8481     void extractDeviceAndDependenciesLocked(VkDevice device,
8482                                             InstanceObjects::DeviceObjects& deviceObjects) REQUIRES(mMutex) {
8483         extractInfosWithDeviceInto(device, mBufferInfo, deviceObjects.buffers);
8484         extractInfosWithDeviceInto(device, mCommandBufferInfo, deviceObjects.commandBuffers);
8485         extractInfosWithDeviceInto(device, mCommandPoolInfo, deviceObjects.commandPools);
8486         extractInfosWithDeviceInto(device, mDescriptorPoolInfo, deviceObjects.descriptorPools);
8487         extractInfosWithDeviceInto(device, mDescriptorSetInfo, deviceObjects.descriptorSets);
8488         extractInfosWithDeviceInto(device, mDescriptorSetLayoutInfo,
8489                                    deviceObjects.descriptorSetLayouts);
8490         extractInfosWithDeviceInto(device, mMemoryInfo, deviceObjects.memories);
8491         extractInfosWithDeviceInto(device, mFenceInfo, deviceObjects.fences);
8492         extractInfosWithDeviceInto(device, mFramebufferInfo, deviceObjects.framebuffers);
8493         extractInfosWithDeviceInto(device, mImageInfo, deviceObjects.images);
8494         extractInfosWithDeviceInto(device, mImageViewInfo, deviceObjects.imageViews);
8495         extractInfosWithDeviceInto(device, mPipelineCacheInfo, deviceObjects.pipelineCaches);
8496         extractInfosWithDeviceInto(device, mPipelineLayoutInfo, deviceObjects.pipelineLayouts);
8497         extractInfosWithDeviceInto(device, mPipelineInfo, deviceObjects.pipelines);
8498         extractInfosWithDeviceInto(device, mQueueInfo, deviceObjects.queues);
8499         extractInfosWithDeviceInto(device, mRenderPassInfo, deviceObjects.renderPasses);
8500         extractInfosWithDeviceInto(device, mSamplerInfo, deviceObjects.samplers);
8501         extractInfosWithDeviceInto(device, mSemaphoreInfo, deviceObjects.semaphores);
8502         extractInfosWithDeviceInto(device, mShaderModuleInfo, deviceObjects.shaderModules);
8503     }
8504 
extractInstanceAndDependenciesLocked(VkInstance instance,InstanceObjects & objects)8505     void extractInstanceAndDependenciesLocked(VkInstance instance, InstanceObjects& objects) REQUIRES(mMutex) {
8506         auto instanceInfoIt = mInstanceInfo.find(instance);
8507         if (instanceInfoIt == mInstanceInfo.end()) return;
8508 
8509         objects.instance = mInstanceInfo.extract(instanceInfoIt);
8510 
8511         for (auto [device, physicalDevice] : mDeviceToPhysicalDevice) {
8512             auto physicalDeviceInstanceIt = mPhysicalDeviceToInstance.find(physicalDevice);
8513             if (physicalDeviceInstanceIt == mPhysicalDeviceToInstance.end()) continue;
8514             auto physicalDeviceInstance = physicalDeviceInstanceIt->second;
8515 
8516             if (physicalDeviceInstance != instance) continue;
8517             mPhysicalDeviceToInstance.erase(physicalDeviceInstanceIt);
8518 
8519             mPhysdevInfo.erase(physicalDevice);
8520 
8521             auto deviceInfoIt = mDeviceInfo.find(device);
8522             if (deviceInfoIt == mDeviceInfo.end()) continue;
8523 
8524             InstanceObjects::DeviceObjects& deviceObjects = objects.devices.emplace_back();
8525             deviceObjects.device = mDeviceInfo.extract(deviceInfoIt);
8526             extractDeviceAndDependenciesLocked(device, deviceObjects);
8527         }
8528 
8529         for (InstanceObjects::DeviceObjects& deviceObjects : objects.devices) {
8530             mDeviceToPhysicalDevice.erase(deviceObjects.device.key());
8531         }
8532 
8533         for (auto it = mPhysicalDeviceToInstance.begin(); it != mPhysicalDeviceToInstance.end();) {
8534             auto current = it++;
8535             auto physicalDevice = current->first;
8536             auto& physicalDeviceInstance = current->second;
8537             if (physicalDeviceInstance != instance) continue;
8538             mPhysicalDeviceToInstance.erase(current);
8539             mPhysdevInfo.erase(physicalDevice);
8540         }
8541     }
8542 
destroyDeviceObjects(InstanceObjects::DeviceObjects & deviceObjects)8543     void destroyDeviceObjects(InstanceObjects::DeviceObjects& deviceObjects) {
8544             VkDevice device = deviceObjects.device.key();
8545             DeviceInfo& deviceInfo = deviceObjects.device.mapped();
8546             VulkanDispatch* deviceDispatch = dispatch_VkDevice(deviceInfo.boxed);
8547 
8548             // https://bugs.chromium.org/p/chromium/issues/detail?id=1074600
8549             // it's important to idle the device before destroying it!
8550             VkResult res = deviceDispatch->vkDeviceWaitIdle(device);
8551             if (res != VK_SUCCESS) {
8552                 // Something went wrong.. Skip destroying the vulkan objects of the device
8553                 // to avoid further issues.
8554                 ERR("Cannot destroy Vulkan device and objects. "
8555                     "vkDeviceWaitIdle failed with %s [%d].", string_VkResult(res), res);
8556                 return;
8557             }
8558 
8559             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu semaphores.", deviceObjects.semaphores.size());
8560             for (auto& [semaphore, semaphoreInfo] : deviceObjects.semaphores) {
8561                 destroySemaphoreWithExclusiveInfo(device, deviceDispatch, semaphore,
8562                                                   deviceObjects.device.mapped(), semaphoreInfo,
8563                                                   nullptr);
8564             }
8565 
8566             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu samplers.", deviceObjects.samplers.size());
8567             for (auto& [sampler, samplerInfo] : deviceObjects.samplers) {
8568                 destroySamplerWithExclusiveInfo(device, deviceDispatch, sampler, samplerInfo,
8569                                                 nullptr);
8570             }
8571 
8572             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu buffers.", deviceObjects.buffers.size());
8573             for (auto& [buffer, bufferInfo] : deviceObjects.buffers) {
8574                 destroyBufferWithExclusiveInfo(device, deviceDispatch, buffer, bufferInfo, nullptr);
8575             }
8576 
8577             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu imageViews.", deviceObjects.imageViews.size());
8578             for (auto& [imageView, imageViewInfo] : deviceObjects.imageViews) {
8579                 destroyImageViewWithExclusiveInfo(device, deviceDispatch, imageView, imageViewInfo,
8580                                                   nullptr);
8581             }
8582 
8583             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu images.", deviceObjects.images.size());
8584             for (auto& [image, imageInfo] : deviceObjects.images) {
8585                 destroyImageWithExclusiveInfo(device, deviceDispatch, image, imageInfo, nullptr);
8586             }
8587 
8588             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu memories.", deviceObjects.memories.size());
8589             for (auto& [memory, memoryInfo] : deviceObjects.memories) {
8590                 destroyMemoryWithExclusiveInfo(device, deviceDispatch, memory, memoryInfo, nullptr);
8591             }
8592 
8593             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu commandBuffers.", deviceObjects.commandBuffers.size());
8594             for (auto& [commandBuffer, commandBufferInfo] : deviceObjects.commandBuffers) {
8595                 freeCommandBufferWithExclusiveInfos(device, deviceDispatch, commandBuffer,
8596                                                        commandBufferInfo,
8597                                                        deviceObjects.commandPools);
8598             }
8599 
8600             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu commandPools.", deviceObjects.commandPools.size());
8601             for (auto& [commandPool, commandPoolInfo] : deviceObjects.commandPools) {
8602                 destroyCommandPoolWithExclusiveInfo(device, deviceDispatch, commandPool,
8603                                                     commandPoolInfo, deviceObjects.commandBuffers,
8604                                                     nullptr);
8605             }
8606 
8607             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu descriptorPools.", deviceObjects.descriptorPools.size());
8608             for (auto& [descriptorPool, descriptorPoolInfo] : deviceObjects.descriptorPools) {
8609                 destroyDescriptorPoolWithExclusiveInfo(device, deviceDispatch, descriptorPool,
8610                                                        descriptorPoolInfo,
8611                                                        deviceObjects.descriptorSets, nullptr);
8612             }
8613 
8614             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu descriptorSetLayouts.", deviceObjects.descriptorSetLayouts.size());
8615             for (auto& [descriptorSetLayout, descriptorSetLayoutInfo] :
8616                  deviceObjects.descriptorSetLayouts) {
8617                 destroyDescriptorSetLayoutWithExclusiveInfo(
8618                     device, deviceDispatch, descriptorSetLayout, descriptorSetLayoutInfo, nullptr);
8619             }
8620 
8621             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu shaderModules.", deviceObjects.shaderModules.size());
8622             for (auto& [shaderModule, shaderModuleInfo] : deviceObjects.shaderModules) {
8623                 destroyShaderModuleWithExclusiveInfo(device, deviceDispatch, shaderModule,
8624                                                      shaderModuleInfo, nullptr);
8625             }
8626 
8627             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu pipelines.", deviceObjects.pipelines.size());
8628             for (auto& [pipeline, pipelineInfo] : deviceObjects.pipelines) {
8629                 destroyPipelineWithExclusiveInfo(device, deviceDispatch, pipeline, pipelineInfo,
8630                                                  nullptr);
8631             }
8632 
8633             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu pipelineCaches.", deviceObjects.pipelineCaches.size());
8634             for (auto& [pipelineCache, pipelineCacheInfo] : deviceObjects.pipelineCaches) {
8635                 destroyPipelineCacheWithExclusiveInfo(device, deviceDispatch, pipelineCache,
8636                                                       pipelineCacheInfo, nullptr);
8637             }
8638 
8639             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu pipelineLayouts.", deviceObjects.pipelineLayouts.size());
8640             for (auto& [pipelineLayout, pipelineLayoutInfo] : deviceObjects.pipelineLayouts) {
8641                 destroyPipelineLayoutWithExclusiveInfo(device, deviceDispatch, pipelineLayout,
8642                                                       pipelineLayoutInfo, nullptr);
8643             }
8644 
8645             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu framebuffers.", deviceObjects.framebuffers.size());
8646             for (auto& [framebuffer, framebufferInfo] : deviceObjects.framebuffers) {
8647                 destroyFramebufferWithExclusiveInfo(device, deviceDispatch, framebuffer,
8648                                                     framebufferInfo, nullptr);
8649             }
8650 
8651             LOG_CALLS_VERBOSE("destroyDeviceObjects: %zu renderPasses.", deviceObjects.renderPasses.size());
8652             for (auto& [renderPass, renderPassInfo] : deviceObjects.renderPasses) {
8653                 destroyRenderPassWithExclusiveInfo(device, deviceDispatch, renderPass,
8654                                                    renderPassInfo, nullptr);
8655             }
8656 
8657             destroyDeviceWithExclusiveInfo(device, deviceObjects.device.mapped(),
8658                                            deviceObjects.fences, deviceObjects.queues, nullptr);
8659     }
8660 
destroyInstanceObjects(InstanceObjects & objects)8661     void destroyInstanceObjects(InstanceObjects& objects) {
8662         VkInstance instance = objects.instance.key();
8663         InstanceInfo& instanceInfo = objects.instance.mapped();
8664         LOG_CALLS_VERBOSE(
8665             "destroyInstanceObjects called for instance (app:%s, engine:%s) with %d devices.",
8666             instanceInfo.applicationName.c_str(), instanceInfo.engineName.c_str(),
8667             objects.devices.size());
8668 
8669         for (InstanceObjects::DeviceObjects& deviceObjects : objects.devices) {
8670             destroyDeviceObjects(deviceObjects);
8671         }
8672 
8673         m_vk->vkDestroyInstance(instance, nullptr);
8674         INFO("Destroyed VkInstance:%p for application:%s engine:%s.", instance,
8675              instanceInfo.applicationName.c_str(), instanceInfo.engineName.c_str());
8676 
8677 #ifdef CONFIG_AEMU
8678         m_vkEmulation->getCallbacks().unregisterVulkanInstance((uint64_t)instance);
8679 #endif
8680         delete_VkInstance(instanceInfo.boxed);
8681         LOG_CALLS_VERBOSE("destroyInstanceObjects: finished.");
8682     }
8683 
isDescriptorTypeImageInfo(VkDescriptorType descType)8684     bool isDescriptorTypeImageInfo(VkDescriptorType descType) {
8685         return (descType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
8686                (descType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
8687                (descType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
8688                (descType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
8689                (descType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
8690     }
8691 
descriptorTypeContainsImage(VkDescriptorType descType)8692     bool descriptorTypeContainsImage(VkDescriptorType descType) {
8693         return (descType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
8694                (descType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
8695                (descType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
8696                (descType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
8697     }
8698 
descriptorTypeContainsSampler(VkDescriptorType descType)8699     bool descriptorTypeContainsSampler(VkDescriptorType descType) {
8700         return (descType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
8701                (descType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
8702     }
8703 
isDescriptorTypeBufferInfo(VkDescriptorType descType)8704     bool isDescriptorTypeBufferInfo(VkDescriptorType descType) {
8705         return (descType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
8706                (descType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
8707                (descType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
8708                (descType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
8709     }
8710 
isDescriptorTypeBufferView(VkDescriptorType descType)8711     bool isDescriptorTypeBufferView(VkDescriptorType descType) {
8712         return (descType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
8713                (descType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
8714     }
8715 
isDescriptorTypeInlineUniformBlock(VkDescriptorType descType)8716     bool isDescriptorTypeInlineUniformBlock(VkDescriptorType descType) {
8717         return descType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
8718     }
8719 
isDescriptorTypeAccelerationStructure(VkDescriptorType descType)8720     bool isDescriptorTypeAccelerationStructure(VkDescriptorType descType) {
8721         return descType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
8722     }
8723 
descriptorDependencyObjectCount(VkDescriptorType descType)8724     int descriptorDependencyObjectCount(VkDescriptorType descType) {
8725         switch (descType) {
8726             case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
8727                 return 2;
8728             case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
8729             case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
8730             case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
8731             case VK_DESCRIPTOR_TYPE_SAMPLER:
8732             case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
8733             case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
8734             case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
8735             case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
8736             case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
8737             case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
8738                 return 1;
8739             default:
8740                 return 0;
8741         }
8742     }
8743 
8744     struct DescriptorUpdateTemplateInfo {
8745         VkDescriptorUpdateTemplateCreateInfo createInfo;
8746         std::vector<VkDescriptorUpdateTemplateEntry> linearizedTemplateEntries;
8747         // Preallocated pData
8748         std::vector<uint8_t> data;
8749         size_t imageInfoStart;
8750         size_t bufferInfoStart;
8751         size_t bufferViewStart;
8752         size_t inlineUniformBlockStart;
8753     };
8754 
calcLinearizedDescriptorUpdateTemplateInfo(const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo)8755     DescriptorUpdateTemplateInfo calcLinearizedDescriptorUpdateTemplateInfo(
8756         const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo) {
8757         DescriptorUpdateTemplateInfo res;
8758         res.createInfo = *pCreateInfo;
8759 
8760         size_t numImageInfos = 0;
8761         size_t numBufferInfos = 0;
8762         size_t numBufferViews = 0;
8763         size_t numInlineUniformBlocks = 0;
8764 
8765         for (uint32_t i = 0; i < pCreateInfo->descriptorUpdateEntryCount; ++i) {
8766             const auto& entry = pCreateInfo->pDescriptorUpdateEntries[i];
8767             auto type = entry.descriptorType;
8768             auto count = entry.descriptorCount;
8769             if (isDescriptorTypeImageInfo(type)) {
8770                 numImageInfos += count;
8771             } else if (isDescriptorTypeBufferInfo(type)) {
8772                 numBufferInfos += count;
8773             } else if (isDescriptorTypeBufferView(type)) {
8774                 numBufferViews += count;
8775             } else if (type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
8776                 numInlineUniformBlocks += count;
8777             } else {
8778                 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
8779                     << "unknown descriptor type 0x" << std::hex << type;
8780             }
8781         }
8782 
8783         size_t imageInfoBytes = numImageInfos * sizeof(VkDescriptorImageInfo);
8784         size_t bufferInfoBytes = numBufferInfos * sizeof(VkDescriptorBufferInfo);
8785         size_t bufferViewBytes = numBufferViews * sizeof(VkBufferView);
8786         size_t inlineUniformBlockBytes = numInlineUniformBlocks;
8787 
8788         res.data.resize(imageInfoBytes + bufferInfoBytes + bufferViewBytes +
8789                         inlineUniformBlockBytes);
8790         res.imageInfoStart = 0;
8791         res.bufferInfoStart = imageInfoBytes;
8792         res.bufferViewStart = imageInfoBytes + bufferInfoBytes;
8793         res.inlineUniformBlockStart = imageInfoBytes + bufferInfoBytes + bufferViewBytes;
8794 
8795         size_t imageInfoCount = 0;
8796         size_t bufferInfoCount = 0;
8797         size_t bufferViewCount = 0;
8798         size_t inlineUniformBlockCount = 0;
8799 
8800         for (uint32_t i = 0; i < pCreateInfo->descriptorUpdateEntryCount; ++i) {
8801             const auto& entry = pCreateInfo->pDescriptorUpdateEntries[i];
8802             VkDescriptorUpdateTemplateEntry entryForHost = entry;
8803 
8804             auto type = entry.descriptorType;
8805 
8806             if (isDescriptorTypeImageInfo(type)) {
8807                 entryForHost.offset =
8808                     res.imageInfoStart + imageInfoCount * sizeof(VkDescriptorImageInfo);
8809                 entryForHost.stride = sizeof(VkDescriptorImageInfo);
8810                 ++imageInfoCount;
8811             } else if (isDescriptorTypeBufferInfo(type)) {
8812                 entryForHost.offset =
8813                     res.bufferInfoStart + bufferInfoCount * sizeof(VkDescriptorBufferInfo);
8814                 entryForHost.stride = sizeof(VkDescriptorBufferInfo);
8815                 ++bufferInfoCount;
8816             } else if (isDescriptorTypeBufferView(type)) {
8817                 entryForHost.offset = res.bufferViewStart + bufferViewCount * sizeof(VkBufferView);
8818                 entryForHost.stride = sizeof(VkBufferView);
8819                 ++bufferViewCount;
8820             } else if (type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
8821                 entryForHost.offset = res.inlineUniformBlockStart + inlineUniformBlockCount;
8822                 entryForHost.stride = 0;
8823                 inlineUniformBlockCount += entryForHost.descriptorCount;
8824             } else {
8825                 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
8826                     << "unknown descriptor type 0x" << std::hex << type;
8827             }
8828 
8829             res.linearizedTemplateEntries.push_back(entryForHost);
8830         }
8831 
8832         res.createInfo.pDescriptorUpdateEntries = res.linearizedTemplateEntries.data();
8833 
8834         return res;
8835     }
8836 
registerDescriptorUpdateTemplate(VkDescriptorUpdateTemplate descriptorUpdateTemplate,const DescriptorUpdateTemplateInfo & info)8837     void registerDescriptorUpdateTemplate(VkDescriptorUpdateTemplate descriptorUpdateTemplate,
8838                                           const DescriptorUpdateTemplateInfo& info) {
8839         std::lock_guard<std::mutex> lock(mMutex);
8840         mDescriptorUpdateTemplateInfo[descriptorUpdateTemplate] = info;
8841     }
8842 
unregisterDescriptorUpdateTemplate(VkDescriptorUpdateTemplate descriptorUpdateTemplate)8843     void unregisterDescriptorUpdateTemplate(VkDescriptorUpdateTemplate descriptorUpdateTemplate) {
8844         std::lock_guard<std::mutex> lock(mMutex);
8845         mDescriptorUpdateTemplateInfo.erase(descriptorUpdateTemplate);
8846     }
8847 
8848     // Returns the VkInstance associated with a VkDevice, or null if it's not found
deviceToInstanceLocked(VkDevice device)8849     VkInstance* deviceToInstanceLocked(VkDevice device) REQUIRES(mMutex) {
8850         auto* physicalDevice = android::base::find(mDeviceToPhysicalDevice, device);
8851         if (!physicalDevice) return nullptr;
8852         return android::base::find(mPhysicalDeviceToInstance, *physicalDevice);
8853     }
8854 
8855     VulkanDispatch* m_vk;
8856     VkEmulation* m_vkEmulation;
8857     emugl::RenderDocWithMultipleVkInstances* mRenderDocWithMultipleVkInstances = nullptr;
8858     bool mSnapshotsEnabled = false;
8859     bool mBatchedDescriptorSetUpdateEnabled = false;
8860     bool mVkCleanupEnabled = true;
8861     bool mLogging = false;
8862     bool mVerbosePrints = false;
8863     bool mUseOldMemoryCleanupPath = false;
8864 
8865     std::mutex mMutex;
8866 
isBindingFeasibleForAlloc(const DescriptorPoolInfo::PoolState & poolState,const VkDescriptorSetLayoutBinding & binding)8867     bool isBindingFeasibleForAlloc(const DescriptorPoolInfo::PoolState& poolState,
8868                                    const VkDescriptorSetLayoutBinding& binding) {
8869         if (binding.descriptorCount && (poolState.type != binding.descriptorType)) {
8870             return false;
8871         }
8872 
8873         uint32_t availDescriptorCount = poolState.descriptorCount - poolState.used;
8874 
8875         if (availDescriptorCount < binding.descriptorCount) {
8876             return false;
8877         }
8878 
8879         return true;
8880     }
8881 
isBindingFeasibleForFree(const DescriptorPoolInfo::PoolState & poolState,const VkDescriptorSetLayoutBinding & binding)8882     bool isBindingFeasibleForFree(const DescriptorPoolInfo::PoolState& poolState,
8883                                   const VkDescriptorSetLayoutBinding& binding) {
8884         if (poolState.type != binding.descriptorType) return false;
8885         if (poolState.used < binding.descriptorCount) return false;
8886         return true;
8887     }
8888 
allocBindingFeasible(const VkDescriptorSetLayoutBinding & binding,DescriptorPoolInfo::PoolState & poolState)8889     void allocBindingFeasible(const VkDescriptorSetLayoutBinding& binding,
8890                               DescriptorPoolInfo::PoolState& poolState) {
8891         poolState.used += binding.descriptorCount;
8892     }
8893 
freeBindingFeasible(const VkDescriptorSetLayoutBinding & binding,DescriptorPoolInfo::PoolState & poolState)8894     void freeBindingFeasible(const VkDescriptorSetLayoutBinding& binding,
8895                              DescriptorPoolInfo::PoolState& poolState) {
8896         poolState.used -= binding.descriptorCount;
8897     }
8898 
validateDescriptorSetAllocLocked(const VkDescriptorSetAllocateInfo * pAllocateInfo)8899     VkResult validateDescriptorSetAllocLocked(const VkDescriptorSetAllocateInfo* pAllocateInfo)
8900         REQUIRES(mMutex) {
8901         auto* poolInfo = android::base::find(mDescriptorPoolInfo, pAllocateInfo->descriptorPool);
8902         if (!poolInfo) return VK_ERROR_INITIALIZATION_FAILED;
8903 
8904         // Check the number of sets available.
8905         auto setsAvailable = poolInfo->maxSets - poolInfo->usedSets;
8906 
8907         if (setsAvailable < pAllocateInfo->descriptorSetCount) {
8908             return VK_ERROR_OUT_OF_POOL_MEMORY;
8909         }
8910 
8911         // Perform simulated allocation and error out with
8912         // VK_ERROR_OUT_OF_POOL_MEMORY if it fails.
8913         std::vector<DescriptorPoolInfo::PoolState> poolCopy = poolInfo->pools;
8914 
8915         for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; ++i) {
8916             auto setLayoutInfo =
8917                 android::base::find(mDescriptorSetLayoutInfo, pAllocateInfo->pSetLayouts[i]);
8918             if (!setLayoutInfo) return VK_ERROR_INITIALIZATION_FAILED;
8919 
8920             for (const auto& binding : setLayoutInfo->bindings) {
8921                 bool success = false;
8922                 for (auto& pool : poolCopy) {
8923                     if (!isBindingFeasibleForAlloc(pool, binding)) continue;
8924 
8925                     success = true;
8926                     allocBindingFeasible(binding, pool);
8927                     break;
8928                 }
8929 
8930                 if (!success) {
8931                     return VK_ERROR_OUT_OF_POOL_MEMORY;
8932                 }
8933             }
8934         }
8935         return VK_SUCCESS;
8936     }
8937 
applyDescriptorSetAllocationLocked(DescriptorPoolInfo & poolInfo,const std::vector<VkDescriptorSetLayoutBinding> & bindings)8938     void applyDescriptorSetAllocationLocked(
8939         DescriptorPoolInfo& poolInfo, const std::vector<VkDescriptorSetLayoutBinding>& bindings) {
8940         ++poolInfo.usedSets;
8941         for (const auto& binding : bindings) {
8942             for (auto& pool : poolInfo.pools) {
8943                 if (!isBindingFeasibleForAlloc(pool, binding)) continue;
8944                 allocBindingFeasible(binding, pool);
8945                 break;
8946             }
8947         }
8948     }
8949 
removeDescriptorSetAllocationLocked(DescriptorPoolInfo & poolInfo,const std::vector<VkDescriptorSetLayoutBinding> & bindings)8950     void removeDescriptorSetAllocationLocked(
8951         DescriptorPoolInfo& poolInfo, const std::vector<VkDescriptorSetLayoutBinding>& bindings) {
8952         --poolInfo.usedSets;
8953         for (const auto& binding : bindings) {
8954             for (auto& pool : poolInfo.pools) {
8955                 if (!isBindingFeasibleForFree(pool, binding)) continue;
8956                 freeBindingFeasible(binding, pool);
8957                 break;
8958             }
8959         }
8960     }
8961 
8962     // Info tracking for vulkan objects
8963     std::unordered_map<VkInstance, InstanceInfo> mInstanceInfo GUARDED_BY(mMutex);
8964     std::unordered_map<VkPhysicalDevice, PhysicalDeviceInfo> mPhysdevInfo GUARDED_BY(mMutex);
8965     std::unordered_map<VkDevice, DeviceInfo> mDeviceInfo GUARDED_BY(mMutex);
8966 
8967     // Back-reference to the physical device associated with a particular
8968     // VkDevice, and the VkDevice corresponding to a VkQueue.
8969     std::unordered_map<VkDevice, VkPhysicalDevice> mDeviceToPhysicalDevice GUARDED_BY(mMutex);
8970     std::unordered_map<VkPhysicalDevice, VkInstance> mPhysicalDeviceToInstance GUARDED_BY(mMutex);
8971 
8972     // Device objects
8973     std::unordered_map<VkBuffer, BufferInfo> mBufferInfo GUARDED_BY(mMutex);
8974     std::unordered_map<VkCommandBuffer, CommandBufferInfo> mCommandBufferInfo GUARDED_BY(mMutex);
8975     std::unordered_map<VkCommandPool, CommandPoolInfo> mCommandPoolInfo GUARDED_BY(mMutex);
8976     std::unordered_map<VkDescriptorPool, DescriptorPoolInfo> mDescriptorPoolInfo GUARDED_BY(mMutex);
8977     std::unordered_map<VkDescriptorSet, DescriptorSetInfo> mDescriptorSetInfo GUARDED_BY(mMutex);
8978     std::unordered_map<VkDescriptorSetLayout, DescriptorSetLayoutInfo> mDescriptorSetLayoutInfo
8979         GUARDED_BY(mMutex);
8980     std::unordered_map<VkDescriptorUpdateTemplate, DescriptorUpdateTemplateInfo>
8981         mDescriptorUpdateTemplateInfo GUARDED_BY(mMutex);
8982     std::unordered_map<VkDeviceMemory, MemoryInfo> mMemoryInfo GUARDED_BY(mMutex);
8983     std::unordered_map<VkFence, FenceInfo> mFenceInfo GUARDED_BY(mMutex);
8984     std::unordered_map<VkFramebuffer, FramebufferInfo> mFramebufferInfo GUARDED_BY(mMutex);
8985     std::unordered_map<VkImage, ImageInfo> mImageInfo GUARDED_BY(mMutex);
8986     std::unordered_map<VkImageView, ImageViewInfo> mImageViewInfo GUARDED_BY(mMutex);
8987     std::unordered_map<VkPipeline, PipelineInfo> mPipelineInfo GUARDED_BY(mMutex);
8988     std::unordered_map<VkPipelineCache, PipelineCacheInfo> mPipelineCacheInfo GUARDED_BY(mMutex);
8989     std::unordered_map<VkPipelineLayout, PipelineLayoutInfo> mPipelineLayoutInfo GUARDED_BY(mMutex);
8990     std::unordered_map<VkQueue, QueueInfo> mQueueInfo GUARDED_BY(mMutex);
8991     std::unordered_map<VkRenderPass, RenderPassInfo> mRenderPassInfo GUARDED_BY(mMutex);
8992     std::unordered_map<VkSampler, SamplerInfo> mSamplerInfo GUARDED_BY(mMutex);
8993     std::unordered_map<VkSemaphore, SemaphoreInfo> mSemaphoreInfo GUARDED_BY(mMutex);
8994     std::unordered_map<VkShaderModule, ShaderModuleInfo> mShaderModuleInfo GUARDED_BY(mMutex);
8995 
8996 #ifdef _WIN32
8997     int mSemaphoreId = 1;
genSemaphoreId()8998     int genSemaphoreId() {
8999         if (mSemaphoreId == -1) {
9000             mSemaphoreId = 1;
9001         }
9002         int res = mSemaphoreId;
9003         ++mSemaphoreId;
9004         return res;
9005     }
9006     std::unordered_map<int, VkSemaphore> mExternalSemaphoresById GUARDED_BY(mMutex);
9007 #endif
9008 
9009     VkDecoderSnapshot mSnapshot;
9010     enum class SnapshotState {
9011         Normal,
9012         Saving,
9013         Loading,
9014     };
9015     SnapshotState mSnapshotState = SnapshotState::Normal;
9016 
9017     // NOTE: Only present during snapshot loading. This is needed to associate
9018     // `VkDevice`s with Virtio GPU context ids because API calls are not currently
9019     // replayed on the "same" RenderThread which originally made the API call so
9020     // RenderThreadInfoVk::ctx_id is not available.
9021     std::optional<std::unordered_map<VkDevice, uint32_t>> mSnapshotLoadVkDeviceToVirtioCpuContextId
9022         GUARDED_BY(mMutex);
9023 
9024     struct LinearImageCreateInfo {
9025         VkExtent3D extent;
9026         VkFormat format;
9027         VkImageUsageFlags usage;
9028 
toDefaultVkgfxstream::vk::VkDecoderGlobalState::Impl::LinearImageCreateInfo9029         VkImageCreateInfo toDefaultVk() const {
9030             return VkImageCreateInfo{
9031                 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
9032                 .pNext = nullptr,
9033                 .flags = {},
9034                 .imageType = VK_IMAGE_TYPE_2D,
9035                 .format = format,
9036                 .extent = extent,
9037                 .mipLevels = 1,
9038                 .arrayLayers = 1,
9039                 .samples = VK_SAMPLE_COUNT_1_BIT,
9040                 .tiling = VK_IMAGE_TILING_LINEAR,
9041                 .usage = usage,
9042                 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
9043                 .queueFamilyIndexCount = 0,
9044                 .pQueueFamilyIndices = nullptr,
9045                 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
9046             };
9047         }
9048 
9049         struct Hash {
operator ()gfxstream::vk::VkDecoderGlobalState::Impl::LinearImageCreateInfo::Hash9050             std::size_t operator()(const LinearImageCreateInfo& ci) const {
9051                 std::size_t s = 0;
9052                 // Magic number used in boost::hash_combine().
9053                 constexpr size_t kHashMagic = 0x9e3779b9;
9054                 s ^= std::hash<uint32_t>{}(ci.extent.width) + kHashMagic + (s << 6) + (s >> 2);
9055                 s ^= std::hash<uint32_t>{}(ci.extent.height) + kHashMagic + (s << 6) + (s >> 2);
9056                 s ^= std::hash<uint32_t>{}(ci.extent.depth) + kHashMagic + (s << 6) + (s >> 2);
9057                 s ^= std::hash<VkFormat>{}(ci.format) + kHashMagic + (s << 6) + (s >> 2);
9058                 s ^= std::hash<VkImageUsageFlags>{}(ci.usage) + kHashMagic + (s << 6) + (s >> 2);
9059                 return s;
9060             }
9061         };
9062     };
9063 
operator ==(const LinearImageCreateInfo & a,const LinearImageCreateInfo & b)9064     friend bool operator==(const LinearImageCreateInfo& a, const LinearImageCreateInfo& b) {
9065         return a.extent.width == b.extent.width && a.extent.height == b.extent.height &&
9066                a.extent.depth == b.extent.depth && a.format == b.format && a.usage == b.usage;
9067     }
9068 
9069     struct LinearImageProperties {
9070         VkDeviceSize offset;
9071         VkDeviceSize rowPitchAlignment;
9072     };
9073 
9074     // TODO(liyl): Remove after removing the old vkGetLinearImageLayoutGOOGLE.
9075     std::unordered_map<VkFormat, LinearImageProperties> mPerFormatLinearImageProperties
9076         GUARDED_BY(mMutex);
9077 
9078     std::unordered_map<LinearImageCreateInfo, LinearImageProperties, LinearImageCreateInfo::Hash>
9079         mLinearImageProperties GUARDED_BY(mMutex);
9080 };
9081 
VkDecoderGlobalState(VkEmulation * emulation)9082 VkDecoderGlobalState::VkDecoderGlobalState(VkEmulation* emulation)
9083     : mImpl(new VkDecoderGlobalState::Impl(emulation)) {}
9084 
9085 VkDecoderGlobalState::~VkDecoderGlobalState() = default;
9086 
9087 static VkDecoderGlobalState* sGlobalDecoderState = nullptr;
9088 
9089 // static
initialize(VkEmulation * emulation)9090 void VkDecoderGlobalState::initialize(VkEmulation* emulation) {
9091     if (sGlobalDecoderState) {
9092         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
9093             << "Attempted to re-initialize VkDecoderGlobalState.";
9094     }
9095     sGlobalDecoderState = new VkDecoderGlobalState(emulation);
9096 }
9097 
9098 // static
get()9099 VkDecoderGlobalState* VkDecoderGlobalState::get() {
9100     if (!sGlobalDecoderState) {
9101         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "VkDecoderGlobalState not initialized.";
9102     }
9103     return sGlobalDecoderState;
9104 }
9105 
9106 // static
reset()9107 void VkDecoderGlobalState::reset() {
9108     delete sGlobalDecoderState;
9109     sGlobalDecoderState = nullptr;
9110 }
9111 
9112 // Snapshots
snapshotsEnabled() const9113 bool VkDecoderGlobalState::snapshotsEnabled() const { return mImpl->snapshotsEnabled(); }
batchedDescriptorSetUpdateEnabled() const9114 bool VkDecoderGlobalState::batchedDescriptorSetUpdateEnabled() const { return mImpl->batchedDescriptorSetUpdateEnabled(); }
9115 
newGlobalVkGenericHandle()9116 uint64_t VkDecoderGlobalState::newGlobalVkGenericHandle() {
9117     BoxedHandleInfo item;                                                    \
9118     return mImpl->newGlobalHandle(item, Tag_VkGeneric);
9119 }
9120 
isSnapshotCurrentlyLoading() const9121 bool VkDecoderGlobalState::isSnapshotCurrentlyLoading() const {
9122     return mImpl->isSnapshotCurrentlyLoading();
9123 }
9124 
getFeatures() const9125 const gfxstream::host::FeatureSet& VkDecoderGlobalState::getFeatures() const { return mImpl->getFeatures(); }
9126 
vkCleanupEnabled() const9127 bool VkDecoderGlobalState::vkCleanupEnabled() const { return mImpl->vkCleanupEnabled(); }
9128 
save(android::base::Stream * stream)9129 void VkDecoderGlobalState::save(android::base::Stream* stream) { mImpl->save(stream); }
9130 
load(android::base::Stream * stream,GfxApiLogger & gfxLogger,HealthMonitor<> * healthMonitor)9131 void VkDecoderGlobalState::load(android::base::Stream* stream, GfxApiLogger& gfxLogger,
9132                                 HealthMonitor<>* healthMonitor) {
9133     mImpl->load(stream, gfxLogger, healthMonitor);
9134 }
9135 
on_vkEnumerateInstanceVersion(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,uint32_t * pApiVersion)9136 VkResult VkDecoderGlobalState::on_vkEnumerateInstanceVersion(android::base::BumpPool* pool,
9137                                                              VkSnapshotApiCallInfo* snapshotInfo,
9138                                                              uint32_t* pApiVersion) {
9139     return mImpl->on_vkEnumerateInstanceVersion(pool, snapshotInfo, pApiVersion);
9140 }
9141 
on_vkEnumerateInstanceExtensionProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)9142 VkResult VkDecoderGlobalState::on_vkEnumerateInstanceExtensionProperties(
9143     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, const char* pLayerName,
9144     uint32_t* pPropertyCount, VkExtensionProperties* pProperties) {
9145     return mImpl->on_vkEnumerateInstanceExtensionProperties(pool, snapshotInfo, pLayerName,
9146                                                             pPropertyCount, pProperties);
9147 }
9148 
on_vkCreateInstance(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)9149 VkResult VkDecoderGlobalState::on_vkCreateInstance(android::base::BumpPool* pool,
9150                                                    VkSnapshotApiCallInfo* snapshotInfo,
9151                                                    const VkInstanceCreateInfo* pCreateInfo,
9152                                                    const VkAllocationCallbacks* pAllocator,
9153                                                    VkInstance* pInstance) {
9154     return mImpl->on_vkCreateInstance(pool, snapshotInfo, pCreateInfo, pAllocator, pInstance);
9155 }
9156 
on_vkDestroyInstance(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkInstance instance,const VkAllocationCallbacks * pAllocator)9157 void VkDecoderGlobalState::on_vkDestroyInstance(android::base::BumpPool* pool,
9158                                                 VkSnapshotApiCallInfo* snapshotInfo,
9159                                                 VkInstance instance,
9160                                                 const VkAllocationCallbacks* pAllocator) {
9161     mImpl->on_vkDestroyInstance(pool, snapshotInfo, instance, pAllocator);
9162 }
9163 
on_vkEnumeratePhysicalDevices(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkInstance instance,uint32_t * physicalDeviceCount,VkPhysicalDevice * physicalDevices)9164 VkResult VkDecoderGlobalState::on_vkEnumeratePhysicalDevices(android::base::BumpPool* pool,
9165                                                              VkSnapshotApiCallInfo* snapshotInfo,
9166                                                              VkInstance instance,
9167                                                              uint32_t* physicalDeviceCount,
9168                                                              VkPhysicalDevice* physicalDevices) {
9169     return mImpl->on_vkEnumeratePhysicalDevices(pool, snapshotInfo, instance, physicalDeviceCount,
9170                                                 physicalDevices);
9171 }
9172 
on_vkGetPhysicalDeviceFeatures(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures * pFeatures)9173 void VkDecoderGlobalState::on_vkGetPhysicalDeviceFeatures(android::base::BumpPool* pool,
9174                                                           VkSnapshotApiCallInfo* snapshotInfo,
9175                                                           VkPhysicalDevice physicalDevice,
9176                                                           VkPhysicalDeviceFeatures* pFeatures) {
9177     mImpl->on_vkGetPhysicalDeviceFeatures(pool, snapshotInfo, physicalDevice, pFeatures);
9178 }
9179 
on_vkGetPhysicalDeviceFeatures2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures2 * pFeatures)9180 void VkDecoderGlobalState::on_vkGetPhysicalDeviceFeatures2(android::base::BumpPool* pool,
9181                                                            VkSnapshotApiCallInfo* snapshotInfo,
9182                                                            VkPhysicalDevice physicalDevice,
9183                                                            VkPhysicalDeviceFeatures2* pFeatures) {
9184     mImpl->on_vkGetPhysicalDeviceFeatures2(pool, snapshotInfo, physicalDevice, pFeatures);
9185 }
9186 
on_vkGetPhysicalDeviceFeatures2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures2KHR * pFeatures)9187 void VkDecoderGlobalState::on_vkGetPhysicalDeviceFeatures2KHR(
9188     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9189     VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR* pFeatures) {
9190     mImpl->on_vkGetPhysicalDeviceFeatures2(pool, snapshotInfo, physicalDevice, pFeatures);
9191 }
9192 
on_vkGetPhysicalDeviceImageFormatProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags,VkImageFormatProperties * pImageFormatProperties)9193 VkResult VkDecoderGlobalState::on_vkGetPhysicalDeviceImageFormatProperties(
9194     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9195     VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling,
9196     VkImageUsageFlags usage, VkImageCreateFlags flags,
9197     VkImageFormatProperties* pImageFormatProperties) {
9198     return mImpl->on_vkGetPhysicalDeviceImageFormatProperties(pool, snapshotInfo, physicalDevice,
9199                                                               format, type, tiling, usage, flags,
9200                                                               pImageFormatProperties);
9201 }
on_vkGetPhysicalDeviceImageFormatProperties2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,VkImageFormatProperties2 * pImageFormatProperties)9202 VkResult VkDecoderGlobalState::on_vkGetPhysicalDeviceImageFormatProperties2(
9203     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9204     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
9205     VkImageFormatProperties2* pImageFormatProperties) {
9206     return mImpl->on_vkGetPhysicalDeviceImageFormatProperties2(
9207         pool, snapshotInfo, physicalDevice, pImageFormatInfo, pImageFormatProperties);
9208 }
on_vkGetPhysicalDeviceImageFormatProperties2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,VkImageFormatProperties2 * pImageFormatProperties)9209 VkResult VkDecoderGlobalState::on_vkGetPhysicalDeviceImageFormatProperties2KHR(
9210     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9211     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
9212     VkImageFormatProperties2* pImageFormatProperties) {
9213     return mImpl->on_vkGetPhysicalDeviceImageFormatProperties2(
9214         pool, snapshotInfo, physicalDevice, pImageFormatInfo, pImageFormatProperties);
9215 }
9216 
on_vkGetPhysicalDeviceFormatProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties * pFormatProperties)9217 void VkDecoderGlobalState::on_vkGetPhysicalDeviceFormatProperties(
9218     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9219     VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties) {
9220     mImpl->on_vkGetPhysicalDeviceFormatProperties(pool, snapshotInfo, physicalDevice, format,
9221                                                   pFormatProperties);
9222 }
9223 
on_vkGetPhysicalDeviceFormatProperties2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)9224 void VkDecoderGlobalState::on_vkGetPhysicalDeviceFormatProperties2(
9225     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9226     VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties) {
9227     mImpl->on_vkGetPhysicalDeviceFormatProperties2(pool, snapshotInfo, physicalDevice, format,
9228                                                    pFormatProperties);
9229 }
9230 
on_vkGetPhysicalDeviceFormatProperties2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)9231 void VkDecoderGlobalState::on_vkGetPhysicalDeviceFormatProperties2KHR(
9232     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9233     VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties) {
9234     mImpl->on_vkGetPhysicalDeviceFormatProperties2(pool, snapshotInfo, physicalDevice, format,
9235                                                    pFormatProperties);
9236 }
9237 
on_vkGetPhysicalDeviceProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties * pProperties)9238 void VkDecoderGlobalState::on_vkGetPhysicalDeviceProperties(
9239     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9240     VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties) {
9241     mImpl->on_vkGetPhysicalDeviceProperties(pool, snapshotInfo, physicalDevice, pProperties);
9242 }
9243 
on_vkGetPhysicalDeviceProperties2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties2 * pProperties)9244 void VkDecoderGlobalState::on_vkGetPhysicalDeviceProperties2(
9245     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9246     VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties) {
9247     mImpl->on_vkGetPhysicalDeviceProperties2(pool, snapshotInfo, physicalDevice, pProperties);
9248 }
9249 
on_vkGetPhysicalDeviceQueueFamilyProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,uint32_t * pQueueFamilyPropertyCount,VkQueueFamilyProperties * pQueueFamilyProperties)9250 void VkDecoderGlobalState::on_vkGetPhysicalDeviceQueueFamilyProperties(
9251     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9252     VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount,
9253     VkQueueFamilyProperties* pQueueFamilyProperties) {
9254     mImpl->on_vkGetPhysicalDeviceQueueFamilyProperties(
9255         pool, snapshotInfo, physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
9256 }
9257 
on_vkGetPhysicalDeviceQueueFamilyProperties2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,uint32_t * pQueueFamilyPropertyCount,VkQueueFamilyProperties2 * pQueueFamilyProperties)9258 void VkDecoderGlobalState::on_vkGetPhysicalDeviceQueueFamilyProperties2(
9259     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9260     VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount,
9261     VkQueueFamilyProperties2* pQueueFamilyProperties) {
9262     mImpl->on_vkGetPhysicalDeviceQueueFamilyProperties2(
9263         pool, snapshotInfo, physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
9264 }
9265 
on_vkQueuePresentKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue,const VkPresentInfoKHR * pPresentInfo)9266 VkResult VkDecoderGlobalState::on_vkQueuePresentKHR(android::base::BumpPool* pool,
9267                                                     VkSnapshotApiCallInfo* snapshotInfo,
9268                                                     VkQueue queue,
9269                                                     const VkPresentInfoKHR* pPresentInfo) {
9270     return mImpl->on_vkQueuePresentKHR(pool, snapshotInfo, queue, pPresentInfo);
9271 }
9272 
on_vkGetPhysicalDeviceProperties2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties2 * pProperties)9273 void VkDecoderGlobalState::on_vkGetPhysicalDeviceProperties2KHR(
9274     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9275     VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties) {
9276     mImpl->on_vkGetPhysicalDeviceProperties2(pool, snapshotInfo, physicalDevice, pProperties);
9277 }
9278 
on_vkGetPhysicalDeviceMemoryProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties * pMemoryProperties)9279 void VkDecoderGlobalState::on_vkGetPhysicalDeviceMemoryProperties(
9280     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9281     VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
9282     mImpl->on_vkGetPhysicalDeviceMemoryProperties(pool, snapshotInfo, physicalDevice,
9283                                                   pMemoryProperties);
9284 }
9285 
on_vkGetPhysicalDeviceMemoryProperties2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties2 * pMemoryProperties)9286 void VkDecoderGlobalState::on_vkGetPhysicalDeviceMemoryProperties2(
9287     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9288     VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
9289     mImpl->on_vkGetPhysicalDeviceMemoryProperties2(pool, snapshotInfo, physicalDevice,
9290                                                    pMemoryProperties);
9291 }
9292 
on_vkGetPhysicalDeviceMemoryProperties2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties2 * pMemoryProperties)9293 void VkDecoderGlobalState::on_vkGetPhysicalDeviceMemoryProperties2KHR(
9294     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9295     VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
9296     mImpl->on_vkGetPhysicalDeviceMemoryProperties2(pool, snapshotInfo, physicalDevice,
9297                                                    pMemoryProperties);
9298 }
9299 
on_vkEnumerateDeviceExtensionProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)9300 VkResult VkDecoderGlobalState::on_vkEnumerateDeviceExtensionProperties(
9301     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9302     VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount,
9303     VkExtensionProperties* pProperties) {
9304     return mImpl->on_vkEnumerateDeviceExtensionProperties(pool, snapshotInfo, physicalDevice,
9305                                                           pLayerName, pPropertyCount, pProperties);
9306 }
9307 
on_vkCreateDevice(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)9308 VkResult VkDecoderGlobalState::on_vkCreateDevice(android::base::BumpPool* pool,
9309                                                  VkSnapshotApiCallInfo* snapshotInfo,
9310                                                  VkPhysicalDevice physicalDevice,
9311                                                  const VkDeviceCreateInfo* pCreateInfo,
9312                                                  const VkAllocationCallbacks* pAllocator,
9313                                                  VkDevice* pDevice) {
9314     return mImpl->on_vkCreateDevice(pool, snapshotInfo, physicalDevice, pCreateInfo, pAllocator,
9315                                     pDevice);
9316 }
9317 
on_vkGetDeviceQueue(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,uint32_t queueFamilyIndex,uint32_t queueIndex,VkQueue * pQueue)9318 void VkDecoderGlobalState::on_vkGetDeviceQueue(android::base::BumpPool* pool,
9319                                                VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9320                                                uint32_t queueFamilyIndex, uint32_t queueIndex,
9321                                                VkQueue* pQueue) {
9322     mImpl->on_vkGetDeviceQueue(pool, snapshotInfo, device, queueFamilyIndex, queueIndex, pQueue);
9323 }
9324 
on_vkGetDeviceQueue2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkDeviceQueueInfo2 * pQueueInfo,VkQueue * pQueue)9325 void VkDecoderGlobalState::on_vkGetDeviceQueue2(android::base::BumpPool* pool,
9326                                                 VkSnapshotApiCallInfo* snapshotInfo,
9327                                                 VkDevice device,
9328                                                 const VkDeviceQueueInfo2* pQueueInfo,
9329                                                 VkQueue* pQueue) {
9330     mImpl->on_vkGetDeviceQueue2(pool, snapshotInfo, device, pQueueInfo, pQueue);
9331 }
9332 
on_vkDestroyDevice(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkAllocationCallbacks * pAllocator)9333 void VkDecoderGlobalState::on_vkDestroyDevice(android::base::BumpPool* pool,
9334                                               VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9335                                               const VkAllocationCallbacks* pAllocator) {
9336     mImpl->on_vkDestroyDevice(pool, snapshotInfo, device, pAllocator);
9337 }
9338 
on_vkCreateBuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer)9339 VkResult VkDecoderGlobalState::on_vkCreateBuffer(android::base::BumpPool* pool,
9340                                                  VkSnapshotApiCallInfo* snapshotInfo,
9341                                                  VkDevice device,
9342                                                  const VkBufferCreateInfo* pCreateInfo,
9343                                                  const VkAllocationCallbacks* pAllocator,
9344                                                  VkBuffer* pBuffer) {
9345     return mImpl->on_vkCreateBuffer(pool, snapshotInfo, device, pCreateInfo, pAllocator, pBuffer);
9346 }
9347 
on_vkDestroyBuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkBuffer buffer,const VkAllocationCallbacks * pAllocator)9348 void VkDecoderGlobalState::on_vkDestroyBuffer(android::base::BumpPool* pool,
9349                                               VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9350                                               VkBuffer buffer,
9351                                               const VkAllocationCallbacks* pAllocator) {
9352     mImpl->on_vkDestroyBuffer(pool, snapshotInfo, device, buffer, pAllocator);
9353 }
9354 
on_vkBindBufferMemory(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkBuffer buffer,VkDeviceMemory memory,VkDeviceSize memoryOffset)9355 VkResult VkDecoderGlobalState::on_vkBindBufferMemory(android::base::BumpPool* pool,
9356                                                      VkSnapshotApiCallInfo* snapshotInfo,
9357                                                      VkDevice device, VkBuffer buffer,
9358                                                      VkDeviceMemory memory,
9359                                                      VkDeviceSize memoryOffset) {
9360     return mImpl->on_vkBindBufferMemory(pool, snapshotInfo, device, buffer, memory, memoryOffset);
9361 }
9362 
on_vkBindBufferMemory2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,uint32_t bindInfoCount,const VkBindBufferMemoryInfo * pBindInfos)9363 VkResult VkDecoderGlobalState::on_vkBindBufferMemory2(android::base::BumpPool* pool,
9364                                                       VkSnapshotApiCallInfo* snapshotInfo,
9365                                                       VkDevice device, uint32_t bindInfoCount,
9366                                                       const VkBindBufferMemoryInfo* pBindInfos) {
9367     return mImpl->on_vkBindBufferMemory2(pool, snapshotInfo, device, bindInfoCount, pBindInfos);
9368 }
9369 
on_vkBindBufferMemory2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,uint32_t bindInfoCount,const VkBindBufferMemoryInfo * pBindInfos)9370 VkResult VkDecoderGlobalState::on_vkBindBufferMemory2KHR(android::base::BumpPool* pool,
9371                                                          VkSnapshotApiCallInfo* snapshotInfo,
9372                                                          VkDevice device, uint32_t bindInfoCount,
9373                                                          const VkBindBufferMemoryInfo* pBindInfos) {
9374     return mImpl->on_vkBindBufferMemory2KHR(pool, snapshotInfo, device, bindInfoCount, pBindInfos);
9375 }
9376 
on_vkCreateImage(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage)9377 VkResult VkDecoderGlobalState::on_vkCreateImage(android::base::BumpPool* pool,
9378                                                 VkSnapshotApiCallInfo* snapshotInfo,
9379                                                 VkDevice device,
9380                                                 const VkImageCreateInfo* pCreateInfo,
9381                                                 const VkAllocationCallbacks* pAllocator,
9382                                                 VkImage* pImage) {
9383     return mImpl->on_vkCreateImage(pool, snapshotInfo, device, pCreateInfo, pAllocator, pImage);
9384 }
9385 
on_vkDestroyImage(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkImage image,const VkAllocationCallbacks * pAllocator)9386 void VkDecoderGlobalState::on_vkDestroyImage(android::base::BumpPool* pool,
9387                                              VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9388                                              VkImage image,
9389                                              const VkAllocationCallbacks* pAllocator) {
9390     mImpl->on_vkDestroyImage(pool, snapshotInfo, device, image, pAllocator);
9391 }
9392 
on_vkBindImageMemory(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkImage image,VkDeviceMemory memory,VkDeviceSize memoryOffset)9393 VkResult VkDecoderGlobalState::on_vkBindImageMemory(android::base::BumpPool* pool,
9394                                                     VkSnapshotApiCallInfo* snapshotInfo,
9395                                                     VkDevice device, VkImage image,
9396                                                     VkDeviceMemory memory,
9397                                                     VkDeviceSize memoryOffset) {
9398     return mImpl->on_vkBindImageMemory(pool, snapshotInfo, device, image, memory, memoryOffset);
9399 }
9400 
on_vkBindImageMemory2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,uint32_t bindInfoCount,const VkBindImageMemoryInfo * pBindInfos)9401 VkResult VkDecoderGlobalState::on_vkBindImageMemory2(android::base::BumpPool* pool,
9402                                                      VkSnapshotApiCallInfo* snapshotInfo,
9403                                                      VkDevice device, uint32_t bindInfoCount,
9404                                                      const VkBindImageMemoryInfo* pBindInfos) {
9405     return mImpl->on_vkBindImageMemory2(pool, snapshotInfo, device, bindInfoCount, pBindInfos);
9406 }
9407 
on_vkBindImageMemory2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,uint32_t bindInfoCount,const VkBindImageMemoryInfo * pBindInfos)9408 VkResult VkDecoderGlobalState::on_vkBindImageMemory2KHR(android::base::BumpPool* pool,
9409                                                         VkSnapshotApiCallInfo* snapshotInfo,
9410                                                         VkDevice device, uint32_t bindInfoCount,
9411                                                         const VkBindImageMemoryInfo* pBindInfos) {
9412     return mImpl->on_vkBindImageMemory2(pool, snapshotInfo, device, bindInfoCount, pBindInfos);
9413 }
9414 
on_vkCreateImageView(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkImageViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImageView * pView)9415 VkResult VkDecoderGlobalState::on_vkCreateImageView(android::base::BumpPool* pool,
9416                                                     VkSnapshotApiCallInfo* snapshotInfo,
9417                                                     VkDevice device,
9418                                                     const VkImageViewCreateInfo* pCreateInfo,
9419                                                     const VkAllocationCallbacks* pAllocator,
9420                                                     VkImageView* pView) {
9421     return mImpl->on_vkCreateImageView(pool, snapshotInfo, device, pCreateInfo, pAllocator, pView);
9422 }
9423 
on_vkDestroyImageView(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkImageView imageView,const VkAllocationCallbacks * pAllocator)9424 void VkDecoderGlobalState::on_vkDestroyImageView(android::base::BumpPool* pool,
9425                                                  VkSnapshotApiCallInfo* snapshotInfo,
9426                                                  VkDevice device, VkImageView imageView,
9427                                                  const VkAllocationCallbacks* pAllocator) {
9428     mImpl->on_vkDestroyImageView(pool, snapshotInfo, device, imageView, pAllocator);
9429 }
9430 
on_vkCreateSampler(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkSamplerCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)9431 VkResult VkDecoderGlobalState::on_vkCreateSampler(android::base::BumpPool* pool,
9432                                                   VkSnapshotApiCallInfo* snapshotInfo,
9433                                                   VkDevice device,
9434                                                   const VkSamplerCreateInfo* pCreateInfo,
9435                                                   const VkAllocationCallbacks* pAllocator,
9436                                                   VkSampler* pSampler) {
9437     return mImpl->on_vkCreateSampler(pool, snapshotInfo, device, pCreateInfo, pAllocator, pSampler);
9438 }
9439 
on_vkDestroySampler(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkSampler sampler,const VkAllocationCallbacks * pAllocator)9440 void VkDecoderGlobalState::on_vkDestroySampler(android::base::BumpPool* pool,
9441                                                VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9442                                                VkSampler sampler,
9443                                                const VkAllocationCallbacks* pAllocator) {
9444     mImpl->on_vkDestroySampler(pool, snapshotInfo, device, sampler, pAllocator);
9445 }
9446 
on_vkCreateSemaphore(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkSemaphoreCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSemaphore * pSemaphore)9447 VkResult VkDecoderGlobalState::on_vkCreateSemaphore(android::base::BumpPool* pool,
9448                                                     VkSnapshotApiCallInfo* snapshotInfo,
9449                                                     VkDevice device,
9450                                                     const VkSemaphoreCreateInfo* pCreateInfo,
9451                                                     const VkAllocationCallbacks* pAllocator,
9452                                                     VkSemaphore* pSemaphore) {
9453     return mImpl->on_vkCreateSemaphore(pool, snapshotInfo, device, pCreateInfo, pAllocator,
9454                                        pSemaphore);
9455 }
9456 
on_vkImportSemaphoreFdKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkImportSemaphoreFdInfoKHR * pImportSemaphoreFdInfo)9457 VkResult VkDecoderGlobalState::on_vkImportSemaphoreFdKHR(
9458     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9459     const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo) {
9460     return mImpl->on_vkImportSemaphoreFdKHR(pool, snapshotInfo, device, pImportSemaphoreFdInfo);
9461 }
9462 
on_vkGetSemaphoreFdKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkSemaphoreGetFdInfoKHR * pGetFdInfo,int * pFd)9463 VkResult VkDecoderGlobalState::on_vkGetSemaphoreFdKHR(android::base::BumpPool* pool,
9464                                                       VkSnapshotApiCallInfo* snapshotInfo,
9465                                                       VkDevice device,
9466                                                       const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
9467                                                       int* pFd) {
9468     return mImpl->on_vkGetSemaphoreFdKHR(pool, snapshotInfo, device, pGetFdInfo, pFd);
9469 }
9470 
on_vkGetSemaphoreGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkSemaphore semaphore,uint64_t syncId)9471 VkResult VkDecoderGlobalState::on_vkGetSemaphoreGOOGLE(android::base::BumpPool* pool,
9472                                                        VkSnapshotApiCallInfo* snapshotInfo,
9473                                                        VkDevice device, VkSemaphore semaphore,
9474                                                        uint64_t syncId) {
9475     return mImpl->on_vkGetSemaphoreGOOGLE(pool, snapshotInfo, device, semaphore, syncId);
9476 }
9477 
on_vkDestroySemaphore(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkSemaphore semaphore,const VkAllocationCallbacks * pAllocator)9478 void VkDecoderGlobalState::on_vkDestroySemaphore(android::base::BumpPool* pool,
9479                                                  VkSnapshotApiCallInfo* snapshotInfo,
9480                                                  VkDevice device, VkSemaphore semaphore,
9481                                                  const VkAllocationCallbacks* pAllocator) {
9482     mImpl->on_vkDestroySemaphore(pool, snapshotInfo, device, semaphore, pAllocator);
9483 }
9484 
on_vkWaitSemaphores(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkSemaphoreWaitInfo * pWaitInfo,uint64_t timeout)9485 VkResult VkDecoderGlobalState::on_vkWaitSemaphores(android::base::BumpPool* pool,
9486                                                    VkSnapshotApiCallInfo* snapshotInfo,
9487                                                    VkDevice device,
9488                                                    const VkSemaphoreWaitInfo* pWaitInfo,
9489                                                    uint64_t timeout) {
9490     return mImpl->on_vkWaitSemaphores(pool, snapshotInfo, device, pWaitInfo, timeout);
9491 }
9492 
on_vkSignalSemaphore(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkSemaphoreSignalInfo * pSignalInfo)9493 VkResult VkDecoderGlobalState::on_vkSignalSemaphore(android::base::BumpPool* pool,
9494                                                    VkSnapshotApiCallInfo* snapshotInfo,
9495                                                    VkDevice device,
9496                                                    const VkSemaphoreSignalInfo* pSignalInfo) {
9497     return mImpl->on_vkSignalSemaphore(pool, snapshotInfo, device, pSignalInfo);
9498 }
9499 
on_vkCreateFence(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkFenceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkFence * pFence)9500 VkResult VkDecoderGlobalState::on_vkCreateFence(android::base::BumpPool* pool,
9501                                                 VkSnapshotApiCallInfo* snapshotInfo,
9502                                                 VkDevice device,
9503                                                 const VkFenceCreateInfo* pCreateInfo,
9504                                                 const VkAllocationCallbacks* pAllocator,
9505                                                 VkFence* pFence) {
9506     return mImpl->on_vkCreateFence(pool, snapshotInfo, device, pCreateInfo, pAllocator, pFence);
9507 }
9508 
on_vkGetFenceStatus(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkFence fence)9509 VkResult VkDecoderGlobalState::on_vkGetFenceStatus(android::base::BumpPool* pool,
9510                                                    VkSnapshotApiCallInfo* snapshotInfo,
9511                                                    VkDevice device, VkFence fence) {
9512     return mImpl->on_vkGetFenceStatus(pool, snapshotInfo, device, fence);
9513 }
9514 
on_vkWaitForFences(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,uint32_t fenceCount,const VkFence * pFences,VkBool32 waitAll,uint64_t timeout)9515 VkResult VkDecoderGlobalState::on_vkWaitForFences(android::base::BumpPool* pool,
9516                                                   VkSnapshotApiCallInfo* snapshotInfo,
9517                                                   VkDevice device, uint32_t fenceCount,
9518                                                   const VkFence* pFences, VkBool32 waitAll,
9519                                                   uint64_t timeout) {
9520     return mImpl->on_vkWaitForFences(pool, snapshotInfo, device, fenceCount, pFences, waitAll,
9521                                      timeout);
9522 }
9523 
on_vkResetFences(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,uint32_t fenceCount,const VkFence * pFences)9524 VkResult VkDecoderGlobalState::on_vkResetFences(android::base::BumpPool* pool,
9525                                                 VkSnapshotApiCallInfo* snapshotInfo,
9526                                                 VkDevice device, uint32_t fenceCount,
9527                                                 const VkFence* pFences) {
9528     return mImpl->on_vkResetFences(pool, snapshotInfo, device, fenceCount, pFences);
9529 }
9530 
on_vkDestroyFence(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkFence fence,const VkAllocationCallbacks * pAllocator)9531 void VkDecoderGlobalState::on_vkDestroyFence(android::base::BumpPool* pool,
9532                                              VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9533                                              VkFence fence,
9534                                              const VkAllocationCallbacks* pAllocator) {
9535     return mImpl->on_vkDestroyFence(pool, snapshotInfo, device, fence, pAllocator);
9536 }
9537 
on_vkCreateDescriptorSetLayout(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkDescriptorSetLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorSetLayout * pSetLayout)9538 VkResult VkDecoderGlobalState::on_vkCreateDescriptorSetLayout(
9539     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9540     const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
9541     VkDescriptorSetLayout* pSetLayout) {
9542     return mImpl->on_vkCreateDescriptorSetLayout(pool, snapshotInfo, device, pCreateInfo,
9543                                                  pAllocator, pSetLayout);
9544 }
9545 
on_vkDestroyDescriptorSetLayout(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkDescriptorSetLayout descriptorSetLayout,const VkAllocationCallbacks * pAllocator)9546 void VkDecoderGlobalState::on_vkDestroyDescriptorSetLayout(
9547     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9548     VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator) {
9549     mImpl->on_vkDestroyDescriptorSetLayout(pool, snapshotInfo, device, descriptorSetLayout,
9550                                            pAllocator);
9551 }
9552 
on_vkCreateDescriptorPool(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkDescriptorPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorPool * pDescriptorPool)9553 VkResult VkDecoderGlobalState::on_vkCreateDescriptorPool(
9554     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9555     const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
9556     VkDescriptorPool* pDescriptorPool) {
9557     return mImpl->on_vkCreateDescriptorPool(pool, snapshotInfo, device, pCreateInfo, pAllocator,
9558                                             pDescriptorPool);
9559 }
9560 
on_vkDestroyDescriptorPool(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkDescriptorPool descriptorPool,const VkAllocationCallbacks * pAllocator)9561 void VkDecoderGlobalState::on_vkDestroyDescriptorPool(android::base::BumpPool* pool,
9562                                                       VkSnapshotApiCallInfo* snapshotInfo,
9563                                                       VkDevice device,
9564                                                       VkDescriptorPool descriptorPool,
9565                                                       const VkAllocationCallbacks* pAllocator) {
9566     mImpl->on_vkDestroyDescriptorPool(pool, snapshotInfo, device, descriptorPool, pAllocator);
9567 }
9568 
on_vkResetDescriptorPool(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkDescriptorPool descriptorPool,VkDescriptorPoolResetFlags flags)9569 VkResult VkDecoderGlobalState::on_vkResetDescriptorPool(android::base::BumpPool* pool,
9570                                                         VkSnapshotApiCallInfo* snapshotInfo,
9571                                                         VkDevice device,
9572                                                         VkDescriptorPool descriptorPool,
9573                                                         VkDescriptorPoolResetFlags flags) {
9574     return mImpl->on_vkResetDescriptorPool(pool, snapshotInfo, device, descriptorPool, flags);
9575 }
9576 
on_vkAllocateDescriptorSets(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkDescriptorSetAllocateInfo * pAllocateInfo,VkDescriptorSet * pDescriptorSets)9577 VkResult VkDecoderGlobalState::on_vkAllocateDescriptorSets(
9578     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9579     const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets) {
9580     return mImpl->on_vkAllocateDescriptorSets(pool, snapshotInfo, device, pAllocateInfo,
9581                                               pDescriptorSets);
9582 }
9583 
on_vkFreeDescriptorSets(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkDescriptorPool descriptorPool,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets)9584 VkResult VkDecoderGlobalState::on_vkFreeDescriptorSets(android::base::BumpPool* pool,
9585                                                        VkSnapshotApiCallInfo* snapshotInfo,
9586                                                        VkDevice device,
9587                                                        VkDescriptorPool descriptorPool,
9588                                                        uint32_t descriptorSetCount,
9589                                                        const VkDescriptorSet* pDescriptorSets) {
9590     return mImpl->on_vkFreeDescriptorSets(pool, snapshotInfo, device, descriptorPool,
9591                                           descriptorSetCount, pDescriptorSets);
9592 }
9593 
on_vkUpdateDescriptorSets(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites,uint32_t descriptorCopyCount,const VkCopyDescriptorSet * pDescriptorCopies)9594 void VkDecoderGlobalState::on_vkUpdateDescriptorSets(android::base::BumpPool* pool,
9595                                                      VkSnapshotApiCallInfo* snapshotInfo,
9596                                                      VkDevice device, uint32_t descriptorWriteCount,
9597                                                      const VkWriteDescriptorSet* pDescriptorWrites,
9598                                                      uint32_t descriptorCopyCount,
9599                                                      const VkCopyDescriptorSet* pDescriptorCopies) {
9600     mImpl->on_vkUpdateDescriptorSets(pool, snapshotInfo, device, descriptorWriteCount,
9601                                      pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
9602 }
9603 
on_vkCreateShaderModule(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkShaderModuleCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkShaderModule * pShaderModule)9604 VkResult VkDecoderGlobalState::on_vkCreateShaderModule(android::base::BumpPool* pool,
9605                                                        VkSnapshotApiCallInfo* snapshotInfo,
9606                                                        VkDevice boxed_device,
9607                                                        const VkShaderModuleCreateInfo* pCreateInfo,
9608                                                        const VkAllocationCallbacks* pAllocator,
9609                                                        VkShaderModule* pShaderModule) {
9610     return mImpl->on_vkCreateShaderModule(pool, snapshotInfo, boxed_device, pCreateInfo, pAllocator,
9611                                           pShaderModule);
9612 }
9613 
on_vkDestroyShaderModule(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkShaderModule shaderModule,const VkAllocationCallbacks * pAllocator)9614 void VkDecoderGlobalState::on_vkDestroyShaderModule(android::base::BumpPool* pool,
9615                                                     VkSnapshotApiCallInfo* snapshotInfo,
9616                                                     VkDevice boxed_device,
9617                                                     VkShaderModule shaderModule,
9618                                                     const VkAllocationCallbacks* pAllocator) {
9619     mImpl->on_vkDestroyShaderModule(pool, snapshotInfo, boxed_device, shaderModule, pAllocator);
9620 }
9621 
on_vkCreatePipelineCache(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkPipelineCacheCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipelineCache * pPipelineCache)9622 VkResult VkDecoderGlobalState::on_vkCreatePipelineCache(
9623     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
9624     const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
9625     VkPipelineCache* pPipelineCache) {
9626     return mImpl->on_vkCreatePipelineCache(pool, snapshotInfo, boxed_device, pCreateInfo,
9627                                            pAllocator, pPipelineCache);
9628 }
9629 
on_vkDestroyPipelineCache(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkPipelineCache pipelineCache,const VkAllocationCallbacks * pAllocator)9630 void VkDecoderGlobalState::on_vkDestroyPipelineCache(android::base::BumpPool* pool,
9631                                                      VkSnapshotApiCallInfo* snapshotInfo,
9632                                                      VkDevice boxed_device,
9633                                                      VkPipelineCache pipelineCache,
9634                                                      const VkAllocationCallbacks* pAllocator) {
9635     mImpl->on_vkDestroyPipelineCache(pool, snapshotInfo, boxed_device, pipelineCache, pAllocator);
9636 }
9637 
on_vkCreatePipelineLayout(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkPipelineLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipelineLayout * pPipelineLayout)9638 VkResult VkDecoderGlobalState::on_vkCreatePipelineLayout(
9639     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
9640     const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
9641     VkPipelineLayout* pPipelineLayout) {
9642     return mImpl->on_vkCreatePipelineLayout(pool, snapshotInfo, boxed_device, pCreateInfo,
9643                                            pAllocator, pPipelineLayout);
9644 }
9645 
on_vkDestroyPipelineLayout(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkPipelineLayout pipelineLayout,const VkAllocationCallbacks * pAllocator)9646 void VkDecoderGlobalState::on_vkDestroyPipelineLayout(android::base::BumpPool* pool,
9647                                                      VkSnapshotApiCallInfo* snapshotInfo,
9648                                                      VkDevice boxed_device,
9649                                                      VkPipelineLayout pipelineLayout,
9650                                                      const VkAllocationCallbacks* pAllocator) {
9651     mImpl->on_vkDestroyPipelineLayout(pool, snapshotInfo, boxed_device, pipelineLayout, pAllocator);
9652 }
9653 
on_vkCreateGraphicsPipelines(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)9654 VkResult VkDecoderGlobalState::on_vkCreateGraphicsPipelines(
9655     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
9656     VkPipelineCache pipelineCache, uint32_t createInfoCount,
9657     const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator,
9658     VkPipeline* pPipelines) {
9659     return mImpl->on_vkCreateGraphicsPipelines(pool, snapshotInfo, boxed_device, pipelineCache,
9660                                                createInfoCount, pCreateInfos, pAllocator,
9661                                                pPipelines);
9662 }
9663 
on_vkCreateComputePipelines(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)9664 VkResult VkDecoderGlobalState::on_vkCreateComputePipelines(
9665     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
9666     VkPipelineCache pipelineCache, uint32_t createInfoCount,
9667     const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator,
9668     VkPipeline* pPipelines) {
9669     return mImpl->on_vkCreateComputePipelines(pool, snapshotInfo, boxed_device, pipelineCache,
9670                                               createInfoCount, pCreateInfos, pAllocator,
9671                                               pPipelines);
9672 }
9673 
on_vkDestroyPipeline(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkPipeline pipeline,const VkAllocationCallbacks * pAllocator)9674 void VkDecoderGlobalState::on_vkDestroyPipeline(android::base::BumpPool* pool,
9675                                                 VkSnapshotApiCallInfo* snapshotInfo,
9676                                                 VkDevice boxed_device, VkPipeline pipeline,
9677                                                 const VkAllocationCallbacks* pAllocator) {
9678     mImpl->on_vkDestroyPipeline(pool, snapshotInfo, boxed_device, pipeline, pAllocator);
9679 }
9680 
on_vkCmdCopyBufferToImage(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,VkBuffer srcBuffer,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkBufferImageCopy * pRegions,const VkDecoderContext & context)9681 void VkDecoderGlobalState::on_vkCmdCopyBufferToImage(
9682     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9683     VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
9684     VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions,
9685     const VkDecoderContext& context) {
9686     mImpl->on_vkCmdCopyBufferToImage(pool, snapshotInfo, commandBuffer, srcBuffer, dstImage,
9687                                      dstImageLayout, regionCount, pRegions, context);
9688 }
9689 
on_vkCmdCopyImage(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageCopy * pRegions)9690 void VkDecoderGlobalState::on_vkCmdCopyImage(android::base::BumpPool* pool,
9691                                              VkSnapshotApiCallInfo* snapshotInfo,
9692                                              VkCommandBuffer commandBuffer, VkImage srcImage,
9693                                              VkImageLayout srcImageLayout, VkImage dstImage,
9694                                              VkImageLayout dstImageLayout, uint32_t regionCount,
9695                                              const VkImageCopy* pRegions) {
9696     mImpl->on_vkCmdCopyImage(pool, snapshotInfo, commandBuffer, srcImage, srcImageLayout, dstImage,
9697                              dstImageLayout, regionCount, pRegions);
9698 }
on_vkCmdCopyImageToBuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferImageCopy * pRegions)9699 void VkDecoderGlobalState::on_vkCmdCopyImageToBuffer(android::base::BumpPool* pool,
9700                                                      VkSnapshotApiCallInfo* snapshotInfo,
9701                                                      VkCommandBuffer commandBuffer,
9702                                                      VkImage srcImage, VkImageLayout srcImageLayout,
9703                                                      VkBuffer dstBuffer, uint32_t regionCount,
9704                                                      const VkBufferImageCopy* pRegions) {
9705     mImpl->on_vkCmdCopyImageToBuffer(pool, snapshotInfo, commandBuffer, srcImage, srcImageLayout,
9706                                      dstBuffer, regionCount, pRegions);
9707 }
9708 
on_vkCmdCopyBufferToImage2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkCopyBufferToImageInfo2 * pCopyBufferToImageInfo,const VkDecoderContext & context)9709 void VkDecoderGlobalState::on_vkCmdCopyBufferToImage2(
9710     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9711     VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo,
9712     const VkDecoderContext& context) {
9713     mImpl->on_vkCmdCopyBufferToImage2(pool, snapshotInfo, commandBuffer, pCopyBufferToImageInfo,
9714                                       context);
9715 }
9716 
on_vkCmdCopyImage2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkCopyImageInfo2 * pCopyImageInfo)9717 void VkDecoderGlobalState::on_vkCmdCopyImage2(android::base::BumpPool* pool,
9718                                               VkSnapshotApiCallInfo* snapshotInfo,
9719                                               VkCommandBuffer commandBuffer,
9720                                               const VkCopyImageInfo2* pCopyImageInfo) {
9721     mImpl->on_vkCmdCopyImage2(pool, snapshotInfo, commandBuffer, pCopyImageInfo);
9722 }
9723 
on_vkCmdCopyImageToBuffer2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkCopyImageToBufferInfo2 * pCopyImageToBufferInfo)9724 void VkDecoderGlobalState::on_vkCmdCopyImageToBuffer2(
9725     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9726     VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo) {
9727     mImpl->on_vkCmdCopyImageToBuffer2(pool, snapshotInfo, commandBuffer, pCopyImageToBufferInfo);
9728 }
9729 
on_vkCmdCopyBufferToImage2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkCopyBufferToImageInfo2KHR * pCopyBufferToImageInfo,const VkDecoderContext & context)9730 void VkDecoderGlobalState::on_vkCmdCopyBufferToImage2KHR(
9731     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9732     VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo,
9733     const VkDecoderContext& context) {
9734     mImpl->on_vkCmdCopyBufferToImage2KHR(pool, snapshotInfo, commandBuffer, pCopyBufferToImageInfo,
9735                                          context);
9736 }
9737 
on_vkCmdCopyImage2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkCopyImageInfo2KHR * pCopyImageInfo)9738 void VkDecoderGlobalState::on_vkCmdCopyImage2KHR(android::base::BumpPool* pool,
9739                                                  VkSnapshotApiCallInfo* snapshotInfo,
9740                                                  VkCommandBuffer commandBuffer,
9741                                                  const VkCopyImageInfo2KHR* pCopyImageInfo) {
9742     mImpl->on_vkCmdCopyImage2KHR(pool, snapshotInfo, commandBuffer, pCopyImageInfo);
9743 }
9744 
on_vkCmdCopyImageToBuffer2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkCopyImageToBufferInfo2KHR * pCopyImageToBufferInfo)9745 void VkDecoderGlobalState::on_vkCmdCopyImageToBuffer2KHR(
9746     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9747     VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo) {
9748     mImpl->on_vkCmdCopyImageToBuffer2KHR(pool, snapshotInfo, commandBuffer, pCopyImageToBufferInfo);
9749 }
9750 
on_vkGetImageMemoryRequirements(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkImage image,VkMemoryRequirements * pMemoryRequirements)9751 void VkDecoderGlobalState::on_vkGetImageMemoryRequirements(
9752     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9753     VkImage image, VkMemoryRequirements* pMemoryRequirements) {
9754     mImpl->on_vkGetImageMemoryRequirements(pool, snapshotInfo, device, image, pMemoryRequirements);
9755 }
9756 
on_vkGetImageMemoryRequirements2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)9757 void VkDecoderGlobalState::on_vkGetImageMemoryRequirements2(
9758     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9759     const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements) {
9760     mImpl->on_vkGetImageMemoryRequirements2(pool, snapshotInfo, device, pInfo, pMemoryRequirements);
9761 }
9762 
on_vkGetImageMemoryRequirements2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)9763 void VkDecoderGlobalState::on_vkGetImageMemoryRequirements2KHR(
9764     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9765     const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements) {
9766     mImpl->on_vkGetImageMemoryRequirements2(pool, snapshotInfo, device, pInfo, pMemoryRequirements);
9767 }
9768 
on_vkGetBufferMemoryRequirements(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkBuffer buffer,VkMemoryRequirements * pMemoryRequirements)9769 void VkDecoderGlobalState::on_vkGetBufferMemoryRequirements(
9770     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9771     VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements) {
9772     mImpl->on_vkGetBufferMemoryRequirements(pool, snapshotInfo, device, buffer,
9773                                             pMemoryRequirements);
9774 }
9775 
on_vkGetBufferMemoryRequirements2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkBufferMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)9776 void VkDecoderGlobalState::on_vkGetBufferMemoryRequirements2(
9777     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9778     const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements) {
9779     mImpl->on_vkGetBufferMemoryRequirements2(pool, snapshotInfo, device, pInfo,
9780                                              pMemoryRequirements);
9781 }
9782 
on_vkGetBufferMemoryRequirements2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkBufferMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)9783 void VkDecoderGlobalState::on_vkGetBufferMemoryRequirements2KHR(
9784     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9785     const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements) {
9786     mImpl->on_vkGetBufferMemoryRequirements2(pool, snapshotInfo, device, pInfo,
9787                                              pMemoryRequirements);
9788 }
9789 
on_vkCmdPipelineBarrier(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkDependencyFlags dependencyFlags,uint32_t memoryBarrierCount,const VkMemoryBarrier * pMemoryBarriers,uint32_t bufferMemoryBarrierCount,const VkBufferMemoryBarrier * pBufferMemoryBarriers,uint32_t imageMemoryBarrierCount,const VkImageMemoryBarrier * pImageMemoryBarriers)9790 void VkDecoderGlobalState::on_vkCmdPipelineBarrier(
9791     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9792     VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
9793     VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
9794     uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
9795     uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
9796     uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers) {
9797     mImpl->on_vkCmdPipelineBarrier(pool, snapshotInfo, commandBuffer, srcStageMask, dstStageMask,
9798                                    dependencyFlags, memoryBarrierCount, pMemoryBarriers,
9799                                    bufferMemoryBarrierCount, pBufferMemoryBarriers,
9800                                    imageMemoryBarrierCount, pImageMemoryBarriers);
9801 }
9802 
on_vkCmdPipelineBarrier2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkDependencyInfo * pDependencyInfo)9803 void VkDecoderGlobalState::on_vkCmdPipelineBarrier2(android::base::BumpPool* pool,
9804                                                     VkSnapshotApiCallInfo* snapshotInfo,
9805                                                     VkCommandBuffer commandBuffer,
9806                                                     const VkDependencyInfo* pDependencyInfo) {
9807     mImpl->on_vkCmdPipelineBarrier2(pool, snapshotInfo, commandBuffer, pDependencyInfo);
9808 }
9809 
on_vkAllocateMemory(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkMemoryAllocateInfo * pAllocateInfo,const VkAllocationCallbacks * pAllocator,VkDeviceMemory * pMemory)9810 VkResult VkDecoderGlobalState::on_vkAllocateMemory(android::base::BumpPool* pool,
9811                                                    VkSnapshotApiCallInfo* snapshotInfo,
9812                                                    VkDevice device,
9813                                                    const VkMemoryAllocateInfo* pAllocateInfo,
9814                                                    const VkAllocationCallbacks* pAllocator,
9815                                                    VkDeviceMemory* pMemory) {
9816     return mImpl->on_vkAllocateMemory(pool, snapshotInfo, device, pAllocateInfo, pAllocator,
9817                                       pMemory);
9818 }
9819 
on_vkFreeMemory(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkDeviceMemory memory,const VkAllocationCallbacks * pAllocator)9820 void VkDecoderGlobalState::on_vkFreeMemory(android::base::BumpPool* pool,
9821                                            VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9822                                            VkDeviceMemory memory,
9823                                            const VkAllocationCallbacks* pAllocator) {
9824     mImpl->on_vkFreeMemory(pool, snapshotInfo, device, memory, pAllocator);
9825 }
9826 
on_vkMapMemory(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkDeviceMemory memory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)9827 VkResult VkDecoderGlobalState::on_vkMapMemory(android::base::BumpPool* pool,
9828                                               VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9829                                               VkDeviceMemory memory, VkDeviceSize offset,
9830                                               VkDeviceSize size, VkMemoryMapFlags flags,
9831                                               void** ppData) {
9832     return mImpl->on_vkMapMemory(pool, snapshotInfo, device, memory, offset, size, flags, ppData);
9833 }
9834 
on_vkUnmapMemory(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkDeviceMemory memory)9835 void VkDecoderGlobalState::on_vkUnmapMemory(android::base::BumpPool* pool,
9836                                             VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9837                                             VkDeviceMemory memory) {
9838     mImpl->on_vkUnmapMemory(pool, snapshotInfo, device, memory);
9839 }
9840 
getMappedHostPointer(VkDeviceMemory memory)9841 uint8_t* VkDecoderGlobalState::getMappedHostPointer(VkDeviceMemory memory) {
9842     return mImpl->getMappedHostPointer(memory);
9843 }
9844 
getDeviceMemorySize(VkDeviceMemory memory)9845 VkDeviceSize VkDecoderGlobalState::getDeviceMemorySize(VkDeviceMemory memory) {
9846     return mImpl->getDeviceMemorySize(memory);
9847 }
9848 
usingDirectMapping() const9849 bool VkDecoderGlobalState::usingDirectMapping() const { return mImpl->usingDirectMapping(); }
9850 
getHostFeatureSupport() const9851 VkDecoderGlobalState::HostFeatureSupport VkDecoderGlobalState::getHostFeatureSupport() const {
9852     return mImpl->getHostFeatureSupport();
9853 }
9854 
9855 // VK_ANDROID_native_buffer
on_vkGetSwapchainGrallocUsageANDROID(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkFormat format,VkImageUsageFlags imageUsage,int * grallocUsage)9856 VkResult VkDecoderGlobalState::on_vkGetSwapchainGrallocUsageANDROID(
9857     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9858     VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage) {
9859     return mImpl->on_vkGetSwapchainGrallocUsageANDROID(pool, snapshotInfo, device, format,
9860                                                        imageUsage, grallocUsage);
9861 }
9862 
on_vkGetSwapchainGrallocUsage2ANDROID(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkFormat format,VkImageUsageFlags imageUsage,VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,uint64_t * grallocConsumerUsage,uint64_t * grallocProducerUsage)9863 VkResult VkDecoderGlobalState::on_vkGetSwapchainGrallocUsage2ANDROID(
9864     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9865     VkFormat format, VkImageUsageFlags imageUsage,
9866     VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, uint64_t* grallocConsumerUsage,
9867     uint64_t* grallocProducerUsage) {
9868     return mImpl->on_vkGetSwapchainGrallocUsage2ANDROID(pool, snapshotInfo, device, format,
9869                                                         imageUsage, swapchainImageUsage,
9870                                                         grallocConsumerUsage, grallocProducerUsage);
9871 }
9872 
on_vkAcquireImageANDROID(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkImage image,int nativeFenceFd,VkSemaphore semaphore,VkFence fence)9873 VkResult VkDecoderGlobalState::on_vkAcquireImageANDROID(android::base::BumpPool* pool,
9874                                                         VkSnapshotApiCallInfo* snapshotInfo,
9875                                                         VkDevice device, VkImage image,
9876                                                         int nativeFenceFd, VkSemaphore semaphore,
9877                                                         VkFence fence) {
9878     return mImpl->on_vkAcquireImageANDROID(pool, snapshotInfo, device, image, nativeFenceFd,
9879                                            semaphore, fence);
9880 }
9881 
on_vkQueueSignalReleaseImageANDROID(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image,int * pNativeFenceFd)9882 VkResult VkDecoderGlobalState::on_vkQueueSignalReleaseImageANDROID(
9883     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkQueue queue,
9884     uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, VkImage image,
9885     int* pNativeFenceFd) {
9886     return mImpl->on_vkQueueSignalReleaseImageANDROID(pool, snapshotInfo, queue, waitSemaphoreCount,
9887                                                       pWaitSemaphores, image, pNativeFenceFd);
9888 }
9889 
9890 // VK_GOOGLE_gfxstream
on_vkMapMemoryIntoAddressSpaceGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkDeviceMemory memory,uint64_t * pAddress)9891 VkResult VkDecoderGlobalState::on_vkMapMemoryIntoAddressSpaceGOOGLE(
9892     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9893     VkDeviceMemory memory, uint64_t* pAddress) {
9894     return mImpl->on_vkMapMemoryIntoAddressSpaceGOOGLE(pool, snapshotInfo, device, memory,
9895                                                        pAddress);
9896 }
9897 
on_vkGetMemoryHostAddressInfoGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkDeviceMemory memory,uint64_t * pAddress,uint64_t * pSize,uint64_t * pHostmemId)9898 VkResult VkDecoderGlobalState::on_vkGetMemoryHostAddressInfoGOOGLE(
9899     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9900     VkDeviceMemory memory, uint64_t* pAddress, uint64_t* pSize, uint64_t* pHostmemId) {
9901     return mImpl->on_vkGetMemoryHostAddressInfoGOOGLE(pool, snapshotInfo, device, memory, pAddress,
9902                                                       pSize, pHostmemId);
9903 }
9904 
on_vkGetBlobGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkDeviceMemory memory)9905 VkResult VkDecoderGlobalState::on_vkGetBlobGOOGLE(android::base::BumpPool* pool,
9906                                                   VkSnapshotApiCallInfo* snapshotInfo,
9907                                                   VkDevice device, VkDeviceMemory memory) {
9908     return mImpl->on_vkGetBlobGOOGLE(pool, snapshotInfo, device, memory);
9909 }
9910 
on_vkFreeMemorySyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkDeviceMemory memory,const VkAllocationCallbacks * pAllocator)9911 VkResult VkDecoderGlobalState::on_vkFreeMemorySyncGOOGLE(android::base::BumpPool* pool,
9912                                                          VkSnapshotApiCallInfo* snapshotInfo,
9913                                                          VkDevice device, VkDeviceMemory memory,
9914                                                          const VkAllocationCallbacks* pAllocator) {
9915     return mImpl->on_vkFreeMemorySyncGOOGLE(pool, snapshotInfo, device, memory, pAllocator);
9916 }
9917 
on_vkAllocateCommandBuffers(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkCommandBufferAllocateInfo * pAllocateInfo,VkCommandBuffer * pCommandBuffers)9918 VkResult VkDecoderGlobalState::on_vkAllocateCommandBuffers(
9919     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
9920     const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers) {
9921     return mImpl->on_vkAllocateCommandBuffers(pool, snapshotInfo, device, pAllocateInfo,
9922                                               pCommandBuffers);
9923 }
9924 
on_vkCreateCommandPool(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkCommandPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkCommandPool * pCommandPool)9925 VkResult VkDecoderGlobalState::on_vkCreateCommandPool(android::base::BumpPool* pool,
9926                                                       VkSnapshotApiCallInfo* snapshotInfo,
9927                                                       VkDevice device,
9928                                                       const VkCommandPoolCreateInfo* pCreateInfo,
9929                                                       const VkAllocationCallbacks* pAllocator,
9930                                                       VkCommandPool* pCommandPool) {
9931     return mImpl->on_vkCreateCommandPool(pool, snapshotInfo, device, pCreateInfo, pAllocator,
9932                                          pCommandPool);
9933 }
9934 
on_vkDestroyCommandPool(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkCommandPool commandPool,const VkAllocationCallbacks * pAllocator)9935 void VkDecoderGlobalState::on_vkDestroyCommandPool(android::base::BumpPool* pool,
9936                                                    VkSnapshotApiCallInfo* snapshotInfo,
9937                                                    VkDevice device, VkCommandPool commandPool,
9938                                                    const VkAllocationCallbacks* pAllocator) {
9939     mImpl->on_vkDestroyCommandPool(pool, snapshotInfo, device, commandPool, pAllocator);
9940 }
9941 
on_vkResetCommandPool(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkCommandPool commandPool,VkCommandPoolResetFlags flags)9942 VkResult VkDecoderGlobalState::on_vkResetCommandPool(android::base::BumpPool* pool,
9943                                                      VkSnapshotApiCallInfo* snapshotInfo,
9944                                                      VkDevice device, VkCommandPool commandPool,
9945                                                      VkCommandPoolResetFlags flags) {
9946     return mImpl->on_vkResetCommandPool(pool, snapshotInfo, device, commandPool, flags);
9947 }
9948 
on_vkCmdExecuteCommands(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)9949 void VkDecoderGlobalState::on_vkCmdExecuteCommands(android::base::BumpPool* pool,
9950                                                    VkSnapshotApiCallInfo* snapshotInfo,
9951                                                    VkCommandBuffer commandBuffer,
9952                                                    uint32_t commandBufferCount,
9953                                                    const VkCommandBuffer* pCommandBuffers) {
9954     return mImpl->on_vkCmdExecuteCommands(pool, snapshotInfo, commandBuffer, commandBufferCount,
9955                                           pCommandBuffers);
9956 }
9957 
on_vkQueueSubmit(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue,uint32_t submitCount,const VkSubmitInfo * pSubmits,VkFence fence)9958 VkResult VkDecoderGlobalState::on_vkQueueSubmit(android::base::BumpPool* pool,
9959                                                 VkSnapshotApiCallInfo* snapshotInfo, VkQueue queue,
9960                                                 uint32_t submitCount, const VkSubmitInfo* pSubmits,
9961                                                 VkFence fence) {
9962     return mImpl->on_vkQueueSubmit(pool, snapshotInfo, queue, submitCount, pSubmits, fence);
9963 }
9964 
on_vkQueueSubmit2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue,uint32_t submitCount,const VkSubmitInfo2 * pSubmits,VkFence fence)9965 VkResult VkDecoderGlobalState::on_vkQueueSubmit2(android::base::BumpPool* pool,
9966                                                  VkSnapshotApiCallInfo* snapshotInfo, VkQueue queue,
9967                                                  uint32_t submitCount,
9968                                                  const VkSubmitInfo2* pSubmits, VkFence fence) {
9969     return mImpl->on_vkQueueSubmit(pool, snapshotInfo, queue, submitCount, pSubmits, fence);
9970 }
9971 
on_vkQueueWaitIdle(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue)9972 VkResult VkDecoderGlobalState::on_vkQueueWaitIdle(android::base::BumpPool* pool,
9973                                                   VkSnapshotApiCallInfo* snapshotInfo,
9974                                                   VkQueue queue) {
9975     return mImpl->on_vkQueueWaitIdle(pool, snapshotInfo, queue);
9976 }
9977 
on_vkResetCommandBuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,VkCommandBufferResetFlags flags)9978 VkResult VkDecoderGlobalState::on_vkResetCommandBuffer(android::base::BumpPool* pool,
9979                                                        VkSnapshotApiCallInfo* snapshotInfo,
9980                                                        VkCommandBuffer commandBuffer,
9981                                                        VkCommandBufferResetFlags flags) {
9982     return mImpl->on_vkResetCommandBuffer(pool, snapshotInfo, commandBuffer, flags);
9983 }
9984 
on_vkFreeCommandBuffers(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkCommandPool commandPool,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)9985 void VkDecoderGlobalState::on_vkFreeCommandBuffers(android::base::BumpPool* pool,
9986                                                    VkSnapshotApiCallInfo* snapshotInfo,
9987                                                    VkDevice device, VkCommandPool commandPool,
9988                                                    uint32_t commandBufferCount,
9989                                                    const VkCommandBuffer* pCommandBuffers) {
9990     return mImpl->on_vkFreeCommandBuffers(pool, snapshotInfo, device, commandPool,
9991                                           commandBufferCount, pCommandBuffers);
9992 }
9993 
on_vkGetPhysicalDeviceExternalSemaphoreProperties(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,VkExternalSemaphoreProperties * pExternalSemaphoreProperties)9994 void VkDecoderGlobalState::on_vkGetPhysicalDeviceExternalSemaphoreProperties(
9995     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
9996     VkPhysicalDevice physicalDevice,
9997     const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
9998     VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
9999     return mImpl->on_vkGetPhysicalDeviceExternalSemaphoreProperties(
10000         pool, snapshotInfo, physicalDevice, pExternalSemaphoreInfo, pExternalSemaphoreProperties);
10001 }
10002 
on_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,VkExternalSemaphoreProperties * pExternalSemaphoreProperties)10003 void VkDecoderGlobalState::on_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(
10004     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
10005     VkPhysicalDevice physicalDevice,
10006     const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
10007     VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
10008     return mImpl->on_vkGetPhysicalDeviceExternalSemaphoreProperties(
10009         pool, snapshotInfo, physicalDevice, pExternalSemaphoreInfo, pExternalSemaphoreProperties);
10010 }
10011 
10012 // Descriptor update templates
on_vkCreateDescriptorUpdateTemplate(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate)10013 VkResult VkDecoderGlobalState::on_vkCreateDescriptorUpdateTemplate(
10014     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
10015     const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
10016     const VkAllocationCallbacks* pAllocator,
10017     VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
10018     return mImpl->on_vkCreateDescriptorUpdateTemplate(pool, snapshotInfo, boxed_device, pCreateInfo,
10019                                                       pAllocator, pDescriptorUpdateTemplate);
10020 }
10021 
on_vkCreateDescriptorUpdateTemplateKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate)10022 VkResult VkDecoderGlobalState::on_vkCreateDescriptorUpdateTemplateKHR(
10023     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
10024     const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
10025     const VkAllocationCallbacks* pAllocator,
10026     VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
10027     return mImpl->on_vkCreateDescriptorUpdateTemplateKHR(
10028         pool, snapshotInfo, boxed_device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
10029 }
10030 
on_vkDestroyDescriptorUpdateTemplate(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkDescriptorUpdateTemplate descriptorUpdateTemplate,const VkAllocationCallbacks * pAllocator)10031 void VkDecoderGlobalState::on_vkDestroyDescriptorUpdateTemplate(
10032     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
10033     VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator) {
10034     mImpl->on_vkDestroyDescriptorUpdateTemplate(pool, snapshotInfo, boxed_device,
10035                                                 descriptorUpdateTemplate, pAllocator);
10036 }
10037 
on_vkDestroyDescriptorUpdateTemplateKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkDescriptorUpdateTemplate descriptorUpdateTemplate,const VkAllocationCallbacks * pAllocator)10038 void VkDecoderGlobalState::on_vkDestroyDescriptorUpdateTemplateKHR(
10039     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
10040     VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator) {
10041     mImpl->on_vkDestroyDescriptorUpdateTemplateKHR(pool, snapshotInfo, boxed_device,
10042                                                    descriptorUpdateTemplate, pAllocator);
10043 }
10044 
on_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkDescriptorSet descriptorSet,VkDescriptorUpdateTemplate descriptorUpdateTemplate,uint32_t imageInfoCount,uint32_t bufferInfoCount,uint32_t bufferViewCount,const uint32_t * pImageInfoEntryIndices,const uint32_t * pBufferInfoEntryIndices,const uint32_t * pBufferViewEntryIndices,const VkDescriptorImageInfo * pImageInfos,const VkDescriptorBufferInfo * pBufferInfos,const VkBufferView * pBufferViews)10045 void VkDecoderGlobalState::on_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(
10046     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
10047     VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
10048     uint32_t imageInfoCount, uint32_t bufferInfoCount, uint32_t bufferViewCount,
10049     const uint32_t* pImageInfoEntryIndices, const uint32_t* pBufferInfoEntryIndices,
10050     const uint32_t* pBufferViewEntryIndices, const VkDescriptorImageInfo* pImageInfos,
10051     const VkDescriptorBufferInfo* pBufferInfos, const VkBufferView* pBufferViews) {
10052     mImpl->on_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(
10053         pool, snapshotInfo, boxed_device, descriptorSet, descriptorUpdateTemplate, imageInfoCount,
10054         bufferInfoCount, bufferViewCount, pImageInfoEntryIndices, pBufferInfoEntryIndices,
10055         pBufferViewEntryIndices, pImageInfos, pBufferInfos, pBufferViews);
10056 }
10057 
on_vkUpdateDescriptorSetWithTemplateSized2GOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkDescriptorSet descriptorSet,VkDescriptorUpdateTemplate descriptorUpdateTemplate,uint32_t imageInfoCount,uint32_t bufferInfoCount,uint32_t bufferViewCount,uint32_t inlineUniformBlockCount,const uint32_t * pImageInfoEntryIndices,const uint32_t * pBufferInfoEntryIndices,const uint32_t * pBufferViewEntryIndices,const VkDescriptorImageInfo * pImageInfos,const VkDescriptorBufferInfo * pBufferInfos,const VkBufferView * pBufferViews,const uint8_t * pInlineUniformBlockData)10058 void VkDecoderGlobalState::on_vkUpdateDescriptorSetWithTemplateSized2GOOGLE(
10059     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
10060     VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
10061     uint32_t imageInfoCount, uint32_t bufferInfoCount, uint32_t bufferViewCount,
10062     uint32_t inlineUniformBlockCount, const uint32_t* pImageInfoEntryIndices,
10063     const uint32_t* pBufferInfoEntryIndices, const uint32_t* pBufferViewEntryIndices,
10064     const VkDescriptorImageInfo* pImageInfos, const VkDescriptorBufferInfo* pBufferInfos,
10065     const VkBufferView* pBufferViews, const uint8_t* pInlineUniformBlockData) {
10066     mImpl->on_vkUpdateDescriptorSetWithTemplateSized2GOOGLE(
10067         pool, snapshotInfo, boxed_device, descriptorSet, descriptorUpdateTemplate, imageInfoCount,
10068         bufferInfoCount, bufferViewCount, inlineUniformBlockCount, pImageInfoEntryIndices,
10069         pBufferInfoEntryIndices, pBufferViewEntryIndices, pImageInfos, pBufferInfos, pBufferViews,
10070         pInlineUniformBlockData);
10071 }
10072 
on_vkBeginCommandBuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkCommandBufferBeginInfo * pBeginInfo,const VkDecoderContext & context)10073 VkResult VkDecoderGlobalState::on_vkBeginCommandBuffer(android::base::BumpPool* pool,
10074                                                        VkSnapshotApiCallInfo* snapshotInfo,
10075                                                        VkCommandBuffer commandBuffer,
10076                                                        const VkCommandBufferBeginInfo* pBeginInfo,
10077                                                        const VkDecoderContext& context) {
10078     return mImpl->on_vkBeginCommandBuffer(pool, snapshotInfo, commandBuffer, pBeginInfo, context);
10079 }
10080 
on_vkBeginCommandBufferAsyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkCommandBufferBeginInfo * pBeginInfo,const VkDecoderContext & context)10081 void VkDecoderGlobalState::on_vkBeginCommandBufferAsyncGOOGLE(
10082     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
10083     VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo,
10084     const VkDecoderContext& context) {
10085     mImpl->on_vkBeginCommandBuffer(pool, snapshotInfo, commandBuffer, pBeginInfo, context);
10086 }
10087 
on_vkEndCommandBuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkDecoderContext & context)10088 VkResult VkDecoderGlobalState::on_vkEndCommandBuffer(android::base::BumpPool* pool,
10089                                                      VkSnapshotApiCallInfo* snapshotInfo,
10090                                                      VkCommandBuffer commandBuffer,
10091                                                      const VkDecoderContext& context) {
10092     return mImpl->on_vkEndCommandBuffer(pool, snapshotInfo, commandBuffer, context);
10093 }
10094 
on_vkEndCommandBufferAsyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkDecoderContext & context)10095 void VkDecoderGlobalState::on_vkEndCommandBufferAsyncGOOGLE(android::base::BumpPool* pool,
10096                                                             VkSnapshotApiCallInfo* snapshotInfo,
10097                                                             VkCommandBuffer commandBuffer,
10098                                                             const VkDecoderContext& context) {
10099     mImpl->on_vkEndCommandBufferAsyncGOOGLE(pool, snapshotInfo, commandBuffer, context);
10100 }
10101 
on_vkResetCommandBufferAsyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,VkCommandBufferResetFlags flags)10102 void VkDecoderGlobalState::on_vkResetCommandBufferAsyncGOOGLE(android::base::BumpPool* pool,
10103                                                               VkSnapshotApiCallInfo* snapshotInfo,
10104                                                               VkCommandBuffer commandBuffer,
10105                                                               VkCommandBufferResetFlags flags) {
10106     mImpl->on_vkResetCommandBufferAsyncGOOGLE(pool, snapshotInfo, commandBuffer, flags);
10107 }
10108 
on_vkCommandBufferHostSyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,uint32_t needHostSync,uint32_t sequenceNumber)10109 void VkDecoderGlobalState::on_vkCommandBufferHostSyncGOOGLE(android::base::BumpPool* pool,
10110                                                             VkSnapshotApiCallInfo* snapshotInfo,
10111                                                             VkCommandBuffer commandBuffer,
10112                                                             uint32_t needHostSync,
10113                                                             uint32_t sequenceNumber) {
10114     mImpl->hostSyncCommandBuffer("hostSync", commandBuffer, needHostSync, sequenceNumber);
10115 }
10116 
on_vkCreateImageWithRequirementsGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage,VkMemoryRequirements * pMemoryRequirements)10117 VkResult VkDecoderGlobalState::on_vkCreateImageWithRequirementsGOOGLE(
10118     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
10119     const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage,
10120     VkMemoryRequirements* pMemoryRequirements) {
10121     return mImpl->on_vkCreateImageWithRequirementsGOOGLE(pool, snapshotInfo, device, pCreateInfo,
10122                                                          pAllocator, pImage, pMemoryRequirements);
10123 }
10124 
on_vkCreateBufferWithRequirementsGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer,VkMemoryRequirements * pMemoryRequirements)10125 VkResult VkDecoderGlobalState::on_vkCreateBufferWithRequirementsGOOGLE(
10126     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
10127     const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
10128     VkBuffer* pBuffer, VkMemoryRequirements* pMemoryRequirements) {
10129     return mImpl->on_vkCreateBufferWithRequirementsGOOGLE(pool, snapshotInfo, device, pCreateInfo,
10130                                                           pAllocator, pBuffer, pMemoryRequirements);
10131 }
10132 
on_vkCmdBindPipeline(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipeline pipeline)10133 void VkDecoderGlobalState::on_vkCmdBindPipeline(android::base::BumpPool* pool,
10134                                                 VkSnapshotApiCallInfo* snapshotInfo,
10135                                                 VkCommandBuffer commandBuffer,
10136                                                 VkPipelineBindPoint pipelineBindPoint,
10137                                                 VkPipeline pipeline) {
10138     mImpl->on_vkCmdBindPipeline(pool, snapshotInfo, commandBuffer, pipelineBindPoint, pipeline);
10139 }
10140 
on_vkCmdBindDescriptorSets(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipelineLayout layout,uint32_t firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets,uint32_t dynamicOffsetCount,const uint32_t * pDynamicOffsets)10141 void VkDecoderGlobalState::on_vkCmdBindDescriptorSets(
10142     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
10143     VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
10144     uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets,
10145     uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets) {
10146     mImpl->on_vkCmdBindDescriptorSets(pool, snapshotInfo, commandBuffer, pipelineBindPoint, layout,
10147                                       firstSet, descriptorSetCount, pDescriptorSets,
10148                                       dynamicOffsetCount, pDynamicOffsets);
10149 }
10150 
on_vkCreateRenderPass(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkRenderPassCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)10151 VkResult VkDecoderGlobalState::on_vkCreateRenderPass(android::base::BumpPool* pool,
10152                                                      VkSnapshotApiCallInfo* snapshotInfo,
10153                                                      VkDevice boxed_device,
10154                                                      const VkRenderPassCreateInfo* pCreateInfo,
10155                                                      const VkAllocationCallbacks* pAllocator,
10156                                                      VkRenderPass* pRenderPass) {
10157     return mImpl->on_vkCreateRenderPass(pool, snapshotInfo, boxed_device, pCreateInfo, pAllocator,
10158                                         pRenderPass);
10159 }
10160 
on_vkCreateRenderPass2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkRenderPassCreateInfo2 * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)10161 VkResult VkDecoderGlobalState::on_vkCreateRenderPass2(android::base::BumpPool* pool,
10162                                                       VkSnapshotApiCallInfo* snapshotInfo,
10163                                                       VkDevice boxed_device,
10164                                                       const VkRenderPassCreateInfo2* pCreateInfo,
10165                                                       const VkAllocationCallbacks* pAllocator,
10166                                                       VkRenderPass* pRenderPass) {
10167     return mImpl->on_vkCreateRenderPass2(pool, snapshotInfo, boxed_device, pCreateInfo, pAllocator,
10168                                          pRenderPass);
10169 }
10170 
on_vkCreateRenderPass2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkRenderPassCreateInfo2KHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)10171 VkResult VkDecoderGlobalState::on_vkCreateRenderPass2KHR(
10172     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice boxed_device,
10173     const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator,
10174     VkRenderPass* pRenderPass) {
10175     return mImpl->on_vkCreateRenderPass2(pool, snapshotInfo, boxed_device, pCreateInfo, pAllocator,
10176                                          pRenderPass);
10177 }
10178 
on_vkDestroyRenderPass(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkRenderPass renderPass,const VkAllocationCallbacks * pAllocator)10179 void VkDecoderGlobalState::on_vkDestroyRenderPass(android::base::BumpPool* pool,
10180                                                   VkSnapshotApiCallInfo* snapshotInfo,
10181                                                   VkDevice boxed_device, VkRenderPass renderPass,
10182                                                   const VkAllocationCallbacks* pAllocator) {
10183     mImpl->on_vkDestroyRenderPass(pool, snapshotInfo, boxed_device, renderPass, pAllocator);
10184 }
10185 
on_vkCmdBeginRenderPass(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkRenderPassBeginInfo * pRenderPassBegin,VkSubpassContents contents)10186 void VkDecoderGlobalState::on_vkCmdBeginRenderPass(android::base::BumpPool* pool,
10187                                                    VkSnapshotApiCallInfo* snapshotInfo,
10188                                                    VkCommandBuffer commandBuffer,
10189                                                    const VkRenderPassBeginInfo* pRenderPassBegin,
10190                                                    VkSubpassContents contents) {
10191     return mImpl->on_vkCmdBeginRenderPass(pool, snapshotInfo, commandBuffer, pRenderPassBegin,
10192                                           contents);
10193 }
10194 
on_vkCmdBeginRenderPass2(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkRenderPassBeginInfo * pRenderPassBegin,const VkSubpassBeginInfo * pSubpassBeginInfo)10195 void VkDecoderGlobalState::on_vkCmdBeginRenderPass2(android::base::BumpPool* pool,
10196                                                     VkSnapshotApiCallInfo* snapshotInfo,
10197                                                     VkCommandBuffer commandBuffer,
10198                                                     const VkRenderPassBeginInfo* pRenderPassBegin,
10199                                                     const VkSubpassBeginInfo* pSubpassBeginInfo) {
10200     return mImpl->on_vkCmdBeginRenderPass2(pool, snapshotInfo, commandBuffer, pRenderPassBegin,
10201                                            pSubpassBeginInfo);
10202 }
10203 
on_vkCmdBeginRenderPass2KHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,const VkRenderPassBeginInfo * pRenderPassBegin,const VkSubpassBeginInfo * pSubpassBeginInfo)10204 void VkDecoderGlobalState::on_vkCmdBeginRenderPass2KHR(
10205     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
10206     VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin,
10207     const VkSubpassBeginInfo* pSubpassBeginInfo) {
10208     return mImpl->on_vkCmdBeginRenderPass2(pool, snapshotInfo, commandBuffer, pRenderPassBegin,
10209                                            pSubpassBeginInfo);
10210 }
10211 
on_vkCreateFramebuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,const VkFramebufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkFramebuffer * pFramebuffer)10212 VkResult VkDecoderGlobalState::on_vkCreateFramebuffer(android::base::BumpPool* pool,
10213                                                       VkSnapshotApiCallInfo* snapshotInfo,
10214                                                       VkDevice boxed_device,
10215                                                       const VkFramebufferCreateInfo* pCreateInfo,
10216                                                       const VkAllocationCallbacks* pAllocator,
10217                                                       VkFramebuffer* pFramebuffer) {
10218     return mImpl->on_vkCreateFramebuffer(pool, snapshotInfo, boxed_device, pCreateInfo, pAllocator,
10219                                          pFramebuffer);
10220 }
10221 
on_vkDestroyFramebuffer(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice boxed_device,VkFramebuffer framebuffer,const VkAllocationCallbacks * pAllocator)10222 void VkDecoderGlobalState::on_vkDestroyFramebuffer(android::base::BumpPool* pool,
10223                                                    VkSnapshotApiCallInfo* snapshotInfo,
10224                                                    VkDevice boxed_device, VkFramebuffer framebuffer,
10225                                                    const VkAllocationCallbacks* pAllocator) {
10226     mImpl->on_vkDestroyFramebuffer(pool, snapshotInfo, boxed_device, framebuffer, pAllocator);
10227 }
10228 
on_vkQueueHostSyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue,uint32_t needHostSync,uint32_t sequenceNumber)10229 void VkDecoderGlobalState::on_vkQueueHostSyncGOOGLE(android::base::BumpPool* pool,
10230                                                     VkSnapshotApiCallInfo* snapshotInfo,
10231                                                     VkQueue queue, uint32_t needHostSync,
10232                                                     uint32_t sequenceNumber) {
10233     mImpl->hostSyncQueue("hostSyncQueue", queue, needHostSync, sequenceNumber);
10234 }
10235 
on_vkCmdCopyQueryPoolResults(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize stride,VkQueryResultFlags flags)10236 void VkDecoderGlobalState::on_vkCmdCopyQueryPoolResults(
10237     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo,
10238     VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
10239     VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags) {
10240     mImpl->on_vkCmdCopyQueryPoolResults(pool, snapshotInfo, commandBuffer, queryPool, firstQuery,
10241                                         queryCount, dstBuffer, dstOffset, stride, flags);
10242 }
10243 
on_vkQueueSubmitAsyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue,uint32_t submitCount,const VkSubmitInfo * pSubmits,VkFence fence)10244 void VkDecoderGlobalState::on_vkQueueSubmitAsyncGOOGLE(android::base::BumpPool* pool,
10245                                                        VkSnapshotApiCallInfo* snapshotInfo,
10246                                                        VkQueue queue, uint32_t submitCount,
10247                                                        const VkSubmitInfo* pSubmits,
10248                                                        VkFence fence) {
10249     mImpl->on_vkQueueSubmit(pool, snapshotInfo, queue, submitCount, pSubmits, fence);
10250 }
10251 
on_vkQueueSubmitAsync2GOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue,uint32_t submitCount,const VkSubmitInfo2 * pSubmits,VkFence fence)10252 void VkDecoderGlobalState::on_vkQueueSubmitAsync2GOOGLE(android::base::BumpPool* pool,
10253                                                         VkSnapshotApiCallInfo* snapshotInfo,
10254                                                         VkQueue queue, uint32_t submitCount,
10255                                                         const VkSubmitInfo2* pSubmits,
10256                                                         VkFence fence) {
10257     mImpl->on_vkQueueSubmit(pool, snapshotInfo, queue, submitCount, pSubmits, fence);
10258 }
10259 
on_vkQueueWaitIdleAsyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue)10260 void VkDecoderGlobalState::on_vkQueueWaitIdleAsyncGOOGLE(android::base::BumpPool* pool,
10261                                                          VkSnapshotApiCallInfo* snapshotInfo,
10262                                                          VkQueue queue) {
10263     mImpl->on_vkQueueWaitIdle(pool, snapshotInfo, queue);
10264 }
10265 
on_vkQueueBindSparseAsyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue,uint32_t bindInfoCount,const VkBindSparseInfo * pBindInfo,VkFence fence)10266 void VkDecoderGlobalState::on_vkQueueBindSparseAsyncGOOGLE(android::base::BumpPool* pool,
10267                                                            VkSnapshotApiCallInfo* snapshotInfo,
10268                                                            VkQueue queue, uint32_t bindInfoCount,
10269                                                            const VkBindSparseInfo* pBindInfo,
10270                                                            VkFence fence) {
10271     VkResult res =
10272         mImpl->on_vkQueueBindSparse(pool, snapshotInfo, queue, bindInfoCount, pBindInfo, fence);
10273     if (res != VK_SUCCESS) {
10274         // Report an error here as we don't use the result after this call
10275         ERR("vkQueueBindSparse failed with: %s [%d], bindInfoCount=%d, fence=%p",
10276             string_VkResult(res), res, bindInfoCount, fence);
10277     }
10278 }
10279 
on_vkGetLinearImageLayoutGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkFormat format,VkDeviceSize * pOffset,VkDeviceSize * pRowPitchAlignment)10280 void VkDecoderGlobalState::on_vkGetLinearImageLayoutGOOGLE(android::base::BumpPool* pool,
10281                                                            VkSnapshotApiCallInfo* snapshotInfo,
10282                                                            VkDevice device, VkFormat format,
10283                                                            VkDeviceSize* pOffset,
10284                                                            VkDeviceSize* pRowPitchAlignment) {
10285     mImpl->on_vkGetLinearImageLayoutGOOGLE(pool, snapshotInfo, device, format, pOffset,
10286                                            pRowPitchAlignment);
10287 }
10288 
on_vkGetLinearImageLayout2GOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkImageCreateInfo * pCreateInfo,VkDeviceSize * pOffset,VkDeviceSize * pRowPitchAlignment)10289 void VkDecoderGlobalState::on_vkGetLinearImageLayout2GOOGLE(
10290     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
10291     const VkImageCreateInfo* pCreateInfo, VkDeviceSize* pOffset, VkDeviceSize* pRowPitchAlignment) {
10292     mImpl->on_vkGetLinearImageLayout2GOOGLE(pool, snapshotInfo, device, pCreateInfo, pOffset,
10293                                             pRowPitchAlignment);
10294 }
10295 
on_vkQueueFlushCommandsGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue,VkCommandBuffer commandBuffer,VkDeviceSize dataSize,const void * pData,const VkDecoderContext & context)10296 void VkDecoderGlobalState::on_vkQueueFlushCommandsGOOGLE(android::base::BumpPool* pool,
10297                                                          VkSnapshotApiCallInfo* snapshotInfo,
10298                                                          VkQueue queue,
10299                                                          VkCommandBuffer commandBuffer,
10300                                                          VkDeviceSize dataSize, const void* pData,
10301                                                          const VkDecoderContext& context) {
10302     mImpl->on_vkQueueFlushCommandsGOOGLE(pool, snapshotInfo, queue, commandBuffer, dataSize, pData,
10303                                          context);
10304 }
10305 
on_vkQueueFlushCommandsFromAuxMemoryGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue,VkCommandBuffer commandBuffer,VkDeviceMemory deviceMemory,VkDeviceSize dataOffset,VkDeviceSize dataSize,const VkDecoderContext & context)10306 void VkDecoderGlobalState::on_vkQueueFlushCommandsFromAuxMemoryGOOGLE(
10307     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkQueue queue,
10308     VkCommandBuffer commandBuffer, VkDeviceMemory deviceMemory, VkDeviceSize dataOffset,
10309     VkDeviceSize dataSize, const VkDecoderContext& context) {
10310     mImpl->on_vkQueueFlushCommandsFromAuxMemoryGOOGLE(pool, snapshotInfo, queue, commandBuffer,
10311                                                       deviceMemory, dataOffset, dataSize, context);
10312 }
10313 
on_vkQueueCommitDescriptorSetUpdatesGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue,uint32_t descriptorPoolCount,const VkDescriptorPool * pDescriptorPools,uint32_t descriptorSetCount,const VkDescriptorSetLayout * pDescriptorSetLayouts,const uint64_t * pDescriptorSetPoolIds,const uint32_t * pDescriptorSetWhichPool,const uint32_t * pDescriptorSetPendingAllocation,const uint32_t * pDescriptorWriteStartingIndices,uint32_t pendingDescriptorWriteCount,const VkWriteDescriptorSet * pPendingDescriptorWrites)10314 void VkDecoderGlobalState::on_vkQueueCommitDescriptorSetUpdatesGOOGLE(
10315     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkQueue queue,
10316     uint32_t descriptorPoolCount, const VkDescriptorPool* pDescriptorPools,
10317     uint32_t descriptorSetCount, const VkDescriptorSetLayout* pDescriptorSetLayouts,
10318     const uint64_t* pDescriptorSetPoolIds, const uint32_t* pDescriptorSetWhichPool,
10319     const uint32_t* pDescriptorSetPendingAllocation,
10320     const uint32_t* pDescriptorWriteStartingIndices, uint32_t pendingDescriptorWriteCount,
10321     const VkWriteDescriptorSet* pPendingDescriptorWrites) {
10322     mImpl->on_vkQueueCommitDescriptorSetUpdatesGOOGLE(
10323         pool, snapshotInfo, queue, descriptorPoolCount, pDescriptorPools, descriptorSetCount,
10324         pDescriptorSetLayouts, pDescriptorSetPoolIds, pDescriptorSetWhichPool,
10325         pDescriptorSetPendingAllocation, pDescriptorWriteStartingIndices,
10326         pendingDescriptorWriteCount, pPendingDescriptorWrites);
10327 }
10328 
on_vkCollectDescriptorPoolIdsGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkDescriptorPool descriptorPool,uint32_t * pPoolIdCount,uint64_t * pPoolIds)10329 void VkDecoderGlobalState::on_vkCollectDescriptorPoolIdsGOOGLE(
10330     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
10331     VkDescriptorPool descriptorPool, uint32_t* pPoolIdCount, uint64_t* pPoolIds) {
10332     mImpl->on_vkCollectDescriptorPoolIdsGOOGLE(pool, snapshotInfo, device, descriptorPool,
10333                                                pPoolIdCount, pPoolIds);
10334 }
10335 
on_vkQueueBindSparse(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue,uint32_t bindInfoCount,const VkBindSparseInfo * pBindInfo,VkFence fence)10336 VkResult VkDecoderGlobalState::on_vkQueueBindSparse(android::base::BumpPool* pool,
10337                                                     VkSnapshotApiCallInfo* snapshotInfo,
10338                                                     VkQueue queue, uint32_t bindInfoCount,
10339                                                     const VkBindSparseInfo* pBindInfo,
10340                                                     VkFence fence) {
10341     return mImpl->on_vkQueueBindSparse(pool, snapshotInfo, queue, bindInfoCount, pBindInfo, fence);
10342 }
10343 
on_vkQueueSignalReleaseImageANDROIDAsyncGOOGLE(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkQueue queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image)10344 void VkDecoderGlobalState::on_vkQueueSignalReleaseImageANDROIDAsyncGOOGLE(
10345     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkQueue queue,
10346     uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, VkImage image) {
10347     int fenceFd;
10348     mImpl->on_vkQueueSignalReleaseImageANDROID(pool, snapshotInfo, queue, waitSemaphoreCount,
10349                                                pWaitSemaphores, image, &fenceFd);
10350 }
10351 
on_vkCreateSamplerYcbcrConversion(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkSamplerYcbcrConversionCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSamplerYcbcrConversion * pYcbcrConversion)10352 VkResult VkDecoderGlobalState::on_vkCreateSamplerYcbcrConversion(
10353     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
10354     const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
10355     VkSamplerYcbcrConversion* pYcbcrConversion) {
10356     return mImpl->on_vkCreateSamplerYcbcrConversion(pool, snapshotInfo, device, pCreateInfo,
10357                                                     pAllocator, pYcbcrConversion);
10358 }
10359 
on_vkCreateSamplerYcbcrConversionKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,const VkSamplerYcbcrConversionCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSamplerYcbcrConversion * pYcbcrConversion)10360 VkResult VkDecoderGlobalState::on_vkCreateSamplerYcbcrConversionKHR(
10361     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
10362     const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
10363     VkSamplerYcbcrConversion* pYcbcrConversion) {
10364     return mImpl->on_vkCreateSamplerYcbcrConversion(pool, snapshotInfo, device, pCreateInfo,
10365                                                     pAllocator, pYcbcrConversion);
10366 }
10367 
on_vkDestroySamplerYcbcrConversion(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkSamplerYcbcrConversion ycbcrConversion,const VkAllocationCallbacks * pAllocator)10368 void VkDecoderGlobalState::on_vkDestroySamplerYcbcrConversion(
10369     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
10370     VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator) {
10371     mImpl->on_vkDestroySamplerYcbcrConversion(pool, snapshotInfo, device, ycbcrConversion,
10372                                               pAllocator);
10373 }
10374 
on_vkDestroySamplerYcbcrConversionKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkDevice device,VkSamplerYcbcrConversion ycbcrConversion,const VkAllocationCallbacks * pAllocator)10375 void VkDecoderGlobalState::on_vkDestroySamplerYcbcrConversionKHR(
10376     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkDevice device,
10377     VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator) {
10378     mImpl->on_vkDestroySamplerYcbcrConversion(pool, snapshotInfo, device, ycbcrConversion,
10379                                               pAllocator);
10380 }
10381 
on_vkEnumeratePhysicalDeviceGroups(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkInstance instance,uint32_t * pPhysicalDeviceGroupCount,VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties)10382 VkResult VkDecoderGlobalState::on_vkEnumeratePhysicalDeviceGroups(
10383     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkInstance instance,
10384     uint32_t* pPhysicalDeviceGroupCount,
10385     VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
10386     return mImpl->on_vkEnumeratePhysicalDeviceGroups(
10387         pool, snapshotInfo, instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
10388 }
10389 
on_vkEnumeratePhysicalDeviceGroupsKHR(android::base::BumpPool * pool,VkSnapshotApiCallInfo * snapshotInfo,VkInstance instance,uint32_t * pPhysicalDeviceGroupCount,VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties)10390 VkResult VkDecoderGlobalState::on_vkEnumeratePhysicalDeviceGroupsKHR(
10391     android::base::BumpPool* pool, VkSnapshotApiCallInfo* snapshotInfo, VkInstance instance,
10392     uint32_t* pPhysicalDeviceGroupCount,
10393     VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
10394     return mImpl->on_vkEnumeratePhysicalDeviceGroups(
10395         pool, snapshotInfo, instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
10396 }
10397 
on_DeviceLost()10398 void VkDecoderGlobalState::on_DeviceLost() { mImpl->on_DeviceLost(); }
10399 
on_CheckOutOfMemory(VkResult result,uint32_t opCode,const VkDecoderContext & context,std::optional<uint64_t> allocationSize)10400 void VkDecoderGlobalState::on_CheckOutOfMemory(VkResult result, uint32_t opCode,
10401                                                const VkDecoderContext& context,
10402                                                std::optional<uint64_t> allocationSize) {
10403     mImpl->on_CheckOutOfMemory(result, opCode, context, allocationSize);
10404 }
10405 
waitForFence(VkFence boxed_fence,uint64_t timeout)10406 VkResult VkDecoderGlobalState::waitForFence(VkFence boxed_fence, uint64_t timeout) {
10407     VkFence fence = unbox_VkFence(boxed_fence);
10408     return mImpl->waitForFence(fence, timeout);
10409 }
10410 
registerQsriCallback(VkImage image,VkQsriTimeline::Callback callback)10411 AsyncResult VkDecoderGlobalState::registerQsriCallback(VkImage image,
10412                                                        VkQsriTimeline::Callback callback) {
10413     return mImpl->registerQsriCallback(image, std::move(callback));
10414 }
10415 
deviceMemoryTransform_tohost(VkDeviceMemory * memory,uint32_t memoryCount,VkDeviceSize * offset,uint32_t offsetCount,VkDeviceSize * size,uint32_t sizeCount,uint32_t * typeIndex,uint32_t typeIndexCount,uint32_t * typeBits,uint32_t typeBitsCount)10416 void VkDecoderGlobalState::deviceMemoryTransform_tohost(VkDeviceMemory* memory,
10417                                                         uint32_t memoryCount, VkDeviceSize* offset,
10418                                                         uint32_t offsetCount, VkDeviceSize* size,
10419                                                         uint32_t sizeCount, uint32_t* typeIndex,
10420                                                         uint32_t typeIndexCount, uint32_t* typeBits,
10421                                                         uint32_t typeBitsCount) {
10422     // Not used currently
10423     (void)memory;
10424     (void)memoryCount;
10425     (void)offset;
10426     (void)offsetCount;
10427     (void)size;
10428     (void)sizeCount;
10429     (void)typeIndex;
10430     (void)typeIndexCount;
10431     (void)typeBits;
10432     (void)typeBitsCount;
10433 }
10434 
deviceMemoryTransform_fromhost(VkDeviceMemory * memory,uint32_t memoryCount,VkDeviceSize * offset,uint32_t offsetCount,VkDeviceSize * size,uint32_t sizeCount,uint32_t * typeIndex,uint32_t typeIndexCount,uint32_t * typeBits,uint32_t typeBitsCount)10435 void VkDecoderGlobalState::deviceMemoryTransform_fromhost(
10436     VkDeviceMemory* memory, uint32_t memoryCount, VkDeviceSize* offset, uint32_t offsetCount,
10437     VkDeviceSize* size, uint32_t sizeCount, uint32_t* typeIndex, uint32_t typeIndexCount,
10438     uint32_t* typeBits, uint32_t typeBitsCount) {
10439     // Not used currently
10440     (void)memory;
10441     (void)memoryCount;
10442     (void)offset;
10443     (void)offsetCount;
10444     (void)size;
10445     (void)sizeCount;
10446     (void)typeIndex;
10447     (void)typeIndexCount;
10448     (void)typeBits;
10449     (void)typeBitsCount;
10450 }
10451 
snapshot()10452 VkDecoderSnapshot* VkDecoderGlobalState::snapshot() { return mImpl->snapshot(); }
10453 
10454 #define DEFINE_TRANSFORMED_TYPE_IMPL(type)                                                        \
10455     void VkDecoderGlobalState::transformImpl_##type##_tohost(const type* val, uint32_t count) {   \
10456         mImpl->transformImpl_##type##_tohost(val, count);                                         \
10457     }                                                                                             \
10458     void VkDecoderGlobalState::transformImpl_##type##_fromhost(const type* val, uint32_t count) { \
10459         mImpl->transformImpl_##type##_fromhost(val, count);                                       \
10460     }
10461 
10462 LIST_TRANSFORMED_TYPES(DEFINE_TRANSFORMED_TYPE_IMPL)
10463 
10464 }  // namespace vk
10465 }  // namespace gfxstream
10466