• 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 <unordered_map>
21 #include <vector>
22 
23 #include "DecompressionShaders.h"
24 #include "FrameBuffer.h"
25 #include "compressedTextureFormats/etc.h"
26 #include "VkAndroidNativeBuffer.h"
27 #include "VkCommonOperations.h"
28 #include "VkDecoderSnapshot.h"
29 #include "VkFormatUtils.h"
30 #include "VulkanDispatch.h"
31 #include "VulkanStream.h"
32 #include "base/ArraySize.h"
33 #include "base/Optional.h"
34 #include "base/EntityManager.h"
35 #include "base/HybridEntityManager.h"
36 #include "base/Lookup.h"
37 #include "base/Stream.h"
38 #include "base/ConditionVariable.h"
39 #include "base/Lock.h"
40 #include "base/System.h"
41 #include "base/Tracing.h"
42 #include "common/goldfish_vk_marshaling.h"
43 #include "common/goldfish_vk_reserved_marshaling.h"
44 #include "common/goldfish_vk_deepcopy.h"
45 #include "common/goldfish_vk_dispatch.h"
46 #include "host-common/address_space_device_control_ops.h"
47 #include "host-common/vm_operations.h"
48 #include "host-common/feature_control.h"
49 #include "vk_util.h"
50 
51 #ifndef _WIN32
52 #include <unistd.h>
53 #endif
54 
55 #ifdef __APPLE__
56 #include <CoreFoundation/CoreFoundation.h>
57 #endif
58 
59 #include <climits>
60 
61 using android::base::arraySize;
62 using android::base::AutoLock;
63 using android::base::ConditionVariable;
64 using android::base::Lock;
65 using android::base::Optional;
66 
67 // TODO: Asserts build
68 #define DCHECK(condition)
69 
70 #define VKDGS_DEBUG 0
71 
72 #if VKDGS_DEBUG
73 #define VKDGS_LOG(fmt,...) fprintf(stderr, "%s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__);
74 #else
75 #define VKDGS_LOG(fmt,...)
76 #endif
77 
78 namespace goldfish_vk {
79 
80 // A list of extensions that should not be passed to the host driver.
81 // These will mainly include Vulkan features that we emulate ourselves.
82 static constexpr const char* const
83 kEmulatedExtensions[] = {
84     "VK_ANDROID_external_memory_android_hardware_buffer",
85     "VK_ANDROID_native_buffer",
86     "VK_FUCHSIA_buffer_collection",
87     "VK_FUCHSIA_external_memory",
88     "VK_FUCHSIA_external_semaphore",
89     "VK_EXT_queue_family_foreign",
90     "VK_KHR_external_memory",
91     "VK_KHR_external_memory_capabilities",
92     "VK_KHR_external_semaphore",
93     "VK_KHR_external_semaphore_capabilities",
94     "VK_KHR_external_semaphore_fd",
95     "VK_KHR_external_semaphore_win32",
96     "VK_KHR_external_fence_capabilities",
97     "VK_KHR_external_fence",
98     "VK_KHR_external_fence_fd",
99 };
100 
101 static constexpr uint32_t kMaxSafeVersion = VK_MAKE_VERSION(1, 1, 0);
102 static constexpr uint32_t kMinVersion = VK_MAKE_VERSION(1, 0, 0);
103 
104 #define DEFINE_BOXED_HANDLE_TYPE_TAG(type) \
105     Tag_##type, \
106 
107 enum BoxedHandleTypeTag {
108     Tag_Invalid = 0,
109     GOLDFISH_VK_LIST_HANDLE_TYPES_BY_STAGE(DEFINE_BOXED_HANDLE_TYPE_TAG)
110 };
111 
112 template <class T>
113 class BoxedHandleManager {
114 public:
115 
116     // The hybrid entity manager uses a sequence lock to protect access to
117     // a working set of 16000 handles, allowing us to avoid using a regular
118     // lock for those. Performance is degraded when going over this number,
119     // as it will then fall back to a std::map.
120     //
121     // We use 16000 as the max number of live handles to track; we don't
122     // expect the system to go over 16000 total live handles, outside some
123     // dEQP object management tests.
124     using Store = android::base::HybridEntityManager<16000, uint64_t, T>;
125 
126     Lock lock;
127     mutable Store store;
128     std::unordered_map<uint64_t, uint64_t> reverseMap;
129     struct DelayedRemove {
130         uint64_t handle;
131         std::function<void()> callback;
132     };
133     std::unordered_map<VkDevice, std::vector<DelayedRemove>> delayedRemoves;
134 
clear()135     void clear() {
136         reverseMap.clear();
137         store.clear();
138     }
139 
add(const T & item,BoxedHandleTypeTag tag)140     uint64_t add(const T& item, BoxedHandleTypeTag tag) {
141         auto res = (uint64_t)store.add(item, (size_t)tag);
142         AutoLock l(lock);
143         reverseMap[(uint64_t)(item.underlying)] = res;
144         return res;
145     }
146 
addFixed(uint64_t handle,const T & item,BoxedHandleTypeTag tag)147     uint64_t addFixed(uint64_t handle, const T& item, BoxedHandleTypeTag tag) {
148         auto res = (uint64_t)store.addFixed(handle, item, (size_t)tag);
149         AutoLock l(lock);
150         reverseMap[(uint64_t)(item.underlying)] = res;
151         return res;
152     }
153 
remove(uint64_t h)154     void remove(uint64_t h) {
155         auto item = get(h);
156         if (item) {
157             AutoLock l(lock);
158             reverseMap.erase((uint64_t)(item->underlying));
159         }
160         store.remove(h);
161     }
162 
removeDelayed(uint64_t h,VkDevice device,std::function<void ()> callback)163     void removeDelayed(uint64_t h, VkDevice device, std::function<void()> callback) {
164         AutoLock l(lock);
165         delayedRemoves[device].push_back({ h, callback });
166     }
167 
processDelayedRemovesGlobalStateLocked(VkDevice device)168     void processDelayedRemovesGlobalStateLocked(VkDevice device) {
169         AutoLock l(lock);
170         auto it = delayedRemoves.find(device);
171         if (it == delayedRemoves.end()) return;
172         auto& delayedRemovesList = it->second;
173         for (const auto& r : delayedRemovesList) {
174             auto h = r.handle;
175             // VkDecoderGlobalState is already locked when callback is called.
176             auto funcGlobalStateLocked = r.callback;
177             funcGlobalStateLocked();
178             store.remove(h);
179         }
180         delayedRemovesList.clear();
181         delayedRemoves.erase(it);
182     }
183 
get(uint64_t h)184     T* get(uint64_t h) {
185         return (T*)store.get_const(h);
186     }
187 
getBoxedFromUnboxedLocked(uint64_t unboxed)188     uint64_t getBoxedFromUnboxedLocked(uint64_t unboxed) {
189         auto res = android::base::find(reverseMap, unboxed);
190         if (!res) return 0;
191         return *res;
192     }
193 };
194 
195 struct OrderMaintenanceInfo {
196     uint32_t sequenceNumber = 0;
197     Lock lock;
198     ConditionVariable cv;
199 
200     uint32_t refcount = 1;
201 
incRefgoldfish_vk::OrderMaintenanceInfo202     void incRef() {
203         __atomic_add_fetch(&refcount, 1, __ATOMIC_SEQ_CST);
204     }
205 
decRefgoldfish_vk::OrderMaintenanceInfo206     bool decRef() {
207         return 0 == __atomic_sub_fetch(&refcount, 1, __ATOMIC_SEQ_CST);
208     }
209 };
210 
acquireOrderMaintInfo(OrderMaintenanceInfo * ord)211 static void acquireOrderMaintInfo(OrderMaintenanceInfo* ord) {
212     if (!ord) return;
213     ord->incRef();
214 }
215 
releaseOrderMaintInfo(OrderMaintenanceInfo * ord)216 static void releaseOrderMaintInfo(OrderMaintenanceInfo* ord) {
217     if (!ord) return;
218     if (ord->decRef()) delete ord;
219 }
220 
221 template <class T>
222 class DispatchableHandleInfo {
223     public:
224         T underlying;
225         VulkanDispatch* dispatch = nullptr;
226         bool ownDispatch = false;
227         OrderMaintenanceInfo* ordMaintInfo = nullptr;
228         VulkanMemReadingStream* readStream = nullptr;
229 };
230 
231 static BoxedHandleManager<DispatchableHandleInfo<uint64_t>> sBoxedHandleManager;
232 
233 struct ReadStreamRegistry {
234      Lock mLock;
235 
236      std::vector<VulkanMemReadingStream*> freeStreams;
237 
ReadStreamRegistrygoldfish_vk::ReadStreamRegistry238      ReadStreamRegistry() { freeStreams.reserve(100); };
239 
popgoldfish_vk::ReadStreamRegistry240      VulkanMemReadingStream* pop() {
241          AutoLock lock(mLock);
242          if (freeStreams.empty()) {
243              return new VulkanMemReadingStream(0);
244          } else {
245             VulkanMemReadingStream* res = freeStreams.back();
246             freeStreams.pop_back();
247             return res;
248          }
249      }
250 
pushgoldfish_vk::ReadStreamRegistry251      void push(VulkanMemReadingStream* stream) {
252          AutoLock lock(mLock);
253          freeStreams.push_back(stream);
254      }
255 };
256 
257 static ReadStreamRegistry sReadStreamRegistry;
258 
259 class VkDecoderGlobalState::Impl {
260 public:
Impl()261     Impl() :
262         m_vk(emugl::vkDispatch()),
263         m_emu(getGlobalVkEmulation()) {
264         mSnapshotsEnabled =
265             feature_is_enabled(kFeature_VulkanSnapshots);
266         mVkCleanupEnabled = android::base::getEnvironmentVariable("ANDROID_EMU_VK_NO_CLEANUP") != "1";
267         mLogging = android::base::getEnvironmentVariable("ANDROID_EMU_VK_LOG_CALLS") == "1";
268         mVerbosePrints = android::base::getEnvironmentVariable("ANDROID_EMUGL_VERBOSE") == "1";
269         if (get_emugl_address_space_device_control_ops().control_get_hw_funcs &&
270             get_emugl_address_space_device_control_ops().control_get_hw_funcs()) {
271             mUseOldMemoryCleanupPath = 0 == get_emugl_address_space_device_control_ops().control_get_hw_funcs()->getPhysAddrStartLocked();
272         }
273         mGuestUsesAngle =
274             feature_is_enabled(kFeature_GuestUsesAngle);
275     }
276 
277     ~Impl() = default;
278 
279     // Resets all internal tracking info.
280     // Assumes that the heavyweight cleanup operations
281     // have already happened.
clear()282     void clear() {
283         mInstanceInfo.clear();
284         mPhysdevInfo.clear();
285         mDeviceInfo.clear();
286         mImageInfo.clear();
287         mImageViewInfo.clear();
288         mSamplerInfo.clear();
289         mCmdBufferInfo.clear();
290         mCmdPoolInfo.clear();
291 
292         mDeviceToPhysicalDevice.clear();
293         mPhysicalDeviceToInstance.clear();
294         mQueueInfo.clear();
295         mBufferInfo.clear();
296         mMapInfo.clear();
297         mSemaphoreInfo.clear();
298         mFenceInfo.clear();
299 #ifdef _WIN32
300         mSemaphoreId = 1;
301         mExternalSemaphoresById.clear();
302 #endif
303         mDescriptorUpdateTemplateInfo.clear();
304 
305         mCreatedHandlesForSnapshotLoad.clear();
306         mCreatedHandlesForSnapshotLoadIndex = 0;
307 
308         sBoxedHandleManager.clear();
309     }
310 
snapshotsEnabled() const311     bool snapshotsEnabled() const {
312         return mSnapshotsEnabled;
313     }
314 
vkCleanupEnabled() const315     bool vkCleanupEnabled() const {
316         return mVkCleanupEnabled;
317     }
318 
save(android::base::Stream * stream)319     void save(android::base::Stream* stream) {
320         snapshot()->save(stream);
321     }
322 
load(android::base::Stream * stream)323     void load(android::base::Stream* stream) {
324         // assume that we already destroyed all instances
325         // from FrameBuffer's onLoad method.
326 
327         // destroy all current internal data structures
328         clear();
329 
330         // this part will replay in the decoder
331         snapshot()->load(stream);
332     }
333 
lock()334     void lock() {
335         mLock.lock();
336     }
337 
unlock()338     void unlock() {
339         mLock.unlock();
340     }
341 
setCreatedHandlesForSnapshotLoad(const unsigned char * buffer)342     size_t setCreatedHandlesForSnapshotLoad(const unsigned char* buffer) {
343         size_t consumed = 0;
344 
345         if (!buffer) return consumed;
346 
347         uint32_t bufferSize = *(uint32_t*)buffer;
348 
349         consumed += 4;
350 
351         uint32_t handleCount = bufferSize / 8;
352         VKDGS_LOG("incoming handle count: %u", handleCount);
353 
354         uint64_t* handles = (uint64_t*)(buffer + 4);
355 
356         mCreatedHandlesForSnapshotLoad.clear();
357         mCreatedHandlesForSnapshotLoadIndex = 0;
358 
359         for (uint32_t i = 0; i < handleCount; ++i) {
360             VKDGS_LOG("handle to load: 0x%llx", (unsigned long long)(uintptr_t)handles[i]);
361             mCreatedHandlesForSnapshotLoad.push_back(handles[i]);
362             consumed += 8;
363         }
364 
365         return consumed;
366     }
367 
clearCreatedHandlesForSnapshotLoad()368     void clearCreatedHandlesForSnapshotLoad() {
369         mCreatedHandlesForSnapshotLoad.clear();
370         mCreatedHandlesForSnapshotLoadIndex = 0;
371     }
372 
on_vkEnumerateInstanceVersion(android::base::BumpPool * pool,uint32_t * pApiVersion)373     VkResult on_vkEnumerateInstanceVersion(
374             android::base::BumpPool* pool,
375             uint32_t* pApiVersion) {
376         if (m_vk->vkEnumerateInstanceVersion) {
377             VkResult res = m_vk->vkEnumerateInstanceVersion(pApiVersion);
378 
379             if (*pApiVersion > kMaxSafeVersion) {
380                 *pApiVersion = kMaxSafeVersion;
381             }
382 
383             return res;
384         }
385         *pApiVersion = kMinVersion;
386         return VK_SUCCESS;
387     }
388 
on_vkCreateInstance(android::base::BumpPool * pool,const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)389     VkResult on_vkCreateInstance(
390             android::base::BumpPool* pool,
391             const VkInstanceCreateInfo* pCreateInfo,
392             const VkAllocationCallbacks* pAllocator,
393             VkInstance* pInstance) {
394 
395         std::vector<const char*> finalExts =
396             filteredExtensionNames(
397                     pCreateInfo->enabledExtensionCount,
398                     pCreateInfo->ppEnabledExtensionNames);
399 
400         // Create higher version instance whenever it is possible.
401         uint32_t apiVersion = VK_MAKE_VERSION(1, 0, 0);
402         if (pCreateInfo->pApplicationInfo) {
403             apiVersion = pCreateInfo->pApplicationInfo->apiVersion;
404         }
405         if (m_vk->vkEnumerateInstanceVersion) {
406             uint32_t instanceVersion;
407             VkResult result =
408                 m_vk->vkEnumerateInstanceVersion(&instanceVersion);
409             if (result == VK_SUCCESS &&
410                 instanceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
411                 apiVersion = instanceVersion;
412             }
413         }
414 
415         VkInstanceCreateInfo createInfoFiltered = *pCreateInfo;
416         VkApplicationInfo applicationInfo = {};
417         createInfoFiltered.enabledExtensionCount = (uint32_t)finalExts.size();
418         createInfoFiltered.ppEnabledExtensionNames = finalExts.data();
419         if (createInfoFiltered.pApplicationInfo) {
420             applicationInfo = *createInfoFiltered.pApplicationInfo;
421             createInfoFiltered.pApplicationInfo = &applicationInfo;
422         }
423         applicationInfo.apiVersion = apiVersion;
424 
425         // bug: 155795731 (see below)
426         AutoLock lock(mLock);
427 
428         VkResult res = m_vk->vkCreateInstance(&createInfoFiltered, pAllocator, pInstance);
429 
430         if (res != VK_SUCCESS) return res;
431 
432         // bug: 155795731 we should protect vkCreateInstance in the driver too
433         // because, at least w/ tcmalloc, there is a flaky crash on loading its
434         // procs
435         //
436         // AutoLock lock(mLock);
437 
438         // TODO: bug 129484301
439         get_emugl_vm_operations().setSkipSnapshotSave(
440                 !feature_is_enabled(kFeature_VulkanSnapshots));
441 
442         InstanceInfo info;
443         info.apiVersion = apiVersion;
444         for (uint32_t i = 0; i < createInfoFiltered.enabledExtensionCount;
445                 ++i) {
446             info.enabledExtensionNames.push_back(
447                     createInfoFiltered.ppEnabledExtensionNames[i]);
448         }
449 
450         // Box it up
451         VkInstance boxed = new_boxed_VkInstance(*pInstance, nullptr, true /* own dispatch */);
452         init_vulkan_dispatch_from_instance(
453                 m_vk, *pInstance,
454                 dispatch_VkInstance(boxed));
455         info.boxed = boxed;
456 
457         if (m_emu->instanceSupportsMoltenVK) {
458             if (!m_vk->vkSetMTLTextureMVK) {
459                 fprintf(stderr, "Cannot find vkSetMTLTextureMVK\n");
460                 abort();
461             }
462         }
463 
464         mInstanceInfo[*pInstance] = info;
465 
466         *pInstance = (VkInstance)info.boxed;
467 
468         auto fb = FrameBuffer::getFB();
469         if (!fb) return res;
470 
471         if (vkCleanupEnabled()) {
472           fb->registerProcessCleanupCallback(
473               unbox_VkInstance(boxed),
474               [this, boxed] {
475 
476                 vkDestroyInstanceImpl(
477                     unbox_VkInstance(boxed),
478                     nullptr);
479               });
480         }
481 
482         return res;
483     }
484 
vkDestroyInstanceImpl(VkInstance instance,const VkAllocationCallbacks * pAllocator)485     void vkDestroyInstanceImpl(VkInstance instance, const VkAllocationCallbacks* pAllocator) {
486 
487         // Do delayed removes out of the lock, but get the list of devices to destroy inside the lock.
488         {
489             AutoLock lock(mLock);
490             std::vector<VkDevice> devicesToDestroy;
491 
492             for (auto it : mDeviceToPhysicalDevice) {
493                 auto otherInstance = android::base::find(mPhysicalDeviceToInstance, it.second);
494                 if (!otherInstance) continue;
495                 if (instance == *otherInstance) {
496                     devicesToDestroy.push_back(it.first);
497                 }
498             }
499 
500             for (auto device: devicesToDestroy) {
501                 sBoxedHandleManager.processDelayedRemovesGlobalStateLocked(
502                         device);
503             }
504         }
505 
506 
507         AutoLock lock(mLock);
508 
509         teardownInstanceLocked(instance);
510 
511         m_vk->vkDestroyInstance(instance, pAllocator);
512 
513         auto it = mPhysicalDeviceToInstance.begin();
514 
515         while (it != mPhysicalDeviceToInstance.end()) {
516             if (it->second == instance) {
517                 it = mPhysicalDeviceToInstance.erase(it);
518             } else {
519                 ++it;
520             }
521         }
522 
523         auto instInfo = android::base::find(mInstanceInfo, instance);
524         delete_VkInstance(instInfo->boxed);
525         mInstanceInfo.erase(instance);
526     }
527 
on_vkDestroyInstance(android::base::BumpPool * pool,VkInstance boxed_instance,const VkAllocationCallbacks * pAllocator)528     void on_vkDestroyInstance(
529             android::base::BumpPool* pool,
530             VkInstance boxed_instance,
531             const VkAllocationCallbacks* pAllocator) {
532 
533         auto instance = unbox_VkInstance(boxed_instance);
534 
535         vkDestroyInstanceImpl(instance, pAllocator);
536 
537         auto fb = FrameBuffer::getFB();
538         if (!fb) return;
539 
540         fb->unregisterProcessCleanupCallback(instance);
541     }
542 
on_vkEnumeratePhysicalDevices(android::base::BumpPool * pool,VkInstance boxed_instance,uint32_t * physicalDeviceCount,VkPhysicalDevice * physicalDevices)543     VkResult on_vkEnumeratePhysicalDevices(
544             android::base::BumpPool* pool,
545             VkInstance boxed_instance,
546             uint32_t* physicalDeviceCount,
547             VkPhysicalDevice* physicalDevices) {
548 
549         auto instance = unbox_VkInstance(boxed_instance);
550         auto vk = dispatch_VkInstance(boxed_instance);
551 
552         auto res = vk->vkEnumeratePhysicalDevices(instance, physicalDeviceCount, physicalDevices);
553 
554         if (res != VK_SUCCESS) return res;
555 
556         AutoLock lock(mLock);
557 
558         if (physicalDeviceCount && physicalDevices) {
559             // Box them up
560             for (uint32_t i = 0; i < *physicalDeviceCount; ++i) {
561                 mPhysicalDeviceToInstance[physicalDevices[i]] = instance;
562 
563                 auto& physdevInfo = mPhysdevInfo[physicalDevices[i]];
564 
565 
566                 physdevInfo.boxed =
567                     new_boxed_VkPhysicalDevice(physicalDevices[i], vk, false /* does not own dispatch */);
568 
569                 vk->vkGetPhysicalDeviceProperties(physicalDevices[i],
570                         &physdevInfo.props);
571 
572                 if (physdevInfo.props.apiVersion > kMaxSafeVersion) {
573                     physdevInfo.props.apiVersion = kMaxSafeVersion;
574                 }
575 
576                 vk->vkGetPhysicalDeviceMemoryProperties(
577                         physicalDevices[i], &physdevInfo.memoryProperties);
578 
579                 uint32_t queueFamilyPropCount = 0;
580 
581                 vk->vkGetPhysicalDeviceQueueFamilyProperties(
582                         physicalDevices[i], &queueFamilyPropCount, nullptr);
583 
584                 physdevInfo.queueFamilyProperties.resize(
585                         (size_t)queueFamilyPropCount);
586 
587                 vk->vkGetPhysicalDeviceQueueFamilyProperties(
588                         physicalDevices[i], &queueFamilyPropCount,
589                         physdevInfo.queueFamilyProperties.data());
590 
591                 physicalDevices[i] = (VkPhysicalDevice)physdevInfo.boxed;
592             }
593         }
594 
595         return res;
596     }
597 
on_vkGetPhysicalDeviceFeatures(android::base::BumpPool * pool,VkPhysicalDevice boxed_physicalDevice,VkPhysicalDeviceFeatures * pFeatures)598     void on_vkGetPhysicalDeviceFeatures(
599             android::base::BumpPool* pool,
600             VkPhysicalDevice boxed_physicalDevice,
601             VkPhysicalDeviceFeatures* pFeatures) {
602 
603         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
604         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
605 
606         vk->vkGetPhysicalDeviceFeatures(physicalDevice, pFeatures);
607         pFeatures->textureCompressionETC2 = true;
608         pFeatures->textureCompressionASTC_LDR |= kEmulateAstc;
609     }
610 
on_vkGetPhysicalDeviceFeatures2(android::base::BumpPool * pool,VkPhysicalDevice boxed_physicalDevice,VkPhysicalDeviceFeatures2 * pFeatures)611     void on_vkGetPhysicalDeviceFeatures2(
612             android::base::BumpPool* pool,
613             VkPhysicalDevice boxed_physicalDevice,
614             VkPhysicalDeviceFeatures2* pFeatures) {
615 
616         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
617         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
618 
619         AutoLock lock(mLock);
620 
621         auto physdevInfo =
622             android::base::find(mPhysdevInfo, physicalDevice);
623         if (!physdevInfo) return;
624 
625         auto instance = mPhysicalDeviceToInstance[physicalDevice];
626         auto instanceInfo = android::base::find(mInstanceInfo, instance);
627         if (!instanceInfo) return;
628 
629         if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
630             physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
631             vk->vkGetPhysicalDeviceFeatures2(physicalDevice, pFeatures);
632         } else if (hasInstanceExtension(instance, "VK_KHR_get_physical_device_properties2")) {
633             vk->vkGetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures);
634         } else {
635             // No instance extension, fake it!!!!
636             if (pFeatures->pNext) {
637                 fprintf(stderr,
638                         "%s: Warning: Trying to use extension struct in "
639                         "VkPhysicalDeviceFeatures2 without having enabled "
640                         "the extension!!!!11111\n",
641                         __func__);
642             }
643             *pFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, 0, };
644             vk->vkGetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
645         }
646 
647         pFeatures->features.textureCompressionETC2 = true;
648         pFeatures->features.textureCompressionASTC_LDR |= kEmulateAstc;
649     }
650 
on_vkGetPhysicalDeviceImageFormatProperties(android::base::BumpPool * pool,VkPhysicalDevice boxed_physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags,VkImageFormatProperties * pImageFormatProperties)651     VkResult on_vkGetPhysicalDeviceImageFormatProperties(
652             android::base::BumpPool* pool,
653             VkPhysicalDevice boxed_physicalDevice,
654             VkFormat format,
655             VkImageType type,
656             VkImageTiling tiling,
657             VkImageUsageFlags usage,
658             VkImageCreateFlags flags,
659             VkImageFormatProperties* pImageFormatProperties) {
660 
661         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
662         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
663         bool emulatedEtc2 = needEmulatedEtc2(physicalDevice, vk);
664         bool emulatedAstc = needEmulatedAstc(physicalDevice, vk);
665         if (emulatedEtc2 || emulatedAstc) {
666             CompressedImageInfo cmpInfo = createCompressedImageInfo(format);
667             if (cmpInfo.isCompressed && ((emulatedEtc2 && cmpInfo.isEtc2) ||
668                                          (emulatedAstc && cmpInfo.isAstc))) {
669                 if (!supportEmulatedCompressedImageFormatProperty(
670                     format, type, tiling, usage, flags)) {
671                     memset(pImageFormatProperties, 0, sizeof(VkImageFormatProperties));
672                     return VK_ERROR_FORMAT_NOT_SUPPORTED;
673                 }
674                 flags &= ~VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR;
675                 flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
676                 usage |= VK_IMAGE_USAGE_STORAGE_BIT;
677                 format = cmpInfo.sizeCompFormat;
678             }
679         }
680         return vk->vkGetPhysicalDeviceImageFormatProperties(
681                 physicalDevice, format, type, tiling, usage, flags,
682                 pImageFormatProperties);
683     }
684 
on_vkGetPhysicalDeviceImageFormatProperties2(android::base::BumpPool * pool,VkPhysicalDevice boxed_physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,VkImageFormatProperties2 * pImageFormatProperties)685     VkResult on_vkGetPhysicalDeviceImageFormatProperties2(
686             android::base::BumpPool* pool,
687             VkPhysicalDevice boxed_physicalDevice,
688             const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
689             VkImageFormatProperties2* pImageFormatProperties) {
690 
691         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
692         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
693         VkPhysicalDeviceImageFormatInfo2 imageFormatInfo;
694         bool emulatedEtc2 = needEmulatedEtc2(physicalDevice, vk);
695         bool emulatedAstc = needEmulatedAstc(physicalDevice, vk);
696         if (emulatedEtc2 || emulatedAstc) {
697             CompressedImageInfo cmpInfo =
698                 createCompressedImageInfo(pImageFormatInfo->format);
699             if (cmpInfo.isCompressed && ((emulatedEtc2 && cmpInfo.isEtc2) ||
700                                          (emulatedAstc && cmpInfo.isAstc))) {
701                 if (!supportEmulatedCompressedImageFormatProperty(
702                     pImageFormatInfo->format, pImageFormatInfo->type, pImageFormatInfo->tiling,
703                     pImageFormatInfo->usage, pImageFormatInfo->flags)) {
704                     memset(&pImageFormatProperties->imageFormatProperties, 0,
705                         sizeof(VkImageFormatProperties));
706                     return VK_ERROR_FORMAT_NOT_SUPPORTED;
707                 }
708                 imageFormatInfo = *pImageFormatInfo;
709                 pImageFormatInfo = &imageFormatInfo;
710                 imageFormatInfo.flags &= ~VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR;
711                 imageFormatInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
712                 imageFormatInfo.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
713                 imageFormatInfo.format = cmpInfo.sizeCompFormat;
714             }
715         }
716         AutoLock lock(mLock);
717 
718         auto physdevInfo = android::base::find(mPhysdevInfo, physicalDevice);
719         if (!physdevInfo) {
720             return VK_ERROR_OUT_OF_HOST_MEMORY;
721         }
722 
723         VkResult res = VK_ERROR_INITIALIZATION_FAILED;
724 
725         auto instance = mPhysicalDeviceToInstance[physicalDevice];
726         auto instanceInfo = android::base::find(mInstanceInfo, instance);
727         if (!instanceInfo) {
728             return res;
729         }
730 
731         if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
732             physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
733             res = vk->vkGetPhysicalDeviceImageFormatProperties2(
734                 physicalDevice, pImageFormatInfo, pImageFormatProperties);
735         } else if (hasInstanceExtension(
736                     instance,
737                     "VK_KHR_get_physical_device_properties2")) {
738             res = vk->vkGetPhysicalDeviceImageFormatProperties2KHR(
739                 physicalDevice, pImageFormatInfo, pImageFormatProperties);
740         } else {
741             // No instance extension, fake it!!!!
742             if (pImageFormatProperties->pNext) {
743                 fprintf(stderr,
744                         "%s: Warning: Trying to use extension struct in "
745                         "VkPhysicalDeviceFeatures2 without having enabled "
746                         "the extension!!!!11111\n",
747                         __func__);
748             }
749             *pImageFormatProperties = {
750                 VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
751                 0,
752             };
753             res = vk->vkGetPhysicalDeviceImageFormatProperties(
754                 physicalDevice, pImageFormatInfo->format,
755                 pImageFormatInfo->type, pImageFormatInfo->tiling,
756                 pImageFormatInfo->usage, pImageFormatInfo->flags,
757                 &pImageFormatProperties->imageFormatProperties);
758         }
759 
760         const VkPhysicalDeviceExternalImageFormatInfo* extImageFormatInfo =
761             vk_find_struct<VkPhysicalDeviceExternalImageFormatInfo>(pImageFormatInfo);
762         VkExternalImageFormatProperties* extImageFormatProps =
763             vk_find_struct<VkExternalImageFormatProperties>(pImageFormatProperties);
764 
765         // Only allow dedicated allocations for external images.
766         if (extImageFormatInfo && extImageFormatProps) {
767             extImageFormatProps->externalMemoryProperties.externalMemoryFeatures |=
768                 VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
769         }
770 
771         return res;
772     }
773 
on_vkGetPhysicalDeviceFormatProperties(android::base::BumpPool * pool,VkPhysicalDevice boxed_physicalDevice,VkFormat format,VkFormatProperties * pFormatProperties)774     void on_vkGetPhysicalDeviceFormatProperties(
775             android::base::BumpPool* pool,
776             VkPhysicalDevice boxed_physicalDevice,
777             VkFormat format,
778             VkFormatProperties* pFormatProperties) {
779 
780         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
781         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
782         getPhysicalDeviceFormatPropertiesCore<VkFormatProperties>(
783                 [vk](VkPhysicalDevice physicalDevice, VkFormat format,
784                     VkFormatProperties* pFormatProperties) {
785                 vk->vkGetPhysicalDeviceFormatProperties(
786                         physicalDevice, format, pFormatProperties);
787                 },
788                 vk, physicalDevice, format, pFormatProperties);
789     }
790 
on_vkGetPhysicalDeviceFormatProperties2(android::base::BumpPool * pool,VkPhysicalDevice boxed_physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)791     void on_vkGetPhysicalDeviceFormatProperties2(
792             android::base::BumpPool* pool,
793             VkPhysicalDevice boxed_physicalDevice,
794             VkFormat format,
795             VkFormatProperties2* pFormatProperties) {
796 
797         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
798         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
799 
800         AutoLock lock(mLock);
801 
802         auto physdevInfo = android::base::find(mPhysdevInfo, physicalDevice);
803         if (!physdevInfo)
804             return;
805 
806         auto instance = mPhysicalDeviceToInstance[physicalDevice];
807         auto instanceInfo = android::base::find(mInstanceInfo, instance);
808         if (!instanceInfo) return;
809 
810         if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
811             physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
812             getPhysicalDeviceFormatPropertiesCore<VkFormatProperties2>(
813                     [vk](VkPhysicalDevice physicalDevice, VkFormat format,
814                         VkFormatProperties2* pFormatProperties) {
815                     vk->vkGetPhysicalDeviceFormatProperties2(
816                             physicalDevice, format, pFormatProperties);
817                     },
818                     vk, physicalDevice, format, pFormatProperties);
819         } else if (hasInstanceExtension(
820                     instance,
821                     "VK_KHR_get_physical_device_properties2")) {
822             getPhysicalDeviceFormatPropertiesCore<VkFormatProperties2>(
823                     [vk](VkPhysicalDevice physicalDevice, VkFormat format,
824                         VkFormatProperties2* pFormatProperties) {
825                     vk->vkGetPhysicalDeviceFormatProperties2KHR(
826                             physicalDevice, format, pFormatProperties);
827                     },
828                     vk, physicalDevice, format, pFormatProperties);
829         } else {
830             // No instance extension, fake it!!!!
831             if (pFormatProperties->pNext) {
832                 fprintf(stderr,
833                         "%s: Warning: Trying to use extension struct in "
834                         "vkGetPhysicalDeviceFormatProperties2 without having "
835                         "enabled the extension!!!!11111\n",
836                         __func__);
837             }
838             pFormatProperties->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
839             getPhysicalDeviceFormatPropertiesCore<VkFormatProperties>(
840                     [vk](VkPhysicalDevice physicalDevice, VkFormat format,
841                         VkFormatProperties* pFormatProperties) {
842                     vk->vkGetPhysicalDeviceFormatProperties(
843                             physicalDevice, format, pFormatProperties);
844                     },
845                     vk, physicalDevice, format,
846                     &pFormatProperties->formatProperties);
847         }
848     }
849 
on_vkGetPhysicalDeviceProperties(android::base::BumpPool * pool,VkPhysicalDevice boxed_physicalDevice,VkPhysicalDeviceProperties * pProperties)850     void on_vkGetPhysicalDeviceProperties(
851             android::base::BumpPool* pool,
852             VkPhysicalDevice boxed_physicalDevice,
853             VkPhysicalDeviceProperties* pProperties) {
854 
855         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
856         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
857 
858         vk->vkGetPhysicalDeviceProperties(
859                 physicalDevice, pProperties);
860 
861         if (pProperties->apiVersion > kMaxSafeVersion) {
862             pProperties->apiVersion = kMaxSafeVersion;
863         }
864     }
865 
on_vkGetPhysicalDeviceProperties2(android::base::BumpPool * pool,VkPhysicalDevice boxed_physicalDevice,VkPhysicalDeviceProperties2 * pProperties)866     void on_vkGetPhysicalDeviceProperties2(
867             android::base::BumpPool* pool,
868             VkPhysicalDevice boxed_physicalDevice,
869             VkPhysicalDeviceProperties2* pProperties) {
870 
871         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
872         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
873 
874         AutoLock lock(mLock);
875 
876         auto physdevInfo =
877             android::base::find(mPhysdevInfo, physicalDevice);
878         if (!physdevInfo) return;
879 
880         auto instance = mPhysicalDeviceToInstance[physicalDevice];
881         auto instanceInfo = android::base::find(mInstanceInfo, instance);
882         if (!instanceInfo) return;
883 
884         if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
885             physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
886             vk->vkGetPhysicalDeviceProperties2(physicalDevice, pProperties);
887         } else if (hasInstanceExtension(instance, "VK_KHR_get_physical_device_properties2")) {
888             vk->vkGetPhysicalDeviceProperties2KHR(physicalDevice, pProperties);
889         } else {
890             // No instance extension, fake it!!!!
891             if (pProperties->pNext) {
892                 fprintf(stderr,
893                         "%s: Warning: Trying to use extension struct in "
894                         "VkPhysicalDeviceProperties2 without having enabled "
895                         "the extension!!!!11111\n",
896                         __func__);
897             }
898             *pProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, 0, };
899             vk->vkGetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
900         }
901 
902         if (pProperties->properties.apiVersion > kMaxSafeVersion) {
903             pProperties->properties.apiVersion = kMaxSafeVersion;
904         }
905     }
906 
on_vkGetPhysicalDeviceMemoryProperties(android::base::BumpPool * pool,VkPhysicalDevice boxed_physicalDevice,VkPhysicalDeviceMemoryProperties * pMemoryProperties)907     void on_vkGetPhysicalDeviceMemoryProperties(
908             android::base::BumpPool* pool,
909             VkPhysicalDevice boxed_physicalDevice,
910             VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
911 
912         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
913         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
914 
915         vk->vkGetPhysicalDeviceMemoryProperties(
916                 physicalDevice, pMemoryProperties);
917 
918         // Pick a max heap size that will work around
919         // drivers that give bad suggestions (such as 0xFFFFFFFFFFFFFFFF for the heap size)
920         // plus won't break the bank on 32-bit userspace.
921         static constexpr VkDeviceSize kMaxSafeHeapSize =
922             2ULL * 1024ULL * 1024ULL * 1024ULL;
923 
924         for (uint32_t i = 0; i < pMemoryProperties->memoryTypeCount; ++i) {
925             uint32_t heapIndex = pMemoryProperties->memoryTypes[i].heapIndex;
926             auto& heap = pMemoryProperties->memoryHeaps[heapIndex];
927 
928             if (heap.size > kMaxSafeHeapSize) {
929                 heap.size = kMaxSafeHeapSize;
930             }
931 
932             if (!feature_is_enabled(kFeature_GLDirectMem) &&
933                 !feature_is_enabled(kFeature_VirtioGpuNext)) {
934                 pMemoryProperties->memoryTypes[i].propertyFlags =
935                     pMemoryProperties->memoryTypes[i].propertyFlags &
936                     ~(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
937             }
938         }
939     }
940 
on_vkGetPhysicalDeviceMemoryProperties2(android::base::BumpPool * pool,VkPhysicalDevice boxed_physicalDevice,VkPhysicalDeviceMemoryProperties2 * pMemoryProperties)941     void on_vkGetPhysicalDeviceMemoryProperties2(
942             android::base::BumpPool* pool,
943             VkPhysicalDevice boxed_physicalDevice,
944             VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
945 
946         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
947         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
948 
949         auto physdevInfo =
950             android::base::find(mPhysdevInfo, physicalDevice);
951         if (!physdevInfo) return;
952 
953         auto instance = mPhysicalDeviceToInstance[physicalDevice];
954         auto instanceInfo = android::base::find(mInstanceInfo, instance);
955         if (!instanceInfo) return;
956 
957         if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
958             physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
959             vk->vkGetPhysicalDeviceMemoryProperties2(physicalDevice, pMemoryProperties);
960         } else if (hasInstanceExtension(instance, "VK_KHR_get_physical_device_properties2")) {
961             vk->vkGetPhysicalDeviceMemoryProperties2KHR(physicalDevice, pMemoryProperties);
962         } else {
963             // No instance extension, fake it!!!!
964             if (pMemoryProperties->pNext) {
965                 fprintf(stderr,
966                         "%s: Warning: Trying to use extension struct in "
967                         "VkPhysicalDeviceMemoryProperties2 without having enabled "
968                         "the extension!!!!11111\n",
969                         __func__);
970             }
971             *pMemoryProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2, 0, };
972             vk->vkGetPhysicalDeviceMemoryProperties(physicalDevice, &pMemoryProperties->memoryProperties);
973         }
974 
975         // Pick a max heap size that will work around
976         // drivers that give bad suggestions (such as 0xFFFFFFFFFFFFFFFF for the heap size)
977         // plus won't break the bank on 32-bit userspace.
978         static constexpr VkDeviceSize kMaxSafeHeapSize =
979             2ULL * 1024ULL * 1024ULL * 1024ULL;
980 
981         for (uint32_t i = 0; i < pMemoryProperties->memoryProperties.memoryTypeCount; ++i) {
982             uint32_t heapIndex = pMemoryProperties->memoryProperties.memoryTypes[i].heapIndex;
983             auto& heap = pMemoryProperties->memoryProperties.memoryHeaps[heapIndex];
984 
985             if (heap.size > kMaxSafeHeapSize) {
986                 heap.size = kMaxSafeHeapSize;
987             }
988 
989             if (!feature_is_enabled(kFeature_GLDirectMem) &&
990                 !feature_is_enabled(kFeature_VirtioGpuNext)) {
991                 pMemoryProperties->memoryProperties.memoryTypes[i].propertyFlags =
992                     pMemoryProperties->memoryProperties.memoryTypes[i].propertyFlags &
993                     ~(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
994             }
995         }
996     }
997 
on_vkEnumerateDeviceExtensionProperties(android::base::BumpPool * pool,VkPhysicalDevice boxed_physicalDevice,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)998     VkResult on_vkEnumerateDeviceExtensionProperties(
999         android::base::BumpPool* pool,
1000         VkPhysicalDevice boxed_physicalDevice,
1001         const char* pLayerName,
1002         uint32_t* pPropertyCount,
1003         VkExtensionProperties* pProperties) {
1004 
1005         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1006         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1007 
1008         if (!m_emu->instanceSupportsMoltenVK) {
1009             return vk->vkEnumerateDeviceExtensionProperties(
1010                 physicalDevice, pLayerName, pPropertyCount, pProperties);
1011         }
1012 
1013         // If MoltenVK is supported on host, we need to ensure that we include
1014         // VK_MVK_moltenvk extenstion in returned properties.
1015         std::vector<VkExtensionProperties> properties;
1016         uint32_t propertyCount = 0u;
1017         VkResult result = vk->vkEnumerateDeviceExtensionProperties(
1018             physicalDevice, pLayerName, &propertyCount, nullptr);
1019         if (result != VK_SUCCESS) {
1020             return result;
1021         }
1022 
1023         properties.resize(propertyCount);
1024         result = vk->vkEnumerateDeviceExtensionProperties(
1025             physicalDevice, pLayerName, &propertyCount, properties.data());
1026         if (result != VK_SUCCESS) {
1027             return result;
1028         }
1029 
1030         if (std::find_if(properties.begin(), properties.end(),
1031             [](const VkExtensionProperties& props) {
1032                 return strcmp(props.extensionName, VK_MVK_MOLTENVK_EXTENSION_NAME) == 0;
1033             }) == properties.end()) {
1034             VkExtensionProperties mvk_props;
1035             strncpy(mvk_props.extensionName, VK_MVK_MOLTENVK_EXTENSION_NAME,
1036                     sizeof(mvk_props.extensionName));
1037             mvk_props.specVersion = VK_MVK_MOLTENVK_SPEC_VERSION;
1038             properties.push_back(mvk_props);
1039         }
1040 
1041         if (*pPropertyCount == 0) {
1042             *pPropertyCount = properties.size();
1043         } else {
1044             memcpy(pProperties, properties.data(), *pPropertyCount * sizeof(VkExtensionProperties));
1045         }
1046 
1047         return VK_SUCCESS;
1048     }
1049 
on_vkCreateDevice(android::base::BumpPool * pool,VkPhysicalDevice boxed_physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)1050     VkResult on_vkCreateDevice(
1051             android::base::BumpPool* pool,
1052             VkPhysicalDevice boxed_physicalDevice,
1053             const VkDeviceCreateInfo* pCreateInfo,
1054             const VkAllocationCallbacks* pAllocator,
1055             VkDevice* pDevice) {
1056 
1057         if (mLogging) {
1058             fprintf(stderr, "%s: begin\n", __func__);
1059         }
1060 
1061         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
1062         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
1063 
1064         std::vector<const char*> finalExts =
1065             filteredExtensionNames(
1066                     pCreateInfo->enabledExtensionCount,
1067                     pCreateInfo->ppEnabledExtensionNames);
1068 
1069         // Run the underlying API call, filtering extensions.
1070         VkDeviceCreateInfo createInfoFiltered = *pCreateInfo;
1071         bool emulateTextureEtc2 = false;
1072         bool emulateTextureAstc = false;
1073         VkPhysicalDeviceFeatures featuresFiltered;
1074 
1075         if (pCreateInfo->pEnabledFeatures) {
1076             featuresFiltered = *pCreateInfo->pEnabledFeatures;
1077             if (featuresFiltered.textureCompressionETC2) {
1078                 if (needEmulatedEtc2(physicalDevice, vk)) {
1079                     emulateTextureEtc2 = true;
1080                     featuresFiltered.textureCompressionETC2 = false;
1081                 }
1082             }
1083             if (featuresFiltered.textureCompressionASTC_LDR) {
1084                 if (needEmulatedAstc(physicalDevice, vk)) {
1085                     emulateTextureAstc = true;
1086                     featuresFiltered.textureCompressionASTC_LDR = false;
1087                 }
1088             }
1089             createInfoFiltered.pEnabledFeatures = &featuresFiltered;
1090         }
1091 
1092         vk_foreach_struct(ext, pCreateInfo->pNext) {
1093             switch (ext->sType) {
1094                 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2:
1095                     if (needEmulatedEtc2(physicalDevice, vk)) {
1096                         emulateTextureEtc2 = true;
1097                         VkPhysicalDeviceFeatures2* features2 =
1098                             (VkPhysicalDeviceFeatures2*)ext;
1099                         features2->features.textureCompressionETC2 = false;
1100                     }
1101                     if (needEmulatedAstc(physicalDevice, vk)) {
1102                         emulateTextureAstc = true;
1103                         VkPhysicalDeviceFeatures2* features2 =
1104                                 (VkPhysicalDeviceFeatures2*)ext;
1105                         features2->features.textureCompressionASTC_LDR = false;
1106                     }
1107                     break;
1108                 default:
1109                     break;
1110             }
1111         }
1112 
1113         createInfoFiltered.enabledExtensionCount = (uint32_t)finalExts.size();
1114         createInfoFiltered.ppEnabledExtensionNames = finalExts.data();
1115 
1116         // bug: 155795731 (see below)
1117         if (mLogging) {
1118             fprintf(stderr, "%s: acquire lock\n", __func__);
1119         }
1120 
1121         AutoLock lock(mLock);
1122 
1123         if (mLogging) {
1124             fprintf(stderr, "%s: got lock, calling host\n", __func__);
1125         }
1126 
1127         VkResult result =
1128             vk->vkCreateDevice(
1129                     physicalDevice, &createInfoFiltered, pAllocator, pDevice);
1130 
1131         if (mLogging) {
1132             fprintf(stderr, "%s: host returned. result: %d\n", __func__, result);
1133         }
1134 
1135         if (result != VK_SUCCESS) return result;
1136 
1137         if (mLogging) {
1138             fprintf(stderr, "%s: track the new device (begin)\n", __func__);
1139         }
1140 
1141         // bug: 155795731 we should protect vkCreateDevice in the driver too
1142         // because, at least w/ tcmalloc, there is a flaky crash on loading its
1143         // procs
1144         //
1145         // AutoLock lock(mLock);
1146 
1147         mDeviceToPhysicalDevice[*pDevice] = physicalDevice;
1148 
1149         // Fill out information about the logical device here.
1150         auto& deviceInfo = mDeviceInfo[*pDevice];
1151         deviceInfo.physicalDevice = physicalDevice;
1152         deviceInfo.emulateTextureEtc2 = emulateTextureEtc2;
1153         deviceInfo.emulateTextureAstc = emulateTextureAstc;
1154 
1155         for (uint32_t i = 0; i < createInfoFiltered.enabledExtensionCount;
1156                 ++i) {
1157             deviceInfo.enabledExtensionNames.push_back(
1158                 createInfoFiltered.ppEnabledExtensionNames[i]);
1159         }
1160 
1161         // First, get the dispatch table.
1162         VkDevice boxed = new_boxed_VkDevice(*pDevice, nullptr, true /* own dispatch */);
1163 
1164         if (mLogging) {
1165             fprintf(stderr, "%s: init vulkan dispatch from device\n", __func__);
1166         }
1167 
1168         init_vulkan_dispatch_from_device(
1169                 vk, *pDevice,
1170                 dispatch_VkDevice(boxed));
1171 
1172         if (mLogging) {
1173             fprintf(stderr, "%s: init vulkan dispatch from device (end)\n", __func__);
1174         }
1175 
1176         deviceInfo.boxed = boxed;
1177 
1178         // Next, get information about the queue families used by this device.
1179         std::unordered_map<uint32_t, uint32_t> queueFamilyIndexCounts;
1180         for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
1181             const auto& queueCreateInfo =
1182                 pCreateInfo->pQueueCreateInfos[i];
1183             // Check only queues created with flags = 0 in VkDeviceQueueCreateInfo.
1184             auto flags = queueCreateInfo.flags;
1185             if (flags) continue;
1186             uint32_t queueFamilyIndex = queueCreateInfo.queueFamilyIndex;
1187             uint32_t queueCount = queueCreateInfo.queueCount;
1188             queueFamilyIndexCounts[queueFamilyIndex] = queueCount;
1189         }
1190 
1191         auto it = mPhysdevInfo.find(physicalDevice);
1192 
1193         for (auto it : queueFamilyIndexCounts) {
1194             auto index = it.first;
1195             auto count = it.second;
1196             auto& queues = deviceInfo.queues[index];
1197             for (uint32_t i = 0; i < count; ++i) {
1198                 VkQueue queueOut;
1199 
1200                 if (mLogging) {
1201                     fprintf(stderr, "%s: get device queue (begin)\n", __func__);
1202                 }
1203 
1204                 vk->vkGetDeviceQueue(
1205                         *pDevice, index, i, &queueOut);
1206 
1207                 if (mLogging) {
1208                     fprintf(stderr, "%s: get device queue (end)\n", __func__);
1209                 }
1210 
1211                 queues.push_back(queueOut);
1212                 mQueueInfo[queueOut].device = *pDevice;
1213                 mQueueInfo[queueOut].queueFamilyIndex = index;
1214 
1215                 auto boxed = new_boxed_VkQueue(queueOut, dispatch_VkDevice(deviceInfo.boxed), false /* does not own dispatch */);
1216                 mQueueInfo[queueOut].boxed = boxed;
1217                 mQueueInfo[queueOut].lock = new Lock;
1218             }
1219         }
1220 
1221         // Box the device.
1222         *pDevice = (VkDevice)deviceInfo.boxed;
1223 
1224         if (mLogging) {
1225             fprintf(stderr, "%s: (end)\n", __func__);
1226         }
1227 
1228         return VK_SUCCESS;
1229     }
1230 
on_vkGetDeviceQueue(android::base::BumpPool * pool,VkDevice boxed_device,uint32_t queueFamilyIndex,uint32_t queueIndex,VkQueue * pQueue)1231     void on_vkGetDeviceQueue(
1232             android::base::BumpPool* pool,
1233             VkDevice boxed_device,
1234             uint32_t queueFamilyIndex,
1235             uint32_t queueIndex,
1236             VkQueue* pQueue) {
1237 
1238         auto device = unbox_VkDevice(boxed_device);
1239 
1240         AutoLock lock(mLock);
1241 
1242         *pQueue = VK_NULL_HANDLE;
1243 
1244         auto deviceInfo = android::base::find(mDeviceInfo, device);
1245         if (!deviceInfo) return;
1246 
1247         const auto& queues =
1248             deviceInfo->queues;
1249 
1250         const auto queueList =
1251             android::base::find(queues, queueFamilyIndex);
1252 
1253         if (!queueList) return;
1254         if (queueIndex >= queueList->size()) return;
1255 
1256         VkQueue unboxedQueue = (*queueList)[queueIndex];
1257 
1258         auto queueInfo = android::base::find(mQueueInfo, unboxedQueue);
1259 
1260         if (!queueInfo) return;
1261 
1262         *pQueue = (VkQueue)queueInfo->boxed;
1263     }
1264 
destroyDeviceLocked(VkDevice device,const VkAllocationCallbacks * pAllocator)1265     void destroyDeviceLocked(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1266         auto it = mDeviceInfo.find(device);
1267         if (it == mDeviceInfo.end()) return;
1268 
1269         auto eraseIt = mQueueInfo.begin();
1270         for(; eraseIt != mQueueInfo.end();) {
1271             if (eraseIt->second.device == device) {
1272                 delete eraseIt->second.lock;
1273                 delete_VkQueue(eraseIt->second.boxed);
1274                 eraseIt = mQueueInfo.erase(eraseIt);
1275             } else {
1276                 ++eraseIt;
1277             }
1278         }
1279 
1280         // Run the underlying API call.
1281         m_vk->vkDestroyDevice(device, pAllocator);
1282 
1283         delete_VkDevice(it->second.boxed);
1284     }
1285 
on_vkDestroyDevice(android::base::BumpPool * pool,VkDevice boxed_device,const VkAllocationCallbacks * pAllocator)1286     void on_vkDestroyDevice(
1287             android::base::BumpPool* pool,
1288             VkDevice boxed_device,
1289             const VkAllocationCallbacks* pAllocator) {
1290 
1291         auto device = unbox_VkDevice(boxed_device);
1292 
1293         AutoLock lock(mLock);
1294 
1295         sBoxedHandleManager.processDelayedRemovesGlobalStateLocked(device);
1296         destroyDeviceLocked(device, pAllocator);
1297 
1298         mDeviceInfo.erase(device);
1299         mDeviceToPhysicalDevice.erase(device);
1300     }
1301 
on_vkCreateBuffer(android::base::BumpPool * pool,VkDevice boxed_device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer)1302     VkResult on_vkCreateBuffer(
1303             android::base::BumpPool* pool,
1304             VkDevice boxed_device,
1305             const VkBufferCreateInfo* pCreateInfo,
1306             const VkAllocationCallbacks* pAllocator,
1307             VkBuffer* pBuffer) {
1308 
1309         auto device = unbox_VkDevice(boxed_device);
1310         auto vk = dispatch_VkDevice(boxed_device);
1311 
1312         VkResult result =
1313             vk->vkCreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
1314 
1315         if (result == VK_SUCCESS) {
1316             AutoLock lock(mLock);
1317             auto& bufInfo = mBufferInfo[*pBuffer];
1318             bufInfo.device = device;
1319             bufInfo.size = pCreateInfo->size;
1320             bufInfo.vk = vk;
1321             *pBuffer = new_boxed_non_dispatchable_VkBuffer(*pBuffer);
1322         }
1323 
1324         return result;
1325     }
1326 
on_vkDestroyBuffer(android::base::BumpPool * pool,VkDevice boxed_device,VkBuffer buffer,const VkAllocationCallbacks * pAllocator)1327     void on_vkDestroyBuffer(
1328             android::base::BumpPool* pool,
1329             VkDevice boxed_device, VkBuffer buffer,
1330             const VkAllocationCallbacks* pAllocator) {
1331 
1332         auto device = unbox_VkDevice(boxed_device);
1333         auto vk = dispatch_VkDevice(boxed_device);
1334 
1335         vk->vkDestroyBuffer(device, buffer, pAllocator);
1336 
1337         AutoLock lock(mLock);
1338         mBufferInfo.erase(buffer);
1339     }
1340 
setBufferMemoryBindInfoLocked(VkBuffer buffer,VkDeviceMemory memory,VkDeviceSize memoryOffset)1341     void setBufferMemoryBindInfoLocked(
1342             VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset) {
1343         auto it = mBufferInfo.find(buffer);
1344         if (it == mBufferInfo.end()) {
1345             return;
1346         }
1347         it->second.memory = memory;
1348         it->second.memoryOffset = memoryOffset;
1349     }
1350 
on_vkBindBufferMemory(android::base::BumpPool * pool,VkDevice boxed_device,VkBuffer buffer,VkDeviceMemory memory,VkDeviceSize memoryOffset)1351     VkResult on_vkBindBufferMemory(
1352             android::base::BumpPool* pool,
1353             VkDevice boxed_device,
1354             VkBuffer buffer,
1355             VkDeviceMemory memory,
1356             VkDeviceSize memoryOffset) {
1357 
1358         auto device = unbox_VkDevice(boxed_device);
1359         auto vk = dispatch_VkDevice(boxed_device);
1360 
1361         VkResult result =
1362             vk->vkBindBufferMemory(device, buffer, memory, memoryOffset);
1363 
1364         if (result == VK_SUCCESS) {
1365             AutoLock lock(mLock);
1366             setBufferMemoryBindInfoLocked(buffer, memory, memoryOffset);
1367         }
1368         return result;
1369     }
1370 
on_vkBindBufferMemory2(android::base::BumpPool * pool,VkDevice boxed_device,uint32_t bindInfoCount,const VkBindBufferMemoryInfo * pBindInfos)1371     VkResult on_vkBindBufferMemory2(
1372             android::base::BumpPool* pool,
1373             VkDevice boxed_device,
1374             uint32_t bindInfoCount,
1375             const VkBindBufferMemoryInfo* pBindInfos) {
1376 
1377         auto device = unbox_VkDevice(boxed_device);
1378         auto vk = dispatch_VkDevice(boxed_device);
1379 
1380         VkResult result =
1381             vk->vkBindBufferMemory2(device, bindInfoCount, pBindInfos);
1382 
1383         if (result == VK_SUCCESS) {
1384             AutoLock lock(mLock);
1385             for (uint32_t i = 0; i < bindInfoCount; ++i) {
1386                 setBufferMemoryBindInfoLocked(
1387                         pBindInfos[i].buffer,
1388                         pBindInfos[i].memory,
1389                         pBindInfos[i].memoryOffset);
1390             }
1391         }
1392 
1393         return result;
1394     }
1395 
on_vkBindBufferMemory2KHR(android::base::BumpPool * pool,VkDevice boxed_device,uint32_t bindInfoCount,const VkBindBufferMemoryInfo * pBindInfos)1396     VkResult on_vkBindBufferMemory2KHR(
1397             android::base::BumpPool* pool,
1398             VkDevice boxed_device,
1399             uint32_t bindInfoCount,
1400             const VkBindBufferMemoryInfo* pBindInfos) {
1401 
1402         auto device = unbox_VkDevice(boxed_device);
1403         auto vk = dispatch_VkDevice(boxed_device);
1404 
1405         VkResult result =
1406             vk->vkBindBufferMemory2KHR(device, bindInfoCount, pBindInfos);
1407 
1408         if (result == VK_SUCCESS) {
1409             AutoLock lock(mLock);
1410             for (uint32_t i = 0; i < bindInfoCount; ++i) {
1411                 setBufferMemoryBindInfoLocked(
1412                         pBindInfos[i].buffer,
1413                         pBindInfos[i].memory,
1414                         pBindInfos[i].memoryOffset);
1415             }
1416         }
1417 
1418         return result;
1419 
1420     }
1421 
on_vkCreateImage(android::base::BumpPool * pool,VkDevice boxed_device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage)1422     VkResult on_vkCreateImage(
1423             android::base::BumpPool* pool,
1424             VkDevice boxed_device,
1425             const VkImageCreateInfo* pCreateInfo,
1426             const VkAllocationCallbacks* pAllocator,
1427             VkImage* pImage) {
1428 
1429         auto device = unbox_VkDevice(boxed_device);
1430         auto vk = dispatch_VkDevice(boxed_device);
1431 
1432         AutoLock lock(mLock);
1433 
1434         auto deviceInfoIt = mDeviceInfo.find(device);
1435         if (deviceInfoIt == mDeviceInfo.end()) {
1436             return VK_ERROR_OUT_OF_HOST_MEMORY;
1437         }
1438 
1439         CompressedImageInfo cmpInfo = {};
1440         VkImageCreateInfo& sizeCompInfo = cmpInfo.sizeCompImgCreateInfo;
1441         VkImageCreateInfo decompInfo;
1442         if (deviceInfoIt->second.needEmulatedDecompression(
1443                     pCreateInfo->format)) {
1444             cmpInfo = createCompressedImageInfo(pCreateInfo->format);
1445             cmpInfo.imageType = pCreateInfo->imageType;
1446             cmpInfo.extent = pCreateInfo->extent;
1447             cmpInfo.mipLevels = pCreateInfo->mipLevels;
1448             cmpInfo.layerCount = pCreateInfo->arrayLayers;
1449             sizeCompInfo = *pCreateInfo;
1450             sizeCompInfo.format = cmpInfo.sizeCompFormat;
1451             sizeCompInfo.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
1452             sizeCompInfo.flags &=
1453                     ~VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR;
1454             sizeCompInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
1455             // Each block is 4x4 in ETC2 compressed texture
1456             sizeCompInfo.extent.width = (sizeCompInfo.extent.width +
1457                                          cmpInfo.compressedBlockWidth - 1) /
1458                                         cmpInfo.compressedBlockWidth;
1459             sizeCompInfo.extent.height = (sizeCompInfo.extent.height +
1460                                           cmpInfo.compressedBlockHeight - 1) /
1461                                          cmpInfo.compressedBlockHeight;
1462             sizeCompInfo.mipLevels = 1;
1463             if (pCreateInfo->queueFamilyIndexCount) {
1464                 cmpInfo.sizeCompImgQueueFamilyIndices.assign(
1465                         pCreateInfo->pQueueFamilyIndices,
1466                         pCreateInfo->pQueueFamilyIndices +
1467                                 pCreateInfo->queueFamilyIndexCount);
1468                 sizeCompInfo.pQueueFamilyIndices =
1469                         cmpInfo.sizeCompImgQueueFamilyIndices.data();
1470             }
1471             decompInfo = *pCreateInfo;
1472             decompInfo.format = cmpInfo.decompFormat;
1473             decompInfo.flags &=
1474                     ~VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR;
1475             decompInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
1476             decompInfo.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
1477             pCreateInfo = &decompInfo;
1478         }
1479         cmpInfo.device = device;
1480 
1481         AndroidNativeBufferInfo anbInfo;
1482         const VkNativeBufferANDROID* nativeBufferANDROID =
1483             vk_find_struct<VkNativeBufferANDROID>(pCreateInfo);
1484 
1485         VkResult createRes = VK_SUCCESS;
1486 
1487         if (nativeBufferANDROID) {
1488 
1489             auto memProps = memPropsOfDeviceLocked(device);
1490 
1491             createRes =
1492                 prepareAndroidNativeBufferImage(
1493                         vk, device, pCreateInfo, nativeBufferANDROID, pAllocator,
1494                         memProps, &anbInfo);
1495             if (createRes == VK_SUCCESS) {
1496                 *pImage = anbInfo.image;
1497             }
1498         } else {
1499             createRes =
1500                 vk->vkCreateImage(device, pCreateInfo, pAllocator, pImage);
1501         }
1502 
1503         if (createRes != VK_SUCCESS) return createRes;
1504 
1505         if (deviceInfoIt->second.needEmulatedDecompression(cmpInfo)) {
1506             cmpInfo.decompImg = *pImage;
1507             createSizeCompImages(vk, &cmpInfo);
1508         }
1509 
1510         auto& imageInfo = mImageInfo[*pImage];
1511         imageInfo.anbInfo = anbInfo;
1512         imageInfo.cmpInfo = cmpInfo;
1513 
1514         *pImage = new_boxed_non_dispatchable_VkImage(*pImage);
1515 
1516         return createRes;
1517     }
1518 
on_vkDestroyImage(android::base::BumpPool * pool,VkDevice boxed_device,VkImage image,const VkAllocationCallbacks * pAllocator)1519     void on_vkDestroyImage(
1520             android::base::BumpPool* pool,
1521             VkDevice boxed_device,
1522             VkImage image,
1523             const VkAllocationCallbacks* pAllocator) {
1524 
1525         auto device = unbox_VkDevice(boxed_device);
1526         auto vk = dispatch_VkDevice(boxed_device);
1527 
1528         AutoLock lock(mLock);
1529         auto it = mImageInfo.find(image);
1530 
1531         if (it == mImageInfo.end()) return;
1532 
1533         auto info = it->second;
1534 
1535         if (info.anbInfo.image) {
1536             teardownAndroidNativeBufferImage(vk, &info.anbInfo);
1537         } else {
1538             if (info.cmpInfo.isCompressed) {
1539                 CompressedImageInfo& cmpInfo = info.cmpInfo;
1540                 if (image != cmpInfo.decompImg) {
1541                     vk->vkDestroyImage(device, info.cmpInfo.decompImg, nullptr);
1542                 }
1543                 for (const auto& image : cmpInfo.sizeCompImgs) {
1544                     vk->vkDestroyImage(device, image, nullptr);
1545                 }
1546                 vk->vkDestroyDescriptorSetLayout(
1547                         device, cmpInfo.decompDescriptorSetLayout, nullptr);
1548                 vk->vkDestroyDescriptorPool(
1549                         device, cmpInfo.decompDescriptorPool, nullptr);
1550                 vk->vkDestroyShaderModule(device, cmpInfo.decompShader,
1551                         nullptr);
1552                 vk->vkDestroyPipelineLayout(
1553                         device, cmpInfo.decompPipelineLayout, nullptr);
1554                 vk->vkDestroyPipeline(device, cmpInfo.decompPipeline, nullptr);
1555                 for (const auto& imageView : cmpInfo.sizeCompImageViews) {
1556                     vk->vkDestroyImageView(device, imageView, nullptr);
1557                 }
1558                 for (const auto& imageView : cmpInfo.decompImageViews) {
1559                     vk->vkDestroyImageView(device, imageView, nullptr);
1560                 }
1561             }
1562             vk->vkDestroyImage(device, image, pAllocator);
1563         }
1564         mImageInfo.erase(image);
1565     }
1566 
on_vkBindImageMemory(android::base::BumpPool * pool,VkDevice boxed_device,VkImage image,VkDeviceMemory memory,VkDeviceSize memoryOffset)1567     VkResult on_vkBindImageMemory(android::base::BumpPool* pool,
1568             VkDevice boxed_device,
1569             VkImage image,
1570             VkDeviceMemory memory,
1571             VkDeviceSize memoryOffset) {
1572         auto device = unbox_VkDevice(boxed_device);
1573         auto vk = dispatch_VkDevice(boxed_device);
1574         VkResult result =
1575             vk->vkBindImageMemory(device, image, memory, memoryOffset);
1576         if (VK_SUCCESS != result) {
1577             return result;
1578         }
1579         AutoLock lock(mLock);
1580         auto deviceInfoIt = mDeviceInfo.find(device);
1581         if (deviceInfoIt == mDeviceInfo.end()) {
1582             return VK_ERROR_OUT_OF_HOST_MEMORY;
1583         }
1584         auto mapInfoIt = mMapInfo.find(memory);
1585         if (mapInfoIt == mMapInfo.end()) {
1586             return VK_ERROR_OUT_OF_HOST_MEMORY;
1587         }
1588         if (mapInfoIt->second.mtlTexture) {
1589             result = m_vk->vkSetMTLTextureMVK(image, mapInfoIt->second.mtlTexture);
1590             if (result != VK_SUCCESS) {
1591                 fprintf(stderr, "vkSetMTLTexture failed\n");
1592                 return VK_ERROR_OUT_OF_HOST_MEMORY;
1593             }
1594         }
1595         if (!deviceInfoIt->second.emulateTextureEtc2 &&
1596             !deviceInfoIt->second.emulateTextureAstc) {
1597             return VK_SUCCESS;
1598         }
1599         auto imageInfoIt = mImageInfo.find(image);
1600         if (imageInfoIt == mImageInfo.end()) {
1601             return VK_ERROR_OUT_OF_HOST_MEMORY;
1602         }
1603         CompressedImageInfo& cmp = imageInfoIt->second.cmpInfo;
1604         if (!deviceInfoIt->second.needEmulatedDecompression(cmp)) {
1605             return VK_SUCCESS;
1606         }
1607         for (size_t i = 0; i < cmp.sizeCompImgs.size(); i++) {
1608             result = vk->vkBindImageMemory(device, cmp.sizeCompImgs[i], memory,
1609                     memoryOffset + cmp.memoryOffsets[i]);
1610         }
1611 
1612         return VK_SUCCESS;
1613     }
1614 
on_vkCreateImageView(android::base::BumpPool * pool,VkDevice boxed_device,const VkImageViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImageView * pView)1615     VkResult on_vkCreateImageView(
1616             android::base::BumpPool* pool,
1617             VkDevice boxed_device,
1618             const VkImageViewCreateInfo* pCreateInfo,
1619             const VkAllocationCallbacks* pAllocator,
1620             VkImageView* pView) {
1621 
1622         auto device = unbox_VkDevice(boxed_device);
1623         auto vk = dispatch_VkDevice(boxed_device);
1624 
1625         if (!pCreateInfo) {
1626             return VK_ERROR_OUT_OF_HOST_MEMORY;
1627         }
1628 
1629         AutoLock lock(mLock);
1630         auto deviceInfoIt = mDeviceInfo.find(device);
1631         if (deviceInfoIt == mDeviceInfo.end()) {
1632             return VK_ERROR_OUT_OF_HOST_MEMORY;
1633         }
1634         auto imageInfoIt = mImageInfo.find(pCreateInfo->image);
1635         if (imageInfoIt == mImageInfo.end()) {
1636             return VK_ERROR_OUT_OF_HOST_MEMORY;
1637         }
1638         VkImageViewCreateInfo createInfo;
1639         bool needEmulatedAlpha = false;
1640         if (deviceInfoIt->second.emulateTextureEtc2 ||
1641             deviceInfoIt->second.emulateTextureAstc) {
1642             CompressedImageInfo cmpInfo = createCompressedImageInfo(
1643                     pCreateInfo->format
1644                     );
1645             if (deviceInfoIt->second.needEmulatedDecompression(cmpInfo)) {
1646                 if (imageInfoIt->second.cmpInfo.decompImg) {
1647                     createInfo = *pCreateInfo;
1648                     createInfo.format = cmpInfo.decompFormat;
1649                     needEmulatedAlpha = cmpInfo.needEmulatedAlpha();
1650                     createInfo.image = imageInfoIt->second.cmpInfo.decompImg;
1651                     pCreateInfo = &createInfo;
1652                 }
1653             } else if (deviceInfoIt->second.needEmulatedDecompression(
1654                                imageInfoIt->second.cmpInfo)) {
1655                 // Size compatible image view
1656                 createInfo = *pCreateInfo;
1657                 createInfo.format = cmpInfo.sizeCompFormat;
1658                 needEmulatedAlpha = false;
1659                 createInfo.image =
1660                     imageInfoIt->second.cmpInfo.sizeCompImgs
1661                     [pCreateInfo->subresourceRange.baseMipLevel];
1662                 createInfo.subresourceRange.baseMipLevel = 0;
1663                 pCreateInfo = &createInfo;
1664             }
1665         }
1666         if (imageInfoIt->second.anbInfo.externallyBacked) {
1667             createInfo = *pCreateInfo;
1668             createInfo.format = imageInfoIt->second.anbInfo.vkFormat;
1669             pCreateInfo = &createInfo;
1670         }
1671 
1672         VkResult result =
1673             vk->vkCreateImageView(device, pCreateInfo, pAllocator, pView);
1674         if (result != VK_SUCCESS) {
1675             return result;
1676         }
1677 
1678         auto& imageViewInfo = mImageViewInfo[*pView];
1679         imageViewInfo.needEmulatedAlpha = needEmulatedAlpha;
1680 
1681         *pView = new_boxed_non_dispatchable_VkImageView(*pView);
1682 
1683         return result;
1684     }
1685 
on_vkDestroyImageView(android::base::BumpPool * pool,VkDevice boxed_device,VkImageView imageView,const VkAllocationCallbacks * pAllocator)1686     void on_vkDestroyImageView(
1687             android::base::BumpPool* pool,
1688             VkDevice boxed_device,
1689             VkImageView imageView,
1690             const VkAllocationCallbacks* pAllocator) {
1691 
1692         auto device = unbox_VkDevice(boxed_device);
1693         auto vk = dispatch_VkDevice(boxed_device);
1694 
1695         vk->vkDestroyImageView(device, imageView, pAllocator);
1696         AutoLock lock(mLock);
1697         mImageViewInfo.erase(imageView);
1698     }
1699 
on_vkCreateSampler(android::base::BumpPool * pool,VkDevice boxed_device,const VkSamplerCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)1700     VkResult on_vkCreateSampler(
1701             android::base::BumpPool* pool,
1702             VkDevice boxed_device,
1703             const VkSamplerCreateInfo* pCreateInfo,
1704             const VkAllocationCallbacks* pAllocator,
1705             VkSampler* pSampler) {
1706 
1707         auto device = unbox_VkDevice(boxed_device);
1708         auto vk = dispatch_VkDevice(boxed_device);
1709         VkResult result =
1710             vk->vkCreateSampler(device, pCreateInfo, pAllocator, pSampler);
1711         if (result != VK_SUCCESS) {
1712             return result;
1713         }
1714         AutoLock lock(mLock);
1715         auto& samplerInfo = mSamplerInfo[*pSampler];
1716         samplerInfo.createInfo = *pCreateInfo;
1717         // We emulate RGB with RGBA for some compressed textures, which does not
1718         // handle translarent border correctly.
1719         samplerInfo.needEmulatedAlpha =
1720             (pCreateInfo->addressModeU ==
1721              VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER ||
1722              pCreateInfo->addressModeV ==
1723              VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER ||
1724              pCreateInfo->addressModeW ==
1725              VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) &&
1726             (pCreateInfo->borderColor ==
1727              VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK ||
1728              pCreateInfo->borderColor ==
1729              VK_BORDER_COLOR_INT_TRANSPARENT_BLACK);
1730 
1731         *pSampler = new_boxed_non_dispatchable_VkSampler(*pSampler);
1732 
1733         return result;
1734     }
1735 
on_vkDestroySampler(android::base::BumpPool * pool,VkDevice boxed_device,VkSampler sampler,const VkAllocationCallbacks * pAllocator)1736     void on_vkDestroySampler(
1737             android::base::BumpPool* pool,
1738             VkDevice boxed_device,
1739             VkSampler sampler,
1740             const VkAllocationCallbacks* pAllocator) {
1741 
1742         auto device = unbox_VkDevice(boxed_device);
1743         auto vk = dispatch_VkDevice(boxed_device);
1744         vk->vkDestroySampler(device, sampler, pAllocator);
1745         AutoLock lock(mLock);
1746         const auto& samplerInfoIt = mSamplerInfo.find(sampler);
1747         if (samplerInfoIt != mSamplerInfo.end()) {
1748             if (samplerInfoIt->second.emulatedborderSampler != VK_NULL_HANDLE) {
1749                 vk->vkDestroySampler(
1750                         device, samplerInfoIt->second.emulatedborderSampler,
1751                         nullptr);
1752             }
1753             mSamplerInfo.erase(samplerInfoIt);
1754         }
1755     }
1756 
on_vkCreateSemaphore(android::base::BumpPool * pool,VkDevice boxed_device,const VkSemaphoreCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSemaphore * pSemaphore)1757     VkResult on_vkCreateSemaphore(
1758             android::base::BumpPool* pool,
1759             VkDevice boxed_device,
1760             const VkSemaphoreCreateInfo* pCreateInfo,
1761             const VkAllocationCallbacks* pAllocator,
1762             VkSemaphore* pSemaphore) {
1763 
1764         auto device = unbox_VkDevice(boxed_device);
1765         auto vk = dispatch_VkDevice(boxed_device);
1766 
1767         VkSemaphoreCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);
1768         vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&localCreateInfo);
1769 
1770         VkSemaphoreTypeCreateInfoKHR localSemaphoreTypeCreateInfo;
1771         if (const VkSemaphoreTypeCreateInfoKHR* semaphoreTypeCiPtr =
1772                     vk_find_struct<VkSemaphoreTypeCreateInfoKHR>(pCreateInfo);
1773             semaphoreTypeCiPtr) {
1774             localSemaphoreTypeCreateInfo =
1775                     vk_make_orphan_copy(*semaphoreTypeCiPtr);
1776             vk_append_struct(&structChainIter, &localSemaphoreTypeCreateInfo);
1777         }
1778 
1779         const VkExportSemaphoreCreateInfoKHR* exportCiPtr =
1780             vk_find_struct<VkExportSemaphoreCreateInfoKHR>(pCreateInfo);
1781         VkExportSemaphoreCreateInfoKHR localSemaphoreCreateInfo;
1782 
1783         if (exportCiPtr) {
1784             localSemaphoreCreateInfo = vk_make_orphan_copy(*exportCiPtr);
1785 
1786 #ifdef _WIN32
1787             if (localSemaphoreCreateInfo.handleTypes) {
1788                 localSemaphoreCreateInfo.handleTypes =
1789                     VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
1790             }
1791 #endif
1792 
1793             vk_append_struct(&structChainIter, &localSemaphoreCreateInfo);
1794         }
1795 
1796         VkResult res = vk->vkCreateSemaphore(device, &localCreateInfo, pAllocator, pSemaphore);
1797 
1798         if (res != VK_SUCCESS) return res;
1799 
1800         *pSemaphore = new_boxed_non_dispatchable_VkSemaphore(*pSemaphore);
1801 
1802         return res;
1803     }
1804 
on_vkCreateFence(android::base::BumpPool * pool,VkDevice boxed_device,const VkFenceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkFence * pFence)1805     VkResult on_vkCreateFence(android::base::BumpPool* pool,
1806                               VkDevice boxed_device,
1807                               const VkFenceCreateInfo* pCreateInfo,
1808                               const VkAllocationCallbacks* pAllocator,
1809                               VkFence* pFence) {
1810         auto device = unbox_VkDevice(boxed_device);
1811         auto vk = dispatch_VkDevice(boxed_device);
1812 
1813         VkResult res =
1814                 vk->vkCreateFence(device, pCreateInfo, pAllocator, pFence);
1815         if (res != VK_SUCCESS) {
1816             return res;
1817         }
1818 
1819         {
1820             AutoLock lock(mLock);
1821 
1822             DCHECK(mFenceInfo.find(*pFence) == mFenceInfo.end());
1823             mFenceInfo[*pFence] = {};
1824             auto& fenceInfo = mFenceInfo[*pFence];
1825             fenceInfo.device = device;
1826             fenceInfo.vk = vk;
1827 
1828             *pFence = new_boxed_non_dispatchable_VkFence(*pFence);
1829             fenceInfo.boxed = *pFence;
1830         }
1831 
1832         return res;
1833     }
1834 
on_vkImportSemaphoreFdKHR(android::base::BumpPool * pool,VkDevice boxed_device,const VkImportSemaphoreFdInfoKHR * pImportSemaphoreFdInfo)1835     VkResult on_vkImportSemaphoreFdKHR(
1836             android::base::BumpPool* pool,
1837             VkDevice boxed_device,
1838             const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo) {
1839 
1840         auto device = unbox_VkDevice(boxed_device);
1841         auto vk = dispatch_VkDevice(boxed_device);
1842 
1843 #ifdef _WIN32
1844         AutoLock lock(mLock);
1845 
1846         auto infoPtr = android::base::find(
1847                 mSemaphoreInfo, mExternalSemaphoresById[pImportSemaphoreFdInfo->fd]);
1848 
1849         if (!infoPtr) {
1850             return VK_ERROR_INVALID_EXTERNAL_HANDLE;
1851         }
1852 
1853         VK_EXT_MEMORY_HANDLE handle =
1854             dupExternalMemory(infoPtr->externalHandle);
1855 
1856         VkImportSemaphoreWin32HandleInfoKHR win32ImportInfo = {
1857             VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR, 0,
1858             pImportSemaphoreFdInfo->semaphore,
1859             pImportSemaphoreFdInfo->flags,
1860             VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR,
1861             handle, L"",
1862         };
1863 
1864         return vk->vkImportSemaphoreWin32HandleKHR(
1865                 device, &win32ImportInfo);
1866 #else
1867         VkImportSemaphoreFdInfoKHR importInfo = *pImportSemaphoreFdInfo;
1868         importInfo.fd = dup(pImportSemaphoreFdInfo->fd);
1869         return vk->vkImportSemaphoreFdKHR(device, &importInfo);
1870 #endif
1871     }
1872 
on_vkGetSemaphoreFdKHR(android::base::BumpPool * pool,VkDevice boxed_device,const VkSemaphoreGetFdInfoKHR * pGetFdInfo,int * pFd)1873     VkResult on_vkGetSemaphoreFdKHR(
1874             android::base::BumpPool* pool,
1875             VkDevice boxed_device,
1876             const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
1877             int* pFd) {
1878 
1879         auto device = unbox_VkDevice(boxed_device);
1880         auto vk = dispatch_VkDevice(boxed_device);
1881 #ifdef _WIN32
1882         VkSemaphoreGetWin32HandleInfoKHR getWin32 = {
1883             VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR, 0,
1884             pGetFdInfo->semaphore,
1885             VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT,
1886         };
1887         VK_EXT_MEMORY_HANDLE handle;
1888         VkResult result = vk->vkGetSemaphoreWin32HandleKHR(device, &getWin32, &handle);
1889         if (result != VK_SUCCESS) {
1890             return result;
1891         }
1892         AutoLock lock(mLock);
1893         mSemaphoreInfo[pGetFdInfo->semaphore].externalHandle = handle;
1894         int nextId = genSemaphoreId();
1895         mExternalSemaphoresById[nextId] = pGetFdInfo->semaphore;
1896         *pFd = nextId;
1897 #else
1898         VkResult result = vk->vkGetSemaphoreFdKHR(device, pGetFdInfo, pFd);
1899         if (result != VK_SUCCESS) {
1900             return result;
1901         }
1902 
1903         AutoLock lock(mLock);
1904 
1905         mSemaphoreInfo[pGetFdInfo->semaphore].externalHandle = *pFd;
1906         // No next id; its already an fd
1907 #endif
1908         return result;
1909     }
1910 
on_vkDestroySemaphore(android::base::BumpPool * pool,VkDevice boxed_device,VkSemaphore semaphore,const VkAllocationCallbacks * pAllocator)1911     void on_vkDestroySemaphore(
1912             android::base::BumpPool* pool,
1913             VkDevice boxed_device,
1914             VkSemaphore semaphore,
1915             const VkAllocationCallbacks* pAllocator) {
1916 
1917         auto device = unbox_VkDevice(boxed_device);
1918         auto vk = dispatch_VkDevice(boxed_device);
1919 
1920 #ifndef _WIN32
1921         AutoLock lock(mLock);
1922         const auto& ite = mSemaphoreInfo.find(semaphore);
1923         if (ite != mSemaphoreInfo.end() &&
1924                 (ite->second.externalHandle != VK_EXT_MEMORY_HANDLE_INVALID)) {
1925             close(ite->second.externalHandle);
1926         }
1927 #endif
1928         vk->vkDestroySemaphore(device, semaphore, pAllocator);
1929     }
1930 
on_vkDestroyFence(android::base::BumpPool * pool,VkDevice boxed_device,VkFence fence,const VkAllocationCallbacks * pAllocator)1931     void on_vkDestroyFence(android::base::BumpPool* pool,
1932                            VkDevice boxed_device,
1933                            VkFence fence,
1934                            const VkAllocationCallbacks* pAllocator) {
1935         auto device = unbox_VkDevice(boxed_device);
1936         auto vk = dispatch_VkDevice(boxed_device);
1937 
1938         {
1939             AutoLock lock(mLock);
1940             mFenceInfo.erase(fence);
1941         }
1942 
1943         vk->vkDestroyFence(device, fence, pAllocator);
1944     }
1945 
on_vkCreateDescriptorSetLayout(android::base::BumpPool * pool,VkDevice boxed_device,const VkDescriptorSetLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorSetLayout * pSetLayout)1946     VkResult on_vkCreateDescriptorSetLayout(
1947         android::base::BumpPool* pool,
1948         VkDevice boxed_device,
1949         const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
1950         const VkAllocationCallbacks* pAllocator,
1951         VkDescriptorSetLayout* pSetLayout) {
1952 
1953         auto device = unbox_VkDevice(boxed_device);
1954         auto vk = dispatch_VkDevice(boxed_device);
1955 
1956         auto res =
1957             vk->vkCreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout);
1958 
1959         if (res == VK_SUCCESS) {
1960             AutoLock lock(mLock);
1961             auto& info = mDescriptorSetLayoutInfo[*pSetLayout];
1962             info.device = device;
1963             *pSetLayout = new_boxed_non_dispatchable_VkDescriptorSetLayout(*pSetLayout);
1964             info.boxed = *pSetLayout;
1965 
1966             info.createInfo = *pCreateInfo;
1967             for (uint32_t i = 0; i < pCreateInfo->bindingCount; ++i) {
1968                 info.bindings.push_back(pCreateInfo->pBindings[i]);
1969             }
1970         }
1971 
1972         return res;
1973     }
1974 
on_vkDestroyDescriptorSetLayout(android::base::BumpPool * pool,VkDevice boxed_device,VkDescriptorSetLayout descriptorSetLayout,const VkAllocationCallbacks * pAllocator)1975     void on_vkDestroyDescriptorSetLayout(
1976         android::base::BumpPool* pool,
1977         VkDevice boxed_device,
1978         VkDescriptorSetLayout descriptorSetLayout,
1979         const VkAllocationCallbacks* pAllocator) {
1980 
1981         auto device = unbox_VkDevice(boxed_device);
1982         auto vk = dispatch_VkDevice(boxed_device);
1983 
1984         vk->vkDestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
1985 
1986         AutoLock lock(mLock);
1987         mDescriptorSetLayoutInfo.erase(descriptorSetLayout);
1988     }
1989 
on_vkCreateDescriptorPool(android::base::BumpPool * pool,VkDevice boxed_device,const VkDescriptorPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorPool * pDescriptorPool)1990     VkResult on_vkCreateDescriptorPool(
1991         android::base::BumpPool* pool,
1992         VkDevice boxed_device,
1993         const VkDescriptorPoolCreateInfo* pCreateInfo,
1994         const VkAllocationCallbacks* pAllocator,
1995         VkDescriptorPool* pDescriptorPool) {
1996 
1997         auto device = unbox_VkDevice(boxed_device);
1998         auto vk = dispatch_VkDevice(boxed_device);
1999 
2000         auto res =
2001             vk->vkCreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool);
2002 
2003         if (res == VK_SUCCESS) {
2004             AutoLock lock(mLock);
2005             auto& info = mDescriptorPoolInfo[*pDescriptorPool];
2006             info.device = device;
2007             *pDescriptorPool = new_boxed_non_dispatchable_VkDescriptorPool(*pDescriptorPool);
2008             info.boxed = *pDescriptorPool;
2009             info.createInfo = *pCreateInfo;
2010             info.maxSets = pCreateInfo->maxSets;
2011             info.usedSets = 0;
2012 
2013             for (uint32_t i = 0; i < pCreateInfo->poolSizeCount; ++i) {
2014                 DescriptorPoolInfo::PoolState state;
2015                 state.type = pCreateInfo->pPoolSizes[i].type;
2016                 state.descriptorCount = pCreateInfo->pPoolSizes[i].descriptorCount;
2017                 state.used = 0;
2018                 info.pools.push_back(state);
2019             }
2020 
2021             if (feature_is_enabled(kFeature_VulkanBatchedDescriptorSetUpdate)) {
2022                 for (uint32_t i = 0; i < pCreateInfo->maxSets; ++i) {
2023                     info.poolIds.push_back((uint64_t)new_boxed_non_dispatchable_VkDescriptorSet(VK_NULL_HANDLE));
2024                 }
2025             }
2026         }
2027 
2028         return res;
2029     }
2030 
cleanupDescriptorPoolAllocedSetsLocked(VkDescriptorPool descriptorPool,bool isDestroy=false)2031     void cleanupDescriptorPoolAllocedSetsLocked(VkDescriptorPool descriptorPool, bool isDestroy = false) {
2032         auto info = android::base::find(mDescriptorPoolInfo, descriptorPool);
2033 
2034         if (!info) return;
2035 
2036         for (auto it : info->allocedSetsToBoxed) {
2037             auto unboxedSet = it.first;
2038             auto boxedSet = it.second;
2039             mDescriptorSetInfo.erase(unboxedSet);
2040             if (!feature_is_enabled(kFeature_VulkanBatchedDescriptorSetUpdate)) {
2041                 delete_VkDescriptorSet(boxedSet);
2042             }
2043         }
2044 
2045         if (feature_is_enabled(kFeature_VulkanBatchedDescriptorSetUpdate)) {
2046             if (isDestroy) {
2047                 for (auto poolId : info->poolIds) {
2048                     delete_VkDescriptorSet((VkDescriptorSet)poolId);
2049                 }
2050             } else {
2051                 for (auto poolId : info->poolIds) {
2052                     auto handleInfo = sBoxedHandleManager.get(poolId);
2053                     if (handleInfo) handleInfo->underlying = VK_NULL_HANDLE;
2054                 }
2055             }
2056         }
2057 
2058         info->usedSets = 0;
2059         info->allocedSetsToBoxed.clear();
2060 
2061         for (auto& pool : info->pools) {
2062             pool.used = 0;
2063         }
2064     }
2065 
on_vkDestroyDescriptorPool(android::base::BumpPool * pool,VkDevice boxed_device,VkDescriptorPool descriptorPool,const VkAllocationCallbacks * pAllocator)2066     void on_vkDestroyDescriptorPool(
2067         android::base::BumpPool* pool,
2068         VkDevice boxed_device,
2069         VkDescriptorPool descriptorPool,
2070         const VkAllocationCallbacks* pAllocator) {
2071 
2072         auto device = unbox_VkDevice(boxed_device);
2073         auto vk = dispatch_VkDevice(boxed_device);
2074 
2075         vk->vkDestroyDescriptorPool(device, descriptorPool, pAllocator);
2076 
2077         AutoLock lock(mLock);
2078         cleanupDescriptorPoolAllocedSetsLocked(descriptorPool, true /* destroy */);
2079         mDescriptorPoolInfo.erase(descriptorPool);
2080     }
2081 
on_vkResetDescriptorPool(android::base::BumpPool * pool,VkDevice boxed_device,VkDescriptorPool descriptorPool,VkDescriptorPoolResetFlags flags)2082     VkResult on_vkResetDescriptorPool(
2083         android::base::BumpPool* pool,
2084         VkDevice boxed_device,
2085         VkDescriptorPool descriptorPool,
2086         VkDescriptorPoolResetFlags flags) {
2087 
2088         auto device = unbox_VkDevice(boxed_device);
2089         auto vk = dispatch_VkDevice(boxed_device);
2090 
2091         auto res = vk->vkResetDescriptorPool(device, descriptorPool, flags);
2092 
2093         if (res == VK_SUCCESS) {
2094             AutoLock lock(mLock);
2095             cleanupDescriptorPoolAllocedSetsLocked(descriptorPool);
2096         }
2097 
2098         return res;
2099     }
2100 
initDescriptorSetInfoLocked(VkDescriptorPool pool,VkDescriptorSetLayout setLayout,uint64_t boxedDescriptorSet,VkDescriptorSet descriptorSet)2101     void initDescriptorSetInfoLocked(
2102         VkDescriptorPool pool,
2103         VkDescriptorSetLayout setLayout,
2104         uint64_t boxedDescriptorSet,
2105         VkDescriptorSet descriptorSet) {
2106 
2107         auto poolInfo = android::base::find(mDescriptorPoolInfo, pool);
2108 
2109         auto setLayoutInfo =
2110             android::base::find(mDescriptorSetLayoutInfo, setLayout);
2111 
2112         auto& setInfo = mDescriptorSetInfo[descriptorSet];
2113 
2114         setInfo.pool = pool;
2115         setInfo.bindings = setLayoutInfo->bindings;
2116 
2117         poolInfo->allocedSetsToBoxed[descriptorSet] = (VkDescriptorSet)boxedDescriptorSet;
2118         applyDescriptorSetAllocationLocked(*poolInfo, setInfo.bindings);
2119     }
2120 
on_vkAllocateDescriptorSets(android::base::BumpPool * pool,VkDevice boxed_device,const VkDescriptorSetAllocateInfo * pAllocateInfo,VkDescriptorSet * pDescriptorSets)2121     VkResult on_vkAllocateDescriptorSets(
2122         android::base::BumpPool* pool,
2123         VkDevice boxed_device,
2124         const VkDescriptorSetAllocateInfo* pAllocateInfo,
2125         VkDescriptorSet* pDescriptorSets) {
2126 
2127         auto device = unbox_VkDevice(boxed_device);
2128         auto vk = dispatch_VkDevice(boxed_device);
2129 
2130         AutoLock lock(mLock);
2131 
2132         auto allocValidationRes = validateDescriptorSetAllocLocked(pAllocateInfo);
2133         if (allocValidationRes != VK_SUCCESS) return allocValidationRes;
2134 
2135         auto res = vk->vkAllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
2136 
2137         if (res == VK_SUCCESS) {
2138 
2139             auto poolInfo = android::base::find(mDescriptorPoolInfo, pAllocateInfo->descriptorPool);
2140             if (!poolInfo) return res;
2141 
2142             for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; ++i) {
2143                 auto unboxed = pDescriptorSets[i];
2144                 pDescriptorSets[i] = new_boxed_non_dispatchable_VkDescriptorSet(pDescriptorSets[i]);
2145                 initDescriptorSetInfoLocked(
2146                     pAllocateInfo->descriptorPool,
2147                     pAllocateInfo->pSetLayouts[i],
2148                     (uint64_t)(pDescriptorSets[i]),
2149                     unboxed);
2150             }
2151         }
2152 
2153         return res;
2154     }
2155 
on_vkFreeDescriptorSets(android::base::BumpPool * pool,VkDevice boxed_device,VkDescriptorPool descriptorPool,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets)2156     VkResult on_vkFreeDescriptorSets(
2157         android::base::BumpPool* pool,
2158         VkDevice boxed_device,
2159         VkDescriptorPool descriptorPool,
2160         uint32_t descriptorSetCount,
2161         const VkDescriptorSet* pDescriptorSets) {
2162 
2163         auto device = unbox_VkDevice(boxed_device);
2164         auto vk = dispatch_VkDevice(boxed_device);
2165 
2166         auto res = vk->vkFreeDescriptorSets(
2167             device, descriptorPool,
2168             descriptorSetCount, pDescriptorSets);
2169 
2170         if (res == VK_SUCCESS) {
2171             AutoLock lock(mLock);
2172 
2173             for (uint32_t i = 0; i < descriptorSetCount; ++i) {
2174                 auto setInfo = android::base::find(
2175                     mDescriptorSetInfo, pDescriptorSets[i]);
2176 
2177                 if (!setInfo) continue;
2178 
2179                 auto poolInfo =
2180                     android::base::find(
2181                         mDescriptorPoolInfo, setInfo->pool);
2182 
2183                 if (!poolInfo) continue;
2184 
2185                 removeDescriptorSetAllocationLocked(*poolInfo, setInfo->bindings);
2186 
2187                 auto descSetAllocedEntry =
2188                     android::base::find(
2189                         poolInfo->allocedSetsToBoxed, pDescriptorSets[i]);
2190 
2191                 if (!descSetAllocedEntry) continue;
2192 
2193                 auto handleInfo = sBoxedHandleManager.get((uint64_t)*descSetAllocedEntry);
2194                 if (handleInfo) {
2195                     if (feature_is_enabled(kFeature_VulkanBatchedDescriptorSetUpdate)) {
2196                         handleInfo->underlying = VK_NULL_HANDLE;
2197                     } else {
2198                         delete_VkDescriptorSet(*descSetAllocedEntry);
2199                     }
2200                 }
2201 
2202                 poolInfo->allocedSetsToBoxed.erase(pDescriptorSets[i]);
2203 
2204                 mDescriptorSetInfo.erase(pDescriptorSets[i]);
2205             }
2206         }
2207 
2208         return res;
2209     }
2210 
on_vkUpdateDescriptorSets(android::base::BumpPool * pool,VkDevice boxed_device,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites,uint32_t descriptorCopyCount,const VkCopyDescriptorSet * pDescriptorCopies)2211     void on_vkUpdateDescriptorSets(
2212             android::base::BumpPool* pool,
2213             VkDevice boxed_device,
2214             uint32_t descriptorWriteCount,
2215             const VkWriteDescriptorSet* pDescriptorWrites,
2216             uint32_t descriptorCopyCount,
2217             const VkCopyDescriptorSet* pDescriptorCopies) {
2218 
2219         auto device = unbox_VkDevice(boxed_device);
2220         auto vk = dispatch_VkDevice(boxed_device);
2221 
2222         AutoLock lock(mLock);
2223         on_vkUpdateDescriptorSetsImpl(pool, vk, device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
2224     }
2225 
on_vkUpdateDescriptorSetsImpl(android::base::BumpPool * pool,VulkanDispatch * vk,VkDevice device,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites,uint32_t descriptorCopyCount,const VkCopyDescriptorSet * pDescriptorCopies)2226     void on_vkUpdateDescriptorSetsImpl(
2227             android::base::BumpPool* pool,
2228             VulkanDispatch* vk,
2229             VkDevice device,
2230             uint32_t descriptorWriteCount,
2231             const VkWriteDescriptorSet* pDescriptorWrites,
2232             uint32_t descriptorCopyCount,
2233             const VkCopyDescriptorSet* pDescriptorCopies) {
2234 
2235         bool needEmulateWriteDescriptor = false;
2236         // c++ seems to allow for 0-size array allocation
2237         std::unique_ptr<bool[]> descriptorWritesNeedDeepCopy(
2238                 new bool[descriptorWriteCount]);
2239         for (uint32_t i = 0; i < descriptorWriteCount; i++) {
2240             const VkWriteDescriptorSet& descriptorWrite = pDescriptorWrites[i];
2241             descriptorWritesNeedDeepCopy[i] = false;
2242             if (descriptorWrite.descriptorType !=
2243                     VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
2244                 continue;
2245             }
2246             for (uint32_t j = 0; j < descriptorWrite.descriptorCount; j++) {
2247                 const VkDescriptorImageInfo& imageInfo =
2248                     descriptorWrite.pImageInfo[j];
2249                 const auto& viewIt = mImageViewInfo.find(imageInfo.imageView);
2250                 if (viewIt == mImageViewInfo.end()) {
2251                     continue;
2252                 }
2253                 const auto& samplerIt = mSamplerInfo.find(imageInfo.sampler);
2254                 if (samplerIt == mSamplerInfo.end()) {
2255                     continue;
2256                 }
2257                 if (viewIt->second.needEmulatedAlpha &&
2258                         samplerIt->second.needEmulatedAlpha) {
2259                     needEmulateWriteDescriptor = true;
2260                     descriptorWritesNeedDeepCopy[i] = true;
2261                     break;
2262                 }
2263             }
2264         }
2265         if (!needEmulateWriteDescriptor) {
2266             vk->vkUpdateDescriptorSets(device, descriptorWriteCount,
2267                     pDescriptorWrites, descriptorCopyCount,
2268                     pDescriptorCopies);
2269             return;
2270         }
2271         std::list<std::unique_ptr<VkDescriptorImageInfo[]>> imageInfoPool;
2272         std::unique_ptr<VkWriteDescriptorSet[]> descriptorWrites(
2273                 new VkWriteDescriptorSet[descriptorWriteCount]);
2274         for (uint32_t i = 0; i < descriptorWriteCount; i++) {
2275             const VkWriteDescriptorSet& srcDescriptorWrite =
2276                 pDescriptorWrites[i];
2277             VkWriteDescriptorSet& dstDescriptorWrite = descriptorWrites[i];
2278             // Shallow copy first
2279             dstDescriptorWrite = srcDescriptorWrite;
2280             if (!descriptorWritesNeedDeepCopy[i]) {
2281                 continue;
2282             }
2283             // Deep copy
2284             assert(dstDescriptorWrite.descriptorType ==
2285                     VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2286             imageInfoPool.emplace_back(
2287                     new VkDescriptorImageInfo[dstDescriptorWrite
2288                     .descriptorCount]);
2289             VkDescriptorImageInfo* imageInfos = imageInfoPool.back().get();
2290             memcpy(imageInfos, srcDescriptorWrite.pImageInfo,
2291                     dstDescriptorWrite.descriptorCount *
2292                     sizeof(VkDescriptorImageInfo));
2293             dstDescriptorWrite.pImageInfo = imageInfos;
2294             for (uint32_t j = 0; j < dstDescriptorWrite.descriptorCount; j++) {
2295                 VkDescriptorImageInfo& imageInfo = imageInfos[j];
2296                 const auto& viewIt = mImageViewInfo.find(imageInfo.imageView);
2297                 if (viewIt == mImageViewInfo.end()) {
2298                     continue;
2299                 }
2300                 const auto& samplerIt = mSamplerInfo.find(imageInfo.sampler);
2301                 if (samplerIt == mSamplerInfo.end()) {
2302                     continue;
2303                 }
2304                 if (viewIt->second.needEmulatedAlpha &&
2305                         samplerIt->second.needEmulatedAlpha) {
2306                     SamplerInfo& samplerInfo = samplerIt->second;
2307                     if (samplerInfo.emulatedborderSampler == VK_NULL_HANDLE) {
2308                         // create the emulated sampler
2309                         VkSamplerCreateInfo createInfo = samplerInfo.createInfo;
2310                         switch (createInfo.borderColor) {
2311                             case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
2312                                 createInfo.borderColor =
2313                                     VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
2314                                 break;
2315                             case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
2316                                 createInfo.borderColor =
2317                                     VK_BORDER_COLOR_INT_OPAQUE_BLACK;
2318                                 break;
2319                             default:
2320                                 break;
2321                         }
2322                         vk->vkCreateSampler(device, &createInfo, nullptr,
2323                                 &samplerInfo.emulatedborderSampler);
2324                     }
2325                     imageInfo.sampler = samplerInfo.emulatedborderSampler;
2326                 }
2327             }
2328         }
2329         vk->vkUpdateDescriptorSets(device, descriptorWriteCount,
2330                 descriptorWrites.get(), descriptorCopyCount,
2331                 pDescriptorCopies);
2332     }
2333 
on_vkCmdCopyImage(android::base::BumpPool * pool,VkCommandBuffer boxed_commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageCopy * pRegions)2334     void on_vkCmdCopyImage(android::base::BumpPool* pool,
2335                            VkCommandBuffer boxed_commandBuffer,
2336                            VkImage srcImage,
2337                            VkImageLayout srcImageLayout,
2338                            VkImage dstImage,
2339                            VkImageLayout dstImageLayout,
2340                            uint32_t regionCount,
2341                            const VkImageCopy* pRegions) {
2342         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
2343         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
2344 
2345         AutoLock lock(mLock);
2346         auto srcIt = mImageInfo.find(srcImage);
2347         if (srcIt == mImageInfo.end()) {
2348             return;
2349         }
2350         auto dstIt = mImageInfo.find(dstImage);
2351         if (dstIt == mImageInfo.end()) {
2352             return;
2353         }
2354         VkDevice device = srcIt->second.cmpInfo.device;
2355         auto deviceInfoIt = mDeviceInfo.find(device);
2356         if (deviceInfoIt == mDeviceInfo.end()) {
2357             return;
2358         }
2359         bool needEmulatedSrc = deviceInfoIt->second.needEmulatedDecompression(
2360                 srcIt->second.cmpInfo);
2361         bool needEmulatedDst = deviceInfoIt->second.needEmulatedDecompression(
2362                 dstIt->second.cmpInfo);
2363         if (!needEmulatedSrc && !needEmulatedDst) {
2364             vk->vkCmdCopyImage(commandBuffer, srcImage, srcImageLayout,
2365                                dstImage, dstImageLayout, regionCount, pRegions);
2366             return;
2367         }
2368         VkImage srcImageMip = srcImage;
2369         VkImage dstImageMip = dstImage;
2370         for (uint32_t r = 0; r < regionCount; r++) {
2371             VkImageCopy region = pRegions[r];
2372             if (needEmulatedSrc) {
2373                 uint32_t mipLevel = region.srcSubresource.mipLevel;
2374                 uint32_t compressedBlockWidth =
2375                         srcIt->second.cmpInfo.compressedBlockWidth;
2376                 uint32_t compressedBlockHeight =
2377                         srcIt->second.cmpInfo.compressedBlockHeight;
2378                 srcImageMip = srcIt->second.cmpInfo.sizeCompImgs[mipLevel];
2379                 region.srcSubresource.mipLevel = 0;
2380                 region.srcOffset.x /= compressedBlockWidth;
2381                 region.srcOffset.y /= compressedBlockHeight;
2382                 uint32_t width =
2383                         srcIt->second.cmpInfo.sizeCompMipmapWidth(mipLevel);
2384                 uint32_t height =
2385                         srcIt->second.cmpInfo.sizeCompMipmapHeight(mipLevel);
2386                 // region.extent uses pixel size for source image
2387                 region.extent.width =
2388                         (region.extent.width + compressedBlockWidth - 1) /
2389                         compressedBlockWidth;
2390                 region.extent.height =
2391                         (region.extent.height + compressedBlockHeight - 1) /
2392                         compressedBlockHeight;
2393                 region.extent.width = std::min(region.extent.width, width);
2394                 region.extent.height = std::min(region.extent.height, height);
2395             }
2396             if (needEmulatedDst) {
2397                 uint32_t compressedBlockWidth =
2398                         dstIt->second.cmpInfo.compressedBlockWidth;
2399                 uint32_t compressedBlockHeight =
2400                         dstIt->second.cmpInfo.compressedBlockHeight;
2401                 uint32_t mipLevel = region.dstSubresource.mipLevel;
2402                 dstImageMip = dstIt->second.cmpInfo.sizeCompImgs[mipLevel];
2403                 region.dstSubresource.mipLevel = 0;
2404                 region.dstOffset.x /= compressedBlockWidth;
2405                 region.dstOffset.y /= compressedBlockHeight;
2406             }
2407             vk->vkCmdCopyImage(commandBuffer, srcImageMip, srcImageLayout,
2408                                dstImageMip, dstImageLayout, 1, &region);
2409         }
2410     }
2411 
on_vkCmdCopyImageToBuffer(android::base::BumpPool * pool,VkCommandBuffer boxed_commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferImageCopy * pRegions)2412     void on_vkCmdCopyImageToBuffer(android::base::BumpPool* pool,
2413             VkCommandBuffer boxed_commandBuffer,
2414             VkImage srcImage,
2415             VkImageLayout srcImageLayout,
2416             VkBuffer dstBuffer,
2417             uint32_t regionCount,
2418             const VkBufferImageCopy* pRegions) {
2419         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
2420         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
2421 
2422         AutoLock lock(mLock);
2423         auto it = mImageInfo.find(srcImage);
2424         if (it == mImageInfo.end()) {
2425             return;
2426         }
2427         auto bufferInfoIt = mBufferInfo.find(dstBuffer);
2428         if (bufferInfoIt == mBufferInfo.end()) {
2429             return;
2430         }
2431         VkDevice device = bufferInfoIt->second.device;
2432         auto deviceInfoIt = mDeviceInfo.find(device);
2433         if (deviceInfoIt == mDeviceInfo.end()) {
2434             return;
2435         }
2436         if (!deviceInfoIt->second.needEmulatedDecompression(
2437                     it->second.cmpInfo)) {
2438             vk->vkCmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout,
2439                     dstBuffer, regionCount, pRegions);
2440             return;
2441         }
2442         CompressedImageInfo& cmp = it->second.cmpInfo;
2443         for (uint32_t r = 0; r < regionCount; r++) {
2444             VkBufferImageCopy region;
2445             region = pRegions[r];
2446             uint32_t mipLevel = region.imageSubresource.mipLevel;
2447             region.imageSubresource.mipLevel = 0;
2448             region.bufferRowLength /= cmp.compressedBlockWidth;
2449             region.bufferImageHeight /= cmp.compressedBlockHeight;
2450             region.imageOffset.x /= cmp.compressedBlockWidth;
2451             region.imageOffset.y /= cmp.compressedBlockHeight;
2452             uint32_t width = cmp.sizeCompMipmapWidth(mipLevel);
2453             uint32_t height = cmp.sizeCompMipmapHeight(mipLevel);
2454             region.imageExtent.width =
2455                     (region.imageExtent.width + cmp.compressedBlockWidth - 1) /
2456                     cmp.compressedBlockWidth;
2457             region.imageExtent.height = (region.imageExtent.height +
2458                                          cmp.compressedBlockHeight - 1) /
2459                                         cmp.compressedBlockHeight;
2460             region.imageExtent.width =
2461                 std::min(region.imageExtent.width, width);
2462             region.imageExtent.height =
2463                 std::min(region.imageExtent.height, height);
2464             vk->vkCmdCopyImageToBuffer(commandBuffer,
2465                     cmp.sizeCompImgs[mipLevel],
2466                     srcImageLayout, dstBuffer, 1, &region);
2467         }
2468     }
2469 
on_vkGetImageMemoryRequirements(android::base::BumpPool * pool,VkDevice boxed_device,VkImage image,VkMemoryRequirements * pMemoryRequirements)2470     void on_vkGetImageMemoryRequirements(
2471             android::base::BumpPool* pool,
2472             VkDevice boxed_device,
2473             VkImage image,
2474             VkMemoryRequirements* pMemoryRequirements) {
2475         auto device = unbox_VkDevice(boxed_device);
2476         auto vk = dispatch_VkDevice(boxed_device);
2477         vk->vkGetImageMemoryRequirements(device, image, pMemoryRequirements);
2478         AutoLock lock(mLock);
2479         updateImageMemorySizeLocked(device, image, pMemoryRequirements);
2480     }
2481 
on_vkGetImageMemoryRequirements2(android::base::BumpPool * pool,VkDevice boxed_device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)2482     void on_vkGetImageMemoryRequirements2(
2483             android::base::BumpPool* pool,
2484             VkDevice boxed_device,
2485             const VkImageMemoryRequirementsInfo2* pInfo,
2486             VkMemoryRequirements2* pMemoryRequirements) {
2487         auto device = unbox_VkDevice(boxed_device);
2488         auto vk = dispatch_VkDevice(boxed_device);
2489         AutoLock lock(mLock);
2490 
2491         auto physicalDevice = mDeviceToPhysicalDevice[device];
2492         auto physdevInfo = android::base::find(mPhysdevInfo, physicalDevice);
2493 
2494         if (!physdevInfo) {
2495             // If this fails, we crash, as we assume that the memory properties
2496             // map should have the info.
2497             // fprintf(stderr, "%s: Could not get image memory requirement for VkPhysicalDevice\n");
2498         }
2499 
2500         if ((physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) &&
2501             vk->vkGetImageMemoryRequirements2) {
2502             vk->vkGetImageMemoryRequirements2(device, pInfo,
2503                     pMemoryRequirements);
2504         } else if (hasDeviceExtension(device,
2505                     "VK_KHR_get_memory_requirements2")) {
2506             vk->vkGetImageMemoryRequirements2KHR(device, pInfo,
2507                     pMemoryRequirements);
2508         } else {
2509             if (pInfo->pNext) {
2510                 fprintf(stderr,
2511                         "%s: Warning: Trying to use extension struct in "
2512                         "VkMemoryRequirements2 without having enabled "
2513                         "the extension!!!!11111\n",
2514                         __func__);
2515             }
2516 
2517             vk->vkGetImageMemoryRequirements(
2518                     device, pInfo->image,
2519                     &pMemoryRequirements->memoryRequirements);
2520         }
2521         updateImageMemorySizeLocked(device, pInfo->image,
2522                 &pMemoryRequirements->memoryRequirements);
2523     }
2524 
on_vkCmdCopyBufferToImage(android::base::BumpPool * pool,VkCommandBuffer boxed_commandBuffer,VkBuffer srcBuffer,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkBufferImageCopy * pRegions)2525     void on_vkCmdCopyBufferToImage(
2526             android::base::BumpPool* pool,
2527             VkCommandBuffer boxed_commandBuffer,
2528             VkBuffer srcBuffer,
2529             VkImage dstImage,
2530             VkImageLayout dstImageLayout,
2531             uint32_t regionCount,
2532             const VkBufferImageCopy* pRegions) {
2533 
2534         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
2535         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
2536 
2537         AutoLock lock(mLock);
2538         auto it = mImageInfo.find(dstImage);
2539         if (it == mImageInfo.end()) return;
2540         auto bufferInfoIt = mBufferInfo.find(srcBuffer);
2541         if (bufferInfoIt == mBufferInfo.end()) {
2542             return;
2543         }
2544         VkDevice device = bufferInfoIt->second.device;
2545         auto deviceInfoIt = mDeviceInfo.find(device);
2546         if (deviceInfoIt == mDeviceInfo.end()) {
2547             return;
2548         }
2549         if (!deviceInfoIt->second.needEmulatedDecompression(
2550                     it->second.cmpInfo)) {
2551             vk->vkCmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage,
2552                     dstImageLayout, regionCount, pRegions);
2553             return;
2554         }
2555         auto cmdBufferInfoIt = mCmdBufferInfo.find(commandBuffer);
2556         if (cmdBufferInfoIt == mCmdBufferInfo.end()) {
2557             return;
2558         }
2559         CompressedImageInfo& cmp = it->second.cmpInfo;
2560         for (uint32_t r = 0; r < regionCount; r++) {
2561             VkBufferImageCopy dstRegion;
2562             dstRegion = pRegions[r];
2563             uint32_t mipLevel = dstRegion.imageSubresource.mipLevel;
2564             dstRegion.imageSubresource.mipLevel = 0;
2565             dstRegion.bufferRowLength /= cmp.compressedBlockWidth;
2566             dstRegion.bufferImageHeight /= cmp.compressedBlockHeight;
2567             dstRegion.imageOffset.x /= cmp.compressedBlockWidth;
2568             dstRegion.imageOffset.y /= cmp.compressedBlockHeight;
2569             uint32_t width = cmp.sizeCompMipmapWidth(mipLevel);
2570             uint32_t height = cmp.sizeCompMipmapHeight(mipLevel);
2571             dstRegion.imageExtent.width = (dstRegion.imageExtent.width +
2572                                            cmp.compressedBlockWidth - 1) /
2573                                           cmp.compressedBlockWidth;
2574             dstRegion.imageExtent.height = (dstRegion.imageExtent.height +
2575                                             cmp.compressedBlockHeight - 1) /
2576                                            cmp.compressedBlockHeight;
2577             dstRegion.imageExtent.width =
2578                 std::min(dstRegion.imageExtent.width, width);
2579             dstRegion.imageExtent.height =
2580                 std::min(dstRegion.imageExtent.height, height);
2581             vk->vkCmdCopyBufferToImage(commandBuffer, srcBuffer,
2582                     cmp.sizeCompImgs[mipLevel],
2583                     dstImageLayout, 1, &dstRegion);
2584         }
2585     }
2586 
convertQueueFamilyForeignToExternal(uint32_t * queueFamilyIndexPtr)2587     inline void convertQueueFamilyForeignToExternal(uint32_t* queueFamilyIndexPtr) {
2588         if (*queueFamilyIndexPtr == VK_QUEUE_FAMILY_FOREIGN_EXT) {
2589             *queueFamilyIndexPtr = VK_QUEUE_FAMILY_EXTERNAL;
2590         }
2591     }
2592 
convertQueueFamilyForeignToExternal_VkBufferMemoryBarrier(VkBufferMemoryBarrier * barrier)2593     inline void convertQueueFamilyForeignToExternal_VkBufferMemoryBarrier(VkBufferMemoryBarrier* barrier) {
2594         convertQueueFamilyForeignToExternal(&barrier->srcQueueFamilyIndex);
2595         convertQueueFamilyForeignToExternal(&barrier->dstQueueFamilyIndex);
2596     }
2597 
convertQueueFamilyForeignToExternal_VkImageMemoryBarrier(VkImageMemoryBarrier * barrier)2598     inline void convertQueueFamilyForeignToExternal_VkImageMemoryBarrier(VkImageMemoryBarrier* barrier) {
2599         convertQueueFamilyForeignToExternal(&barrier->srcQueueFamilyIndex);
2600         convertQueueFamilyForeignToExternal(&barrier->dstQueueFamilyIndex);
2601     }
2602 
on_vkCmdPipelineBarrier(android::base::BumpPool * pool,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)2603     void on_vkCmdPipelineBarrier(
2604             android::base::BumpPool* pool,
2605             VkCommandBuffer boxed_commandBuffer,
2606             VkPipelineStageFlags srcStageMask,
2607             VkPipelineStageFlags dstStageMask,
2608             VkDependencyFlags dependencyFlags,
2609             uint32_t memoryBarrierCount,
2610             const VkMemoryBarrier* pMemoryBarriers,
2611             uint32_t bufferMemoryBarrierCount,
2612             const VkBufferMemoryBarrier* pBufferMemoryBarriers,
2613             uint32_t imageMemoryBarrierCount,
2614             const VkImageMemoryBarrier* pImageMemoryBarriers) {
2615 
2616         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
2617         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
2618 
2619         for (uint32_t i = 0; i < bufferMemoryBarrierCount; ++i) {
2620             convertQueueFamilyForeignToExternal_VkBufferMemoryBarrier(
2621                 ((VkBufferMemoryBarrier*)pBufferMemoryBarriers) + i);
2622         }
2623 
2624         for (uint32_t i = 0; i < imageMemoryBarrierCount; ++i) {
2625             convertQueueFamilyForeignToExternal_VkImageMemoryBarrier(
2626                 ((VkImageMemoryBarrier*)pImageMemoryBarriers) + i);
2627         }
2628 
2629         if (imageMemoryBarrierCount == 0) {
2630             vk->vkCmdPipelineBarrier(
2631                     commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
2632                     memoryBarrierCount, pMemoryBarriers,
2633                     bufferMemoryBarrierCount, pBufferMemoryBarriers,
2634                     imageMemoryBarrierCount, pImageMemoryBarriers);
2635             return;
2636         }
2637         AutoLock lock(mLock);
2638         auto cmdBufferInfoIt = mCmdBufferInfo.find(commandBuffer);
2639         if (cmdBufferInfoIt == mCmdBufferInfo.end()) {
2640             return;
2641         }
2642         auto deviceInfoIt = mDeviceInfo.find(cmdBufferInfoIt->second.device);
2643         if (deviceInfoIt == mDeviceInfo.end()) {
2644             return;
2645         }
2646         if (!deviceInfoIt->second.emulateTextureEtc2 &&
2647             !deviceInfoIt->second.emulateTextureAstc) {
2648             vk->vkCmdPipelineBarrier(
2649                     commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
2650                     memoryBarrierCount, pMemoryBarriers,
2651                     bufferMemoryBarrierCount, pBufferMemoryBarriers,
2652                     imageMemoryBarrierCount, pImageMemoryBarriers);
2653             return;
2654         }
2655         // Add barrier for decompressed image
2656         std::vector<VkImageMemoryBarrier> persistentImageBarriers;
2657         bool needRebind = false;
2658         for (uint32_t i = 0; i < imageMemoryBarrierCount; i++) {
2659             const VkImageMemoryBarrier& srcBarrier = pImageMemoryBarriers[i];
2660             auto image = srcBarrier.image;
2661             auto it = mImageInfo.find(image);
2662             if (it == mImageInfo.end() ||
2663                 !deviceInfoIt->second.needEmulatedDecompression(
2664                         it->second.cmpInfo)) {
2665                 persistentImageBarriers.push_back(srcBarrier);
2666                 continue;
2667             }
2668             uint32_t baseMipLevel = srcBarrier.subresourceRange.baseMipLevel;
2669             uint32_t levelCount = srcBarrier.subresourceRange.levelCount;
2670             VkImageMemoryBarrier decompBarrier = srcBarrier;
2671             decompBarrier.image = it->second.cmpInfo.decompImg;
2672             VkImageMemoryBarrier sizeCompBarrierTemplate = srcBarrier;
2673             sizeCompBarrierTemplate.subresourceRange.baseMipLevel = 0;
2674             sizeCompBarrierTemplate.subresourceRange.levelCount = 1;
2675             std::vector<VkImageMemoryBarrier> sizeCompBarriers(
2676                     srcBarrier.subresourceRange.levelCount,
2677                     sizeCompBarrierTemplate);
2678             for (uint32_t j = 0; j < levelCount; j++) {
2679                 sizeCompBarriers[j].image =
2680                     it->second.cmpInfo.sizeCompImgs[baseMipLevel + j];
2681             }
2682 
2683             // TODO: should we use image layout or access bit?
2684             if (srcBarrier.oldLayout == 0 ||
2685                     (srcBarrier.newLayout != VK_IMAGE_LAYOUT_GENERAL &&
2686                      srcBarrier.newLayout !=
2687                      VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)) {
2688                 // TODO: might only need to push one of them?
2689                 persistentImageBarriers.push_back(decompBarrier);
2690                 persistentImageBarriers.insert(persistentImageBarriers.end(),
2691                         sizeCompBarriers.begin(),
2692                         sizeCompBarriers.end());
2693                 continue;
2694             }
2695             if (srcBarrier.newLayout !=
2696                     VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL &&
2697                     srcBarrier.newLayout != VK_IMAGE_LAYOUT_GENERAL) {
2698                 fprintf(stderr,
2699                         "WARNING: unexpected usage to transfer "
2700                         "compressed image layout from %d to %d\n",
2701                         srcBarrier.oldLayout, srcBarrier.newLayout);
2702             }
2703 
2704             VkResult result = it->second.cmpInfo.initDecomp(
2705                     vk, cmdBufferInfoIt->second.device, image);
2706             if (result != VK_SUCCESS) {
2707                 fprintf(stderr, "WARNING: texture decompression failed\n");
2708                 continue;
2709             }
2710 
2711             std::vector<VkImageMemoryBarrier> currImageBarriers;
2712             currImageBarriers.reserve(sizeCompBarriers.size() + 1);
2713             currImageBarriers.insert(currImageBarriers.end(),
2714                     sizeCompBarriers.begin(),
2715                     sizeCompBarriers.end());
2716             for (auto& barrier : currImageBarriers) {
2717                 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
2718                 barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
2719             }
2720             currImageBarriers.push_back(decompBarrier);
2721             {
2722                 VkImageMemoryBarrier& barrier = currImageBarriers[levelCount];
2723                 barrier.srcAccessMask = 0;
2724                 barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
2725                 barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2726                 barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
2727             }
2728             vk->vkCmdPipelineBarrier(commandBuffer, srcStageMask,
2729                     VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0,
2730                     nullptr, 0, nullptr,
2731                     currImageBarriers.size(),
2732                     currImageBarriers.data());
2733             it->second.cmpInfo.cmdDecompress(
2734                     vk, commandBuffer, dstStageMask, decompBarrier.newLayout,
2735                     decompBarrier.dstAccessMask, baseMipLevel, levelCount,
2736                     srcBarrier.subresourceRange.baseArrayLayer,
2737                     srcBarrier.subresourceRange.layerCount);
2738             needRebind = true;
2739 
2740             for (uint32_t j = 0; j < currImageBarriers.size(); j++) {
2741                 VkImageMemoryBarrier& barrier = currImageBarriers[j];
2742                 barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
2743                 barrier.dstAccessMask = srcBarrier.dstAccessMask;
2744                 barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
2745                 barrier.newLayout = srcBarrier.newLayout;
2746             }
2747             {
2748                 VkImageMemoryBarrier& barrier = currImageBarriers[levelCount];
2749                 barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
2750                 barrier.dstAccessMask = srcBarrier.dstAccessMask;
2751                 barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
2752                 barrier.newLayout = srcBarrier.newLayout;
2753             }
2754 
2755             vk->vkCmdPipelineBarrier(
2756                     commandBuffer,
2757                     VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,  // srcStageMask
2758                     dstStageMask,                          // dstStageMask
2759                     0,                                     // dependencyFlags
2760                     0,                                     // memoryBarrierCount
2761                     nullptr,                               // pMemoryBarriers
2762                     0,                         // bufferMemoryBarrierCount
2763                     nullptr,                   // pBufferMemoryBarriers
2764                     currImageBarriers.size(),  // imageMemoryBarrierCount
2765                     currImageBarriers.data()   // pImageMemoryBarriers
2766                     );
2767         }
2768         if (needRebind && cmdBufferInfoIt->second.computePipeline) {
2769             // Recover pipeline bindings
2770             vk->vkCmdBindPipeline(commandBuffer,
2771                     VK_PIPELINE_BIND_POINT_COMPUTE,
2772                     cmdBufferInfoIt->second.computePipeline);
2773             if (cmdBufferInfoIt->second.descriptorSets.size() > 0) {
2774                 vk->vkCmdBindDescriptorSets(
2775                         commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE,
2776                         cmdBufferInfoIt->second.descriptorLayout,
2777                         cmdBufferInfoIt->second.firstSet,
2778                         cmdBufferInfoIt->second.descriptorSets.size(),
2779                         cmdBufferInfoIt->second.descriptorSets.data(), 0,
2780                         nullptr);
2781             }
2782         }
2783         if (memoryBarrierCount || bufferMemoryBarrierCount ||
2784                 !persistentImageBarriers.empty()) {
2785             vk->vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask,
2786                     dependencyFlags, memoryBarrierCount,
2787                     pMemoryBarriers, bufferMemoryBarrierCount,
2788                     pBufferMemoryBarriers,
2789                     persistentImageBarriers.size(),
2790                     persistentImageBarriers.data());
2791         }
2792     }
2793 
mapHostVisibleMemoryToGuestPhysicalAddressLocked(VulkanDispatch * vk,VkDevice device,VkDeviceMemory memory,uint64_t physAddr)2794     bool mapHostVisibleMemoryToGuestPhysicalAddressLocked(
2795             VulkanDispatch* vk,
2796             VkDevice device,
2797             VkDeviceMemory memory,
2798             uint64_t physAddr) {
2799 
2800         if (!feature_is_enabled(kFeature_GLDirectMem) &&
2801             !feature_is_enabled(kFeature_VirtioGpuNext)) {
2802             // fprintf(stderr, "%s: Tried to use direct mapping "
2803                     // "while GLDirectMem is not enabled!\n");
2804         }
2805 
2806         auto info = android::base::find(mMapInfo, memory);
2807 
2808         if (!info) return false;
2809 
2810         info->guestPhysAddr = physAddr;
2811 
2812         constexpr size_t kPageBits = 12;
2813         constexpr size_t kPageSize = 1u << kPageBits;
2814         constexpr size_t kPageOffsetMask = kPageSize - 1;
2815 
2816         uintptr_t addr = reinterpret_cast<uintptr_t>(info->ptr);
2817         uintptr_t pageOffset = addr & kPageOffsetMask;
2818 
2819         info->pageAlignedHva =
2820             reinterpret_cast<void*>(addr - pageOffset);
2821         info->sizeToPage =
2822             ((info->size + pageOffset + kPageSize - 1) >>
2823              kPageBits) << kPageBits;
2824 
2825         if (mLogging) {
2826             fprintf(stderr, "%s: map: %p, %p -> [0x%llx 0x%llx]\n", __func__,
2827                     info->ptr,
2828                     info->pageAlignedHva,
2829                     (unsigned long long)info->guestPhysAddr,
2830                     (unsigned long long)info->guestPhysAddr + info->sizeToPage);
2831         }
2832 
2833         info->directMapped = true;
2834         uint64_t gpa = info->guestPhysAddr;
2835         void* hva = info->pageAlignedHva;
2836         size_t sizeToPage = info->sizeToPage;
2837 
2838         AutoLock occupiedGpasLock(mOccupiedGpasLock);
2839 
2840         auto existingMemoryInfo =
2841             android::base::find(mOccupiedGpas, gpa);
2842 
2843         if (existingMemoryInfo) {
2844 
2845             fprintf(stderr, "%s: WARNING: already mapped gpa 0x%llx, replacing",
2846                     __func__,
2847                     (unsigned long long)gpa);
2848 
2849             get_emugl_vm_operations().unmapUserBackedRam(
2850                 existingMemoryInfo->gpa,
2851                 existingMemoryInfo->sizeToPage);
2852 
2853             mOccupiedGpas.erase(gpa);
2854         }
2855 
2856         get_emugl_vm_operations().mapUserBackedRam(
2857             gpa, hva, sizeToPage);
2858 
2859         if (mVerbosePrints) {
2860             fprintf(stderr, "VERBOSE:%s: registering gpa 0x%llx to mOccupiedGpas\n", __func__,
2861                     (unsigned long long)gpa);
2862         }
2863 
2864         mOccupiedGpas[gpa] = {
2865             vk,
2866             device,
2867             memory,
2868             gpa,
2869             sizeToPage,
2870         };
2871 
2872         if (!mUseOldMemoryCleanupPath) {
2873             get_emugl_address_space_device_control_ops().register_deallocation_callback(
2874                 this, gpa, [](void* thisPtr, uint64_t gpa) {
2875                 Impl* implPtr = (Impl*)thisPtr;
2876                 implPtr->unmapMemoryAtGpaIfExists(gpa);
2877             });
2878         }
2879 
2880         return true;
2881     }
2882 
2883     // Only call this from the address space device deallocation operation's
2884     // context, or it's possible that the guest/host view of which gpa's are
2885     // occupied goes out of sync.
unmapMemoryAtGpaIfExists(uint64_t gpa)2886     void unmapMemoryAtGpaIfExists(uint64_t gpa) {
2887         AutoLock lock(mOccupiedGpasLock);
2888 
2889         if (mVerbosePrints) {
2890             fprintf(stderr, "VERBOSE:%s: deallocation callback for gpa 0x%llx\n", __func__,
2891                     (unsigned long long)gpa);
2892         }
2893 
2894         auto existingMemoryInfo =
2895             android::base::find(mOccupiedGpas, gpa);
2896 
2897         if (!existingMemoryInfo) return;
2898 
2899         get_emugl_vm_operations().unmapUserBackedRam(
2900             existingMemoryInfo->gpa,
2901             existingMemoryInfo->sizeToPage);
2902 
2903         mOccupiedGpas.erase(gpa);
2904     }
2905 
on_vkAllocateMemory(android::base::BumpPool * pool,VkDevice boxed_device,const VkMemoryAllocateInfo * pAllocateInfo,const VkAllocationCallbacks * pAllocator,VkDeviceMemory * pMemory)2906     VkResult on_vkAllocateMemory(
2907             android::base::BumpPool* pool,
2908             VkDevice boxed_device,
2909             const VkMemoryAllocateInfo* pAllocateInfo,
2910             const VkAllocationCallbacks* pAllocator,
2911             VkDeviceMemory* pMemory) {
2912 
2913         auto device = unbox_VkDevice(boxed_device);
2914         auto vk = dispatch_VkDevice(boxed_device);
2915 
2916         if (!pAllocateInfo) return VK_ERROR_INITIALIZATION_FAILED;
2917 
2918         VkMemoryAllocateInfo localAllocInfo = vk_make_orphan_copy(*pAllocateInfo);
2919         vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&localAllocInfo);
2920 
2921         // handle type should already be converted in unmarshaling
2922         const VkExportMemoryAllocateInfo* exportAllocInfoPtr =
2923             vk_find_struct<VkExportMemoryAllocateInfo>(pAllocateInfo);
2924 
2925         if (exportAllocInfoPtr) {
2926             fprintf(stderr,
2927                     "%s: Fatal: Export allocs are to be handled "
2928                     "on the guest side / VkCommonOperations.\n",
2929                     __func__);
2930             abort();
2931         }
2932 
2933         const VkMemoryDedicatedAllocateInfo* dedicatedAllocInfoPtr =
2934             vk_find_struct<VkMemoryDedicatedAllocateInfo>(pAllocateInfo);
2935         VkMemoryDedicatedAllocateInfo localDedicatedAllocInfo;
2936 
2937         if (dedicatedAllocInfoPtr) {
2938             localDedicatedAllocInfo = vk_make_orphan_copy(*dedicatedAllocInfoPtr);
2939             vk_append_struct(&structChainIter, &localDedicatedAllocInfo);
2940         }
2941 
2942         const VkImportPhysicalAddressGOOGLE* importPhysAddrInfoPtr =
2943             vk_find_struct<VkImportPhysicalAddressGOOGLE>(pAllocateInfo);
2944 
2945         if (importPhysAddrInfoPtr) {
2946             // TODO: Implement what happens on importing a physical address:
2947             // 1 - perform action of vkMapMemoryIntoAddressSpaceGOOGLE if
2948             //     host visible
2949             // 2 - create color buffer, setup Vk for it,
2950             //     and associate it with the physical address
2951         }
2952 
2953         const VkImportColorBufferGOOGLE* importCbInfoPtr =
2954             vk_find_struct<VkImportColorBufferGOOGLE>(pAllocateInfo);
2955         const VkImportBufferGOOGLE* importBufferInfoPtr =
2956                 vk_find_struct<VkImportBufferGOOGLE>(pAllocateInfo);
2957 
2958 #ifdef _WIN32
2959         VkImportMemoryWin32HandleInfoKHR importInfo {
2960             VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR, 0,
2961                 VK_EXT_MEMORY_HANDLE_TYPE_BIT,
2962                 VK_EXT_MEMORY_HANDLE_INVALID, L"",
2963         };
2964 #else
2965         VkImportMemoryFdInfoKHR importInfo {
2966             VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, 0,
2967                 VK_EXT_MEMORY_HANDLE_TYPE_BIT,
2968                 VK_EXT_MEMORY_HANDLE_INVALID,
2969         };
2970 #endif
2971 
2972         AutoLock lock(mLock);
2973 
2974         auto physdev = android::base::find(mDeviceToPhysicalDevice, device);
2975 
2976         if (!physdev) {
2977             // User app gave an invalid VkDevice,
2978             // but we don't really want to crash here.
2979             // We should allow invalid apps.
2980             return VK_ERROR_DEVICE_LOST;
2981         }
2982 
2983         auto physdevInfo = android::base::find(mPhysdevInfo, *physdev);
2984 
2985         if (!physdevInfo) {
2986             // If this fails, we crash, as we assume that the memory properties
2987             // map should have the info.
2988             fprintf(stderr, "Error: Could not get memory properties for VkPhysicalDevice\n");
2989         }
2990 
2991         // If the memory was allocated with a type index that corresponds
2992         // to a memory type that is host visible, let's also map the entire
2993         // thing.
2994 
2995         // First, check validity of the user's type index.
2996         if (localAllocInfo.memoryTypeIndex >=
2997             physdevInfo->memoryProperties.memoryTypeCount) {
2998             // Continue allowing invalid behavior.
2999             return VK_ERROR_INCOMPATIBLE_DRIVER;
3000         }
3001 
3002         VkMemoryPropertyFlags memoryPropertyFlags =
3003                 physdevInfo->memoryProperties
3004                         .memoryTypes[localAllocInfo.memoryTypeIndex]
3005                         .propertyFlags;
3006 
3007         lock.unlock();
3008 
3009         void* mappedPtr = nullptr;
3010         if (importCbInfoPtr) {
3011             bool vulkanOnly = mGuestUsesAngle;
3012 
3013             // Ensure color buffer has Vulkan backing.
3014             setupVkColorBuffer(importCbInfoPtr->colorBuffer,
3015                                vulkanOnly,
3016                                0u /* memoryProperty */, nullptr,
3017                                // Modify the allocation size and type index
3018                                // to suit the resulting image memory size.
3019                                &localAllocInfo.allocationSize,
3020                                &localAllocInfo.memoryTypeIndex, &mappedPtr);
3021 
3022             if (!vulkanOnly) {
3023                 updateVkImageFromColorBuffer(importCbInfoPtr->colorBuffer);
3024             }
3025 
3026             if (m_emu->instanceSupportsExternalMemoryCapabilities) {
3027                 VK_EXT_MEMORY_HANDLE cbExtMemoryHandle =
3028                     getColorBufferExtMemoryHandle(importCbInfoPtr->colorBuffer);
3029 
3030                 if (cbExtMemoryHandle == VK_EXT_MEMORY_HANDLE_INVALID) {
3031                     fprintf(stderr,
3032                             "%s: VK_ERROR_OUT_OF_DEVICE_MEMORY: "
3033                             "colorBuffer 0x%x does not have Vulkan external memory backing\n", __func__,
3034                             importCbInfoPtr->colorBuffer);
3035                     return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3036                 }
3037 
3038                 cbExtMemoryHandle = dupExternalMemory(cbExtMemoryHandle);
3039 
3040 #ifdef _WIN32
3041                 importInfo.handle = cbExtMemoryHandle;
3042 #else
3043                 importInfo.fd = cbExtMemoryHandle;
3044 #endif
3045                 vk_append_struct(&structChainIter, &importInfo);
3046             }
3047         }
3048 
3049         if (importBufferInfoPtr) {
3050             // Ensure buffer has Vulkan backing.
3051             setupVkBuffer(importBufferInfoPtr->buffer,
3052                           true /* Buffers are Vulkan only */,
3053                           0u /* memoryProperty */, nullptr,
3054                           // Modify the allocation size and type index
3055                           // to suit the resulting image memory size.
3056                           &localAllocInfo.allocationSize,
3057                           &localAllocInfo.memoryTypeIndex);
3058 
3059             if (m_emu->instanceSupportsExternalMemoryCapabilities) {
3060                 VK_EXT_MEMORY_HANDLE bufferExtMemoryHandle =
3061                         getBufferExtMemoryHandle(importBufferInfoPtr->buffer);
3062 
3063                 if (bufferExtMemoryHandle == VK_EXT_MEMORY_HANDLE_INVALID) {
3064                     fprintf(stderr,
3065                             "%s: VK_ERROR_OUT_OF_DEVICE_MEMORY: "
3066                             "buffer 0x%x does not have Vulkan external memory "
3067                             "backing\n",
3068                             __func__, importBufferInfoPtr->buffer);
3069                     return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3070                 }
3071 
3072                 bufferExtMemoryHandle =
3073                         dupExternalMemory(bufferExtMemoryHandle);
3074 
3075 #ifdef _WIN32
3076                 importInfo.handle = bufferExtMemoryHandle;
3077 #else
3078                 importInfo.fd = bufferExtMemoryHandle;
3079 #endif
3080                 vk_append_struct(&structChainIter, &importInfo);
3081             }
3082         }
3083 
3084         VkResult result =
3085             vk->vkAllocateMemory(device, &localAllocInfo, pAllocator, pMemory);
3086 
3087         if (result != VK_SUCCESS) {
3088             return result;
3089         }
3090 
3091         lock.lock();
3092 
3093         mMapInfo[*pMemory] = MappedMemoryInfo();
3094         auto& mapInfo = mMapInfo[*pMemory];
3095         mapInfo.size = localAllocInfo.allocationSize;
3096         mapInfo.device = device;
3097         if (importCbInfoPtr && m_emu->instanceSupportsMoltenVK) {
3098             mapInfo.mtlTexture = getColorBufferMTLTexture(importCbInfoPtr->colorBuffer);
3099         }
3100 
3101         bool hostVisible =
3102                 memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
3103 
3104         if (!hostVisible) {
3105             *pMemory = new_boxed_non_dispatchable_VkDeviceMemory(*pMemory);
3106             return result;
3107         }
3108 
3109         if (mappedPtr) {
3110             mapInfo.needUnmap = false;
3111             mapInfo.ptr = mappedPtr;
3112         } else {
3113             mapInfo.needUnmap = true;
3114             VkResult mapResult = vk->vkMapMemory(device, *pMemory, 0,
3115                                                  mapInfo.size, 0, &mapInfo.ptr);
3116             if (mapResult != VK_SUCCESS) {
3117                 return VK_ERROR_OUT_OF_HOST_MEMORY;
3118             }
3119         }
3120 
3121         *pMemory = new_boxed_non_dispatchable_VkDeviceMemory(*pMemory);
3122 
3123         return result;
3124     }
3125 
freeMemoryLocked(VulkanDispatch * vk,VkDevice device,VkDeviceMemory memory,const VkAllocationCallbacks * pAllocator)3126     void freeMemoryLocked(
3127             VulkanDispatch* vk,
3128             VkDevice device,
3129             VkDeviceMemory memory,
3130             const VkAllocationCallbacks* pAllocator) {
3131 
3132         auto info = android::base::find(mMapInfo, memory);
3133 
3134         if (!info) {
3135             // Invalid usage.
3136             return;
3137         }
3138 
3139 #ifdef __APPLE__
3140         if (info->mtlTexture) {
3141             CFRelease(info->mtlTexture);
3142             info->mtlTexture = nullptr;
3143         }
3144 #endif
3145 
3146         if (info->directMapped) {
3147 
3148             // if direct mapped, we leave it up to the guest address space driver
3149             // to control the unmapping of kvm slot on the host side
3150             // in order to avoid situations where
3151             //
3152             // 1. we try to unmap here and deadlock
3153             //
3154             // 2. unmapping at the wrong time (possibility of a parallel call
3155             // to unmap vs. address space allocate and mapMemory leading to
3156             // mapping the same gpa twice)
3157             if (mUseOldMemoryCleanupPath) {
3158                 unmapMemoryAtGpaIfExists(info->guestPhysAddr);
3159             }
3160         }
3161 
3162         if (info->virtioGpuMapped) {
3163             if (mLogging) {
3164                 fprintf(stderr, "%s: unmap hostmem %p id 0x%llx\n", __func__,
3165                         info->ptr,
3166                         (unsigned long long)info->hostmemId);
3167             }
3168 
3169             get_emugl_vm_operations().hostmemUnregister(info->hostmemId);
3170         }
3171 
3172         if (info->needUnmap && info->ptr) {
3173             vk->vkUnmapMemory(device, memory);
3174         }
3175 
3176         vk->vkFreeMemory(device, memory, pAllocator);
3177 
3178         mMapInfo.erase(memory);
3179     }
3180 
on_vkFreeMemory(android::base::BumpPool * pool,VkDevice boxed_device,VkDeviceMemory memory,const VkAllocationCallbacks * pAllocator)3181     void on_vkFreeMemory(
3182             android::base::BumpPool* pool,
3183             VkDevice boxed_device,
3184             VkDeviceMemory memory,
3185             const VkAllocationCallbacks* pAllocator) {
3186 
3187         auto device = unbox_VkDevice(boxed_device);
3188         auto vk = dispatch_VkDevice(boxed_device);
3189 
3190         AutoLock lock(mLock);
3191 
3192         freeMemoryLocked(vk, device, memory, pAllocator);
3193     }
3194 
on_vkMapMemory(android::base::BumpPool * pool,VkDevice,VkDeviceMemory memory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)3195     VkResult on_vkMapMemory(
3196             android::base::BumpPool* pool,
3197             VkDevice,
3198             VkDeviceMemory memory,
3199             VkDeviceSize offset,
3200             VkDeviceSize size,
3201             VkMemoryMapFlags flags,
3202             void** ppData) {
3203 
3204         AutoLock lock(mLock);
3205         return on_vkMapMemoryLocked(0, memory, offset, size, flags, ppData);
3206     }
on_vkMapMemoryLocked(VkDevice,VkDeviceMemory memory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)3207     VkResult on_vkMapMemoryLocked(VkDevice,
3208             VkDeviceMemory memory,
3209             VkDeviceSize offset,
3210             VkDeviceSize size,
3211             VkMemoryMapFlags flags,
3212             void** ppData) {
3213         auto info = android::base::find(mMapInfo, memory);
3214 
3215         if (!info) {
3216             // Invalid usage.
3217             return VK_ERROR_MEMORY_MAP_FAILED;
3218         }
3219 
3220         if (!info->ptr) {
3221             return VK_ERROR_MEMORY_MAP_FAILED;
3222         }
3223 
3224         *ppData = (void*)((uint8_t*)info->ptr + offset);
3225 
3226         return VK_SUCCESS;
3227     }
3228 
on_vkUnmapMemory(android::base::BumpPool * pool,VkDevice,VkDeviceMemory)3229     void on_vkUnmapMemory(
3230             android::base::BumpPool* pool,
3231             VkDevice, VkDeviceMemory) {
3232         // no-op; user-level mapping does not correspond
3233         // to any operation here.
3234     }
3235 
getMappedHostPointer(VkDeviceMemory memory)3236     uint8_t* getMappedHostPointer(VkDeviceMemory memory) {
3237         AutoLock lock(mLock);
3238 
3239         auto info = android::base::find(mMapInfo, memory);
3240 
3241         if (!info) {
3242             // Invalid usage.
3243             return nullptr;
3244         }
3245 
3246         return (uint8_t*)(info->ptr);
3247     }
3248 
getDeviceMemorySize(VkDeviceMemory memory)3249     VkDeviceSize getDeviceMemorySize(VkDeviceMemory memory) {
3250         AutoLock lock(mLock);
3251 
3252         auto info = android::base::find(mMapInfo, memory);
3253 
3254         if (!info) {
3255             // Invalid usage.
3256             return 0;
3257         }
3258 
3259         return info->size;
3260     }
3261 
usingDirectMapping() const3262     bool usingDirectMapping() const {
3263         return feature_is_enabled(kFeature_GLDirectMem) ||
3264                feature_is_enabled(kFeature_VirtioGpuNext);
3265     }
3266 
getHostFeatureSupport() const3267     HostFeatureSupport getHostFeatureSupport() const {
3268         HostFeatureSupport res;
3269 
3270         if (!m_vk) return res;
3271 
3272         auto emu = getGlobalVkEmulation();
3273 
3274         res.supportsVulkan = emu && emu->live;
3275 
3276         if (!res.supportsVulkan) return res;
3277 
3278         const auto& props = emu->deviceInfo.physdevProps;
3279 
3280         res.supportsVulkan1_1 =
3281             props.apiVersion >= VK_API_VERSION_1_1;
3282         res.supportsExternalMemory =
3283             emu->deviceInfo.supportsExternalMemory;
3284         res.useDeferredCommands =
3285             emu->useDeferredCommands;
3286         res.useCreateResourcesWithRequirements =
3287             emu->useCreateResourcesWithRequirements;
3288 
3289         res.apiVersion = props.apiVersion;
3290         res.driverVersion = props.driverVersion;
3291         res.deviceID = props.deviceID;
3292         res.vendorID = props.vendorID;
3293         return res;
3294     }
3295 
hasInstanceExtension(VkInstance instance,const std::string & name)3296     bool hasInstanceExtension(VkInstance instance, const std::string& name) {
3297         auto info = android::base::find(mInstanceInfo, instance);
3298         if (!info) return false;
3299 
3300         for (const auto& enabledName : info->enabledExtensionNames) {
3301             if (name == enabledName) return true;
3302         }
3303 
3304         return false;
3305     }
3306 
hasDeviceExtension(VkDevice device,const std::string & name)3307     bool hasDeviceExtension(VkDevice device, const std::string& name) {
3308         auto info = android::base::find(mDeviceInfo, device);
3309         if (!info) return false;
3310 
3311         for (const auto& enabledName : info->enabledExtensionNames) {
3312             if (name == enabledName) return true;
3313         }
3314 
3315         return false;
3316     }
3317 
3318     // VK_ANDROID_native_buffer
on_vkGetSwapchainGrallocUsageANDROID(android::base::BumpPool * pool,VkDevice,VkFormat format,VkImageUsageFlags imageUsage,int * grallocUsage)3319     VkResult on_vkGetSwapchainGrallocUsageANDROID(
3320             android::base::BumpPool* pool,
3321             VkDevice,
3322             VkFormat format,
3323             VkImageUsageFlags imageUsage,
3324             int* grallocUsage) {
3325         getGralloc0Usage(format, imageUsage, grallocUsage);
3326         return VK_SUCCESS;
3327     }
3328 
on_vkGetSwapchainGrallocUsage2ANDROID(android::base::BumpPool * pool,VkDevice,VkFormat format,VkImageUsageFlags imageUsage,VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,uint64_t * grallocConsumerUsage,uint64_t * grallocProducerUsage)3329     VkResult on_vkGetSwapchainGrallocUsage2ANDROID(
3330             android::base::BumpPool* pool,
3331             VkDevice,
3332             VkFormat format,
3333             VkImageUsageFlags imageUsage,
3334             VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
3335             uint64_t* grallocConsumerUsage,
3336             uint64_t* grallocProducerUsage) {
3337         getGralloc1Usage(format, imageUsage, swapchainImageUsage,
3338                 grallocConsumerUsage,
3339                 grallocProducerUsage);
3340         return VK_SUCCESS;
3341     }
3342 
on_vkAcquireImageANDROID(android::base::BumpPool * pool,VkDevice boxed_device,VkImage image,int nativeFenceFd,VkSemaphore semaphore,VkFence fence)3343     VkResult on_vkAcquireImageANDROID(
3344             android::base::BumpPool* pool,
3345             VkDevice boxed_device,
3346             VkImage image,
3347             int nativeFenceFd,
3348             VkSemaphore semaphore,
3349             VkFence fence) {
3350 
3351         auto device = unbox_VkDevice(boxed_device);
3352         auto vk = dispatch_VkDevice(boxed_device);
3353 
3354         AutoLock lock(mLock);
3355 
3356         auto imageInfo = android::base::find(mImageInfo, image);
3357         if (!imageInfo) {
3358             return VK_ERROR_INITIALIZATION_FAILED;
3359         }
3360 
3361         VkQueue defaultQueue;
3362         uint32_t defaultQueueFamilyIndex;
3363         if (!getDefaultQueueForDeviceLocked(
3364                     device, &defaultQueue, &defaultQueueFamilyIndex)) {
3365             fprintf(stderr, "%s: cant get the default q\n", __func__);
3366             return VK_ERROR_INITIALIZATION_FAILED;
3367         }
3368 
3369         AndroidNativeBufferInfo* anbInfo = &imageInfo->anbInfo;
3370 
3371         return
3372             setAndroidNativeImageSemaphoreSignaled(
3373                     vk, device,
3374                     defaultQueue, defaultQueueFamilyIndex,
3375                     semaphore, fence, anbInfo);
3376     }
3377 
on_vkQueueSignalReleaseImageANDROID(android::base::BumpPool * pool,VkQueue boxed_queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image,int * pNativeFenceFd)3378     VkResult on_vkQueueSignalReleaseImageANDROID(
3379             android::base::BumpPool* pool,
3380             VkQueue boxed_queue,
3381             uint32_t waitSemaphoreCount,
3382             const VkSemaphore* pWaitSemaphores,
3383             VkImage image,
3384             int* pNativeFenceFd) {
3385 
3386         auto queue = unbox_VkQueue(boxed_queue);
3387         auto vk = dispatch_VkQueue(boxed_queue);
3388 
3389         AutoLock lock(mLock);
3390 
3391         auto queueFamilyIndex = queueFamilyIndexOfQueueLocked(queue);
3392 
3393         if (!queueFamilyIndex) {
3394             return VK_ERROR_INITIALIZATION_FAILED;
3395         }
3396 
3397         auto imageInfo = android::base::find(mImageInfo, image);
3398         AndroidNativeBufferInfo* anbInfo = &imageInfo->anbInfo;
3399 
3400         return
3401             syncImageToColorBuffer(
3402                     vk,
3403                     *queueFamilyIndex,
3404                     queue,
3405                     waitSemaphoreCount, pWaitSemaphores,
3406                     pNativeFenceFd, anbInfo);
3407     }
3408 
on_vkMapMemoryIntoAddressSpaceGOOGLE(android::base::BumpPool * pool,VkDevice boxed_device,VkDeviceMemory memory,uint64_t * pAddress)3409     VkResult on_vkMapMemoryIntoAddressSpaceGOOGLE(
3410             android::base::BumpPool* pool,
3411             VkDevice boxed_device, VkDeviceMemory memory, uint64_t* pAddress) {
3412 
3413         auto device = unbox_VkDevice(boxed_device);
3414         auto vk = dispatch_VkDevice(boxed_device);
3415 
3416         if (!feature_is_enabled(kFeature_GLDirectMem)) {
3417             fprintf(stderr, "FATAL: Tried to use direct mapping "
3418                     "while GLDirectMem is not enabled!\n");
3419         }
3420 
3421         AutoLock lock(mLock);
3422 
3423         auto info = android::base::find(mMapInfo, memory);
3424 
3425         if (mLogging) {
3426             fprintf(stderr, "%s: deviceMemory: 0x%llx pAddress: 0x%llx\n", __func__,
3427                     (unsigned long long)memory,
3428                     (unsigned long long)(*pAddress));
3429         }
3430 
3431         if (!mapHostVisibleMemoryToGuestPhysicalAddressLocked(
3432                     vk, device, memory, *pAddress)) {
3433             return VK_ERROR_OUT_OF_HOST_MEMORY;
3434         }
3435 
3436         if (!info) return VK_ERROR_INITIALIZATION_FAILED;
3437 
3438         *pAddress = (uint64_t)(uintptr_t)info->ptr;
3439 
3440         return VK_SUCCESS;
3441     }
3442 
on_vkGetMemoryHostAddressInfoGOOGLE(android::base::BumpPool * pool,VkDevice boxed_device,VkDeviceMemory memory,uint64_t * pAddress,uint64_t * pSize,uint64_t * pHostmemId)3443     VkResult on_vkGetMemoryHostAddressInfoGOOGLE(
3444             android::base::BumpPool* pool,
3445             VkDevice boxed_device, VkDeviceMemory memory,
3446             uint64_t* pAddress, uint64_t* pSize, uint64_t* pHostmemId) {
3447         AutoLock lock(mLock);
3448 
3449         auto info = android::base::find(mMapInfo, memory);
3450 
3451         if (!info) return VK_ERROR_OUT_OF_HOST_MEMORY;
3452 
3453         uint64_t hva = (uint64_t)(uintptr_t)(info->ptr);
3454         uint64_t size = (uint64_t)(uintptr_t)(info->size);
3455 
3456         constexpr size_t kPageBits = 12;
3457         constexpr size_t kPageSize = 1u << kPageBits;
3458         constexpr size_t kPageOffsetMask = kPageSize - 1;
3459 
3460         uint64_t pageOffset = hva & kPageOffsetMask;
3461         uint64_t sizeToPage =
3462             ((size + pageOffset + kPageSize - 1) >>
3463              kPageBits) << kPageBits;
3464 
3465         auto id =
3466             get_emugl_vm_operations().hostmemRegister(
3467                     (uint64_t)(uintptr_t)(info->ptr),
3468                     (uint64_t)(uintptr_t)(info->size),
3469                     // No fixed registration
3470                     false, 0);
3471 
3472         *pAddress = hva & (0xfff); // Don't expose exact hva to guest
3473         *pSize = sizeToPage;
3474         *pHostmemId = id;
3475 
3476         info->virtioGpuMapped = true;
3477         info->hostmemId = id;
3478 
3479         fprintf(stderr, "%s: hva, size, sizeToPage: %p 0x%llx 0x%llx id 0x%llx\n", __func__,
3480                 info->ptr, (unsigned long long)(info->size),
3481                 (unsigned long long)(sizeToPage),
3482                 (unsigned long long)(*pHostmemId));
3483         return VK_SUCCESS;
3484     }
3485 
on_vkFreeMemorySyncGOOGLE(android::base::BumpPool * pool,VkDevice boxed_device,VkDeviceMemory memory,const VkAllocationCallbacks * pAllocator)3486     VkResult on_vkFreeMemorySyncGOOGLE(
3487         android::base::BumpPool* pool,
3488         VkDevice boxed_device, VkDeviceMemory memory,
3489         const VkAllocationCallbacks* pAllocator) {
3490 
3491         on_vkFreeMemory(pool, boxed_device, memory, pAllocator);
3492 
3493         return VK_SUCCESS;
3494     }
3495 
3496 
on_vkRegisterImageColorBufferGOOGLE(android::base::BumpPool * pool,VkDevice device,VkImage image,uint32_t colorBuffer)3497     VkResult on_vkRegisterImageColorBufferGOOGLE(
3498             android::base::BumpPool* pool,
3499             VkDevice device, VkImage image, uint32_t colorBuffer) {
3500 
3501         (void)image;
3502 
3503         bool success = setupVkColorBuffer(colorBuffer);
3504 
3505         return success ? VK_SUCCESS : VK_ERROR_OUT_OF_DEVICE_MEMORY;
3506     }
3507 
on_vkRegisterBufferColorBufferGOOGLE(android::base::BumpPool * pool,VkDevice device,VkBuffer buffer,uint32_t colorBuffer)3508     VkResult on_vkRegisterBufferColorBufferGOOGLE(
3509             android::base::BumpPool* pool,
3510             VkDevice device, VkBuffer buffer, uint32_t colorBuffer) {
3511 
3512         (void)buffer;
3513 
3514         bool success = setupVkColorBuffer(colorBuffer);
3515 
3516         return success ? VK_SUCCESS : VK_ERROR_OUT_OF_DEVICE_MEMORY;
3517     }
3518 
on_vkAllocateCommandBuffers(android::base::BumpPool * pool,VkDevice boxed_device,const VkCommandBufferAllocateInfo * pAllocateInfo,VkCommandBuffer * pCommandBuffers)3519     VkResult on_vkAllocateCommandBuffers(
3520             android::base::BumpPool* pool,
3521             VkDevice boxed_device,
3522             const VkCommandBufferAllocateInfo* pAllocateInfo,
3523             VkCommandBuffer* pCommandBuffers) {
3524 
3525         auto device = unbox_VkDevice(boxed_device);
3526         auto vk = dispatch_VkDevice(boxed_device);
3527 
3528         VkResult result = vk->vkAllocateCommandBuffers(
3529                 device, pAllocateInfo, pCommandBuffers);
3530 
3531         if (result != VK_SUCCESS) {
3532             return result;
3533         }
3534 
3535         AutoLock lock(mLock);
3536         for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
3537             mCmdBufferInfo[pCommandBuffers[i]] = CommandBufferInfo();
3538             mCmdBufferInfo[pCommandBuffers[i]].device = device;
3539             mCmdBufferInfo[pCommandBuffers[i]].cmdPool =
3540                 pAllocateInfo->commandPool;
3541             auto boxed = new_boxed_VkCommandBuffer(pCommandBuffers[i], vk, false /* does not own dispatch */);
3542             mCmdBufferInfo[pCommandBuffers[i]].boxed = boxed;
3543             pCommandBuffers[i] = (VkCommandBuffer)boxed;
3544         }
3545         return result;
3546     }
3547 
on_vkCreateCommandPool(android::base::BumpPool * pool,VkDevice boxed_device,const VkCommandPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkCommandPool * pCommandPool)3548     VkResult on_vkCreateCommandPool(
3549             android::base::BumpPool* pool,
3550             VkDevice boxed_device,
3551             const VkCommandPoolCreateInfo* pCreateInfo,
3552             const VkAllocationCallbacks* pAllocator,
3553             VkCommandPool* pCommandPool) {
3554 
3555         auto device = unbox_VkDevice(boxed_device);
3556         auto vk = dispatch_VkDevice(boxed_device);
3557 
3558         VkResult result = vk->vkCreateCommandPool(device, pCreateInfo,
3559                 pAllocator, pCommandPool);
3560         if (result != VK_SUCCESS) {
3561             return result;
3562         }
3563         AutoLock lock(mLock);
3564         mCmdPoolInfo[*pCommandPool] = CommandPoolInfo();
3565         auto& cmdPoolInfo = mCmdPoolInfo[*pCommandPool];
3566         cmdPoolInfo.device = device;
3567 
3568         *pCommandPool = new_boxed_non_dispatchable_VkCommandPool(*pCommandPool);
3569         cmdPoolInfo.boxed = *pCommandPool;
3570 
3571         return result;
3572     }
3573 
on_vkDestroyCommandPool(android::base::BumpPool * pool,VkDevice boxed_device,VkCommandPool commandPool,const VkAllocationCallbacks * pAllocator)3574     void on_vkDestroyCommandPool(
3575             android::base::BumpPool* pool,
3576             VkDevice boxed_device,
3577             VkCommandPool commandPool,
3578             const VkAllocationCallbacks* pAllocator) {
3579 
3580         auto device = unbox_VkDevice(boxed_device);
3581         auto vk = dispatch_VkDevice(boxed_device);
3582 
3583         vk->vkDestroyCommandPool(device, commandPool, pAllocator);
3584         AutoLock lock(mLock);
3585         const auto ite = mCmdPoolInfo.find(commandPool);
3586         if (ite != mCmdPoolInfo.end()) {
3587             removeCommandBufferInfo(ite->second.cmdBuffers);
3588             mCmdPoolInfo.erase(ite);
3589         }
3590     }
3591 
on_vkResetCommandPool(android::base::BumpPool * pool,VkDevice boxed_device,VkCommandPool commandPool,VkCommandPoolResetFlags flags)3592     VkResult on_vkResetCommandPool(
3593             android::base::BumpPool* pool,
3594             VkDevice boxed_device,
3595             VkCommandPool commandPool,
3596             VkCommandPoolResetFlags flags) {
3597 
3598         auto device = unbox_VkDevice(boxed_device);
3599         auto vk = dispatch_VkDevice(boxed_device);
3600 
3601         VkResult result =
3602             vk->vkResetCommandPool(device, commandPool, flags);
3603         if (result != VK_SUCCESS) {
3604             return result;
3605         }
3606         return result;
3607     }
3608 
on_vkCmdExecuteCommands(android::base::BumpPool * pool,VkCommandBuffer boxed_commandBuffer,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)3609     void on_vkCmdExecuteCommands(
3610             android::base::BumpPool* pool,
3611             VkCommandBuffer boxed_commandBuffer,
3612             uint32_t commandBufferCount,
3613             const VkCommandBuffer* pCommandBuffers) {
3614 
3615         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
3616         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
3617 
3618         vk->vkCmdExecuteCommands(commandBuffer, commandBufferCount,
3619                 pCommandBuffers);
3620         AutoLock lock(mLock);
3621         CommandBufferInfo& cmdBuffer = mCmdBufferInfo[commandBuffer];
3622         cmdBuffer.subCmds.insert(cmdBuffer.subCmds.end(),
3623                 pCommandBuffers, pCommandBuffers + commandBufferCount);
3624     }
3625 
on_vkQueueSubmit(android::base::BumpPool * pool,VkQueue boxed_queue,uint32_t submitCount,const VkSubmitInfo * pSubmits,VkFence fence)3626     VkResult on_vkQueueSubmit(
3627             android::base::BumpPool* pool,
3628             VkQueue boxed_queue,
3629             uint32_t submitCount,
3630             const VkSubmitInfo* pSubmits,
3631             VkFence fence) {
3632 
3633         auto queue = unbox_VkQueue(boxed_queue);
3634         auto vk = dispatch_VkQueue(boxed_queue);
3635 
3636         AutoLock lock(mLock);
3637 
3638         {
3639             auto queueInfo = android::base::find(mQueueInfo, queue);
3640             if (queueInfo) {
3641                 sBoxedHandleManager.processDelayedRemovesGlobalStateLocked(
3642                         queueInfo->device);
3643             }
3644         }
3645 
3646         for (uint32_t i = 0; i < submitCount; i++) {
3647             const VkSubmitInfo& submit = pSubmits[i];
3648             for (uint32_t c = 0; c < submit.commandBufferCount; c++) {
3649                 executePreprocessRecursive(0, submit.pCommandBuffers[c]);
3650             }
3651         }
3652 
3653         auto queueInfo = android::base::find(mQueueInfo, queue);
3654         if (!queueInfo) return VK_SUCCESS;
3655         Lock* ql = queueInfo->lock;
3656         lock.unlock();
3657 
3658         AutoLock qlock(*ql);
3659 
3660         return vk->vkQueueSubmit(queue, submitCount, pSubmits, fence);
3661     }
3662 
on_vkQueueWaitIdle(android::base::BumpPool * pool,VkQueue boxed_queue)3663     VkResult on_vkQueueWaitIdle(
3664             android::base::BumpPool* pool,
3665             VkQueue boxed_queue) {
3666 
3667         auto queue = unbox_VkQueue(boxed_queue);
3668         auto vk = dispatch_VkQueue(boxed_queue);
3669 
3670         if (!queue) return VK_SUCCESS;
3671 
3672         AutoLock lock(mLock);
3673         auto queueInfo = android::base::find(mQueueInfo, queue);
3674         if (!queueInfo) return VK_SUCCESS;
3675         Lock* ql = queueInfo->lock;
3676         lock.unlock();
3677 
3678         AutoLock qlock(*ql);
3679         return vk->vkQueueWaitIdle(queue);
3680     }
3681 
on_vkResetCommandBuffer(android::base::BumpPool * pool,VkCommandBuffer boxed_commandBuffer,VkCommandBufferResetFlags flags)3682     VkResult on_vkResetCommandBuffer(
3683             android::base::BumpPool* pool,
3684             VkCommandBuffer boxed_commandBuffer,
3685             VkCommandBufferResetFlags flags) {
3686 
3687         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
3688         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
3689 
3690         VkResult result = vk->vkResetCommandBuffer(commandBuffer, flags);
3691         if (VK_SUCCESS == result) {
3692             AutoLock lock(mLock);
3693             mCmdBufferInfo[commandBuffer].preprocessFuncs.clear();
3694             mCmdBufferInfo[commandBuffer].subCmds.clear();
3695             mCmdBufferInfo[commandBuffer].computePipeline = 0;
3696             mCmdBufferInfo[commandBuffer].firstSet = 0;
3697             mCmdBufferInfo[commandBuffer].descriptorLayout = 0;
3698             mCmdBufferInfo[commandBuffer].descriptorSets.clear();
3699         }
3700         return result;
3701     }
3702 
on_vkFreeCommandBuffers(android::base::BumpPool * pool,VkDevice boxed_device,VkCommandPool commandPool,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)3703     void on_vkFreeCommandBuffers(
3704             android::base::BumpPool* pool,
3705             VkDevice boxed_device,
3706             VkCommandPool commandPool,
3707             uint32_t commandBufferCount,
3708             const VkCommandBuffer* pCommandBuffers) {
3709 
3710         auto device = unbox_VkDevice(boxed_device);
3711         auto vk = dispatch_VkDevice(boxed_device);
3712 
3713         if (!device) return;
3714         vk->vkFreeCommandBuffers(device, commandPool, commandBufferCount,
3715                 pCommandBuffers);
3716         AutoLock lock(mLock);
3717         for (uint32_t i = 0; i < commandBufferCount; i++) {
3718             const auto& cmdBufferInfoIt =
3719                 mCmdBufferInfo.find(pCommandBuffers[i]);
3720             if (cmdBufferInfoIt != mCmdBufferInfo.end()) {
3721                 const auto& cmdPoolInfoIt =
3722                     mCmdPoolInfo.find(cmdBufferInfoIt->second.cmdPool);
3723                 if (cmdPoolInfoIt != mCmdPoolInfo.end()) {
3724                     cmdPoolInfoIt->second.cmdBuffers.erase(pCommandBuffers[i]);
3725                 }
3726                 // Done in decoder
3727                 // delete_VkCommandBuffer(cmdBufferInfoIt->second.boxed);
3728                 mCmdBufferInfo.erase(cmdBufferInfoIt);
3729             }
3730         }
3731     }
3732 
on_vkGetPhysicalDeviceExternalSemaphoreProperties(android::base::BumpPool * pool,VkPhysicalDevice boxed_physicalDevice,const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,VkExternalSemaphoreProperties * pExternalSemaphoreProperties)3733     void on_vkGetPhysicalDeviceExternalSemaphoreProperties(
3734             android::base::BumpPool* pool,
3735             VkPhysicalDevice boxed_physicalDevice,
3736             const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
3737             VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
3738 
3739         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
3740 
3741         if (!physicalDevice) {
3742             return;
3743         }
3744         // Cannot forward this call to driver because nVidia linux driver crahses on it.
3745         switch (pExternalSemaphoreInfo->handleType) {
3746             case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
3747                 pExternalSemaphoreProperties->exportFromImportedHandleTypes =
3748                     VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
3749                 pExternalSemaphoreProperties->compatibleHandleTypes =
3750                     VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
3751                 pExternalSemaphoreProperties->externalSemaphoreFeatures =
3752                     VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |
3753                     VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
3754                 return;
3755             case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
3756                 pExternalSemaphoreProperties->exportFromImportedHandleTypes =
3757                     VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
3758                 pExternalSemaphoreProperties->compatibleHandleTypes =
3759                     VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
3760                 pExternalSemaphoreProperties->externalSemaphoreFeatures =
3761                     VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |
3762                     VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
3763                 return;
3764             default:
3765                 break;
3766         }
3767 
3768         pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
3769         pExternalSemaphoreProperties->compatibleHandleTypes = 0;
3770         pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
3771     }
3772 
on_vkCreateDescriptorUpdateTemplate(android::base::BumpPool * pool,VkDevice boxed_device,const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate)3773     VkResult on_vkCreateDescriptorUpdateTemplate(
3774             android::base::BumpPool* pool,
3775             VkDevice boxed_device,
3776             const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
3777             const VkAllocationCallbacks* pAllocator,
3778             VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
3779 
3780         auto device = unbox_VkDevice(boxed_device);
3781         auto vk = dispatch_VkDevice(boxed_device);
3782 
3783         auto descriptorUpdateTemplateInfo =
3784             calcLinearizedDescriptorUpdateTemplateInfo(pCreateInfo);
3785 
3786         VkResult res = vk->vkCreateDescriptorUpdateTemplate(
3787                 device, &descriptorUpdateTemplateInfo.createInfo,
3788                 pAllocator, pDescriptorUpdateTemplate);
3789 
3790         if (res == VK_SUCCESS) {
3791             registerDescriptorUpdateTemplate(
3792                     *pDescriptorUpdateTemplate,
3793                     descriptorUpdateTemplateInfo);
3794             *pDescriptorUpdateTemplate = new_boxed_non_dispatchable_VkDescriptorUpdateTemplate(*pDescriptorUpdateTemplate);
3795         }
3796 
3797         return res;
3798     }
3799 
on_vkCreateDescriptorUpdateTemplateKHR(android::base::BumpPool * pool,VkDevice boxed_device,const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate)3800     VkResult on_vkCreateDescriptorUpdateTemplateKHR(
3801             android::base::BumpPool* pool,
3802             VkDevice boxed_device,
3803             const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
3804             const VkAllocationCallbacks* pAllocator,
3805             VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
3806 
3807         auto device = unbox_VkDevice(boxed_device);
3808         auto vk = dispatch_VkDevice(boxed_device);
3809 
3810         auto descriptorUpdateTemplateInfo =
3811             calcLinearizedDescriptorUpdateTemplateInfo(pCreateInfo);
3812 
3813         VkResult res = vk->vkCreateDescriptorUpdateTemplateKHR(
3814                 device, &descriptorUpdateTemplateInfo.createInfo,
3815                 pAllocator, pDescriptorUpdateTemplate);
3816 
3817         if (res == VK_SUCCESS) {
3818             registerDescriptorUpdateTemplate(
3819                     *pDescriptorUpdateTemplate,
3820                     descriptorUpdateTemplateInfo);
3821             *pDescriptorUpdateTemplate = new_boxed_non_dispatchable_VkDescriptorUpdateTemplate(*pDescriptorUpdateTemplate);
3822         }
3823 
3824         return res;
3825     }
3826 
on_vkDestroyDescriptorUpdateTemplate(android::base::BumpPool * pool,VkDevice boxed_device,VkDescriptorUpdateTemplate descriptorUpdateTemplate,const VkAllocationCallbacks * pAllocator)3827     void on_vkDestroyDescriptorUpdateTemplate(
3828             android::base::BumpPool* pool,
3829             VkDevice boxed_device,
3830             VkDescriptorUpdateTemplate descriptorUpdateTemplate,
3831             const VkAllocationCallbacks* pAllocator) {
3832         auto device = unbox_VkDevice(boxed_device);
3833         auto vk = dispatch_VkDevice(boxed_device);
3834 
3835         vk->vkDestroyDescriptorUpdateTemplate(
3836                 device, descriptorUpdateTemplate, pAllocator);
3837 
3838         unregisterDescriptorUpdateTemplate(descriptorUpdateTemplate);
3839     }
3840 
on_vkDestroyDescriptorUpdateTemplateKHR(android::base::BumpPool * pool,VkDevice boxed_device,VkDescriptorUpdateTemplate descriptorUpdateTemplate,const VkAllocationCallbacks * pAllocator)3841     void on_vkDestroyDescriptorUpdateTemplateKHR(
3842             android::base::BumpPool* pool,
3843             VkDevice boxed_device,
3844             VkDescriptorUpdateTemplate descriptorUpdateTemplate,
3845             const VkAllocationCallbacks* pAllocator) {
3846         auto device = unbox_VkDevice(boxed_device);
3847         auto vk = dispatch_VkDevice(boxed_device);
3848 
3849         vk->vkDestroyDescriptorUpdateTemplateKHR(
3850                 device, descriptorUpdateTemplate, pAllocator);
3851 
3852         unregisterDescriptorUpdateTemplate(descriptorUpdateTemplate);
3853     }
3854 
on_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(android::base::BumpPool * pool,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)3855     void on_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(
3856             android::base::BumpPool* pool,
3857             VkDevice boxed_device,
3858             VkDescriptorSet descriptorSet,
3859             VkDescriptorUpdateTemplate descriptorUpdateTemplate,
3860             uint32_t imageInfoCount,
3861             uint32_t bufferInfoCount,
3862             uint32_t bufferViewCount,
3863             const uint32_t* pImageInfoEntryIndices,
3864             const uint32_t* pBufferInfoEntryIndices,
3865             const uint32_t* pBufferViewEntryIndices,
3866             const VkDescriptorImageInfo* pImageInfos,
3867             const VkDescriptorBufferInfo* pBufferInfos,
3868             const VkBufferView* pBufferViews) {
3869 
3870         auto device = unbox_VkDevice(boxed_device);
3871         auto vk = dispatch_VkDevice(boxed_device);
3872 
3873         AutoLock lock(mLock);
3874         auto info = android::base::find(
3875                 mDescriptorUpdateTemplateInfo,
3876                 descriptorUpdateTemplate);
3877 
3878         if (!info) return;
3879 
3880         memcpy(info->data.data() + info->imageInfoStart,
3881                 pImageInfos,
3882                 imageInfoCount * sizeof(VkDescriptorImageInfo));
3883         memcpy(info->data.data() + info->bufferInfoStart,
3884                 pBufferInfos,
3885                 bufferInfoCount * sizeof(VkDescriptorBufferInfo));
3886         memcpy(info->data.data() + info->bufferViewStart,
3887                 pBufferViews,
3888                 bufferViewCount * sizeof(VkBufferView));
3889 
3890         vk->vkUpdateDescriptorSetWithTemplate(
3891                 device, descriptorSet, descriptorUpdateTemplate,
3892                 info->data.data());
3893     }
3894 
hostSyncCommandBuffer(const char * tag,VkCommandBuffer boxed_commandBuffer,uint32_t needHostSync,uint32_t sequenceNumber)3895     void hostSyncCommandBuffer(
3896         const char* tag,
3897         VkCommandBuffer boxed_commandBuffer,
3898         uint32_t needHostSync,
3899         uint32_t sequenceNumber) {
3900 
3901         auto nextDeadline = []() {
3902             return android::base::getUnixTimeUs() + 10000; // 10 ms
3903         };
3904 
3905         auto timeoutDeadline = android::base::getUnixTimeUs() + 5000000; // 5 s
3906 
3907         OrderMaintenanceInfo* order = ordmaint_VkCommandBuffer(boxed_commandBuffer);
3908         if (!order) return;
3909 
3910         AutoLock lock(order->lock);
3911 
3912         if (needHostSync) {
3913             while ((sequenceNumber - __atomic_load_n(&order->sequenceNumber, __ATOMIC_ACQUIRE) != 1)) {
3914                 auto waitUntilUs = nextDeadline();
3915                 order->cv.timedWait(
3916                     &order->lock, waitUntilUs);
3917 
3918                 if (timeoutDeadline < android::base::getUnixTimeUs()) {
3919                     break;
3920                 }
3921             }
3922         }
3923 
3924         __atomic_store_n(&order->sequenceNumber, sequenceNumber, __ATOMIC_RELEASE);
3925         order->cv.signal();
3926         releaseOrderMaintInfo(order);
3927     }
3928 
on_vkCommandBufferHostSyncGOOGLE(android::base::BumpPool * pool,VkCommandBuffer commandBuffer,uint32_t needHostSync,uint32_t sequenceNumber)3929     void on_vkCommandBufferHostSyncGOOGLE(
3930             android::base::BumpPool* pool,
3931             VkCommandBuffer commandBuffer,
3932             uint32_t needHostSync,
3933             uint32_t sequenceNumber) {
3934         this->hostSyncCommandBuffer("hostSync", commandBuffer, needHostSync, sequenceNumber);
3935     }
3936 
hostSyncQueue(const char * tag,VkQueue boxed_queue,uint32_t needHostSync,uint32_t sequenceNumber)3937     void hostSyncQueue(
3938         const char* tag,
3939         VkQueue boxed_queue,
3940         uint32_t needHostSync,
3941         uint32_t sequenceNumber) {
3942 
3943         auto nextDeadline = []() {
3944             return android::base::getUnixTimeUs() + 10000; // 10 ms
3945         };
3946 
3947         auto timeoutDeadline = android::base::getUnixTimeUs() + 5000000; // 5 s
3948 
3949         OrderMaintenanceInfo* order = ordmaint_VkQueue(boxed_queue);
3950         if (!order) return;
3951 
3952         AutoLock lock(order->lock);
3953 
3954         if (needHostSync) {
3955             while ((sequenceNumber - __atomic_load_n(&order->sequenceNumber, __ATOMIC_ACQUIRE) != 1)) {
3956                 auto waitUntilUs = nextDeadline();
3957                 order->cv.timedWait(
3958                     &order->lock, waitUntilUs);
3959 
3960                 if (timeoutDeadline < android::base::getUnixTimeUs()) {
3961                     break;
3962                 }
3963             }
3964         }
3965 
3966         __atomic_store_n(&order->sequenceNumber, sequenceNumber, __ATOMIC_RELEASE);
3967         order->cv.signal();
3968         releaseOrderMaintInfo(order);
3969     }
3970 
on_vkQueueHostSyncGOOGLE(android::base::BumpPool * pool,VkQueue queue,uint32_t needHostSync,uint32_t sequenceNumber)3971     void on_vkQueueHostSyncGOOGLE(
3972         android::base::BumpPool* pool,
3973         VkQueue queue,
3974         uint32_t needHostSync,
3975         uint32_t sequenceNumber) {
3976         this->hostSyncQueue("hostSyncQueue", queue, needHostSync, sequenceNumber);
3977     }
3978 
3979 
on_vkCreateImageWithRequirementsGOOGLE(android::base::BumpPool * pool,VkDevice boxed_device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage,VkMemoryRequirements * pMemoryRequirements)3980     VkResult on_vkCreateImageWithRequirementsGOOGLE(
3981         android::base::BumpPool* pool,
3982         VkDevice boxed_device,
3983         const VkImageCreateInfo* pCreateInfo,
3984         const VkAllocationCallbacks* pAllocator,
3985         VkImage* pImage,
3986         VkMemoryRequirements* pMemoryRequirements) {
3987 
3988         if (pMemoryRequirements) {
3989             memset(pMemoryRequirements, 0, sizeof(*pMemoryRequirements));
3990         }
3991 
3992         VkResult imageCreateRes =
3993             on_vkCreateImage(pool, boxed_device, pCreateInfo, pAllocator, pImage);
3994 
3995         if (imageCreateRes != VK_SUCCESS) {
3996             return imageCreateRes;
3997         }
3998 
3999         on_vkGetImageMemoryRequirements(
4000             pool, boxed_device,
4001             unbox_VkImage(*pImage),
4002             pMemoryRequirements);
4003 
4004         return imageCreateRes;
4005     }
4006 
on_vkCreateBufferWithRequirementsGOOGLE(android::base::BumpPool * pool,VkDevice boxed_device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer,VkMemoryRequirements * pMemoryRequirements)4007     VkResult on_vkCreateBufferWithRequirementsGOOGLE(
4008         android::base::BumpPool* pool,
4009         VkDevice boxed_device,
4010         const VkBufferCreateInfo* pCreateInfo,
4011         const VkAllocationCallbacks* pAllocator,
4012         VkBuffer* pBuffer,
4013         VkMemoryRequirements* pMemoryRequirements) {
4014 
4015         if (pMemoryRequirements) {
4016             memset(pMemoryRequirements, 0, sizeof(*pMemoryRequirements));
4017         }
4018 
4019         VkResult bufferCreateRes =
4020             on_vkCreateBuffer(pool, boxed_device, pCreateInfo, pAllocator, pBuffer);
4021 
4022         if (bufferCreateRes != VK_SUCCESS) {
4023             return bufferCreateRes;
4024         }
4025 
4026         auto device = unbox_VkDevice(boxed_device);
4027         auto vk = dispatch_VkDevice(boxed_device);
4028 
4029         vk->vkGetBufferMemoryRequirements(
4030             device, unbox_VkBuffer(*pBuffer), pMemoryRequirements);
4031 
4032         return bufferCreateRes;
4033     }
4034 
4035 
on_vkBeginCommandBuffer(android::base::BumpPool * pool,VkCommandBuffer boxed_commandBuffer,const VkCommandBufferBeginInfo * pBeginInfo)4036     VkResult on_vkBeginCommandBuffer(
4037             android::base::BumpPool* pool,
4038             VkCommandBuffer boxed_commandBuffer,
4039             const VkCommandBufferBeginInfo* pBeginInfo) {
4040         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4041         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4042         VkResult result = vk->vkBeginCommandBuffer(commandBuffer, pBeginInfo);
4043 
4044         if (result != VK_SUCCESS) {
4045             return result;
4046         }
4047 
4048         AutoLock lock(mLock);
4049         mCmdBufferInfo[commandBuffer].preprocessFuncs.clear();
4050         mCmdBufferInfo[commandBuffer].subCmds.clear();
4051         return VK_SUCCESS;
4052     }
4053 
on_vkBeginCommandBufferAsyncGOOGLE(android::base::BumpPool * pool,VkCommandBuffer boxed_commandBuffer,const VkCommandBufferBeginInfo * pBeginInfo)4054     VkResult on_vkBeginCommandBufferAsyncGOOGLE(
4055             android::base::BumpPool* pool,
4056             VkCommandBuffer boxed_commandBuffer,
4057             const VkCommandBufferBeginInfo* pBeginInfo) {
4058         return this->on_vkBeginCommandBuffer(
4059             pool, boxed_commandBuffer, pBeginInfo);
4060     }
4061 
on_vkEndCommandBufferAsyncGOOGLE(android::base::BumpPool * pool,VkCommandBuffer boxed_commandBuffer)4062     void on_vkEndCommandBufferAsyncGOOGLE(
4063             android::base::BumpPool* pool,
4064             VkCommandBuffer boxed_commandBuffer) {
4065 
4066         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4067         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4068 
4069         vk->vkEndCommandBuffer(commandBuffer);
4070     }
4071 
on_vkResetCommandBufferAsyncGOOGLE(android::base::BumpPool * pool,VkCommandBuffer boxed_commandBuffer,VkCommandBufferResetFlags flags)4072     void on_vkResetCommandBufferAsyncGOOGLE(
4073             android::base::BumpPool* pool,
4074             VkCommandBuffer boxed_commandBuffer,
4075             VkCommandBufferResetFlags flags) {
4076         on_vkResetCommandBuffer(pool, boxed_commandBuffer, flags);
4077     }
4078 
on_vkCmdBindPipeline(android::base::BumpPool * pool,VkCommandBuffer boxed_commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipeline pipeline)4079     void on_vkCmdBindPipeline(android::base::BumpPool* pool,
4080             VkCommandBuffer boxed_commandBuffer,
4081             VkPipelineBindPoint pipelineBindPoint,
4082             VkPipeline pipeline) {
4083         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4084         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4085         vk->vkCmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
4086         if (pipelineBindPoint == VK_PIPELINE_BIND_POINT_COMPUTE) {
4087             AutoLock lock(mLock);
4088             auto cmdBufferInfoIt = mCmdBufferInfo.find(commandBuffer);
4089             if (cmdBufferInfoIt != mCmdBufferInfo.end()) {
4090                 if (pipelineBindPoint == VK_PIPELINE_BIND_POINT_COMPUTE) {
4091                     cmdBufferInfoIt->second.computePipeline = pipeline;
4092                 }
4093             }
4094         }
4095     }
4096 
on_vkCmdBindDescriptorSets(android::base::BumpPool * pool,VkCommandBuffer boxed_commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipelineLayout layout,uint32_t firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets,uint32_t dynamicOffsetCount,const uint32_t * pDynamicOffsets)4097     void on_vkCmdBindDescriptorSets(android::base::BumpPool* pool,
4098             VkCommandBuffer boxed_commandBuffer,
4099             VkPipelineBindPoint pipelineBindPoint,
4100             VkPipelineLayout layout,
4101             uint32_t firstSet,
4102             uint32_t descriptorSetCount,
4103             const VkDescriptorSet* pDescriptorSets,
4104             uint32_t dynamicOffsetCount,
4105             const uint32_t* pDynamicOffsets) {
4106         auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4107         auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4108         vk->vkCmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout,
4109                 firstSet, descriptorSetCount,
4110                 pDescriptorSets, dynamicOffsetCount,
4111                 pDynamicOffsets);
4112         if (pipelineBindPoint == VK_PIPELINE_BIND_POINT_COMPUTE) {
4113             AutoLock lock(mLock);
4114             auto cmdBufferInfoIt = mCmdBufferInfo.find(commandBuffer);
4115             if (cmdBufferInfoIt != mCmdBufferInfo.end()) {
4116                 cmdBufferInfoIt->second.descriptorLayout = layout;
4117                 if (descriptorSetCount) {
4118                     cmdBufferInfoIt->second.firstSet = firstSet;
4119                     cmdBufferInfoIt->second.descriptorSets.assign(
4120                             pDescriptorSets,
4121                             pDescriptorSets + descriptorSetCount);
4122                 }
4123             }
4124         }
4125     }
4126 
on_vkCreateRenderPass(android::base::BumpPool * pool,VkDevice boxed_device,const VkRenderPassCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)4127     VkResult on_vkCreateRenderPass(android::base::BumpPool* pool,
4128                                    VkDevice boxed_device,
4129                                    const VkRenderPassCreateInfo* pCreateInfo,
4130                                    const VkAllocationCallbacks* pAllocator,
4131                                    VkRenderPass* pRenderPass) {
4132         auto device = unbox_VkDevice(boxed_device);
4133         auto vk = dispatch_VkDevice(boxed_device);
4134         VkRenderPassCreateInfo createInfo;
4135         bool needReformat = false;
4136         AutoLock lock(mLock);
4137 
4138         auto deviceInfoIt = mDeviceInfo.find(device);
4139         if (deviceInfoIt == mDeviceInfo.end()) {
4140             return VK_ERROR_OUT_OF_HOST_MEMORY;
4141         }
4142         if (deviceInfoIt->second.emulateTextureEtc2 ||
4143             deviceInfoIt->second.emulateTextureAstc) {
4144             for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
4145                 if (deviceInfoIt->second.needEmulatedDecompression(
4146                             pCreateInfo->pAttachments[i].format)) {
4147                     needReformat = true;
4148                     break;
4149                 }
4150             }
4151         }
4152         std::vector<VkAttachmentDescription> attachments;
4153         if (needReformat) {
4154             createInfo = *pCreateInfo;
4155             attachments.assign(
4156                     pCreateInfo->pAttachments,
4157                     pCreateInfo->pAttachments + pCreateInfo->attachmentCount);
4158             createInfo.pAttachments = attachments.data();
4159             for (auto& attachment : attachments) {
4160                 attachment.format = getDecompFormat(attachment.format);
4161             }
4162             pCreateInfo = &createInfo;
4163         }
4164         VkResult res = vk->vkCreateRenderPass(device, pCreateInfo, pAllocator,
4165                                               pRenderPass);
4166         if (res != VK_SUCCESS) {
4167             return res;
4168         }
4169 
4170         *pRenderPass = new_boxed_non_dispatchable_VkRenderPass(*pRenderPass);
4171 
4172         return res;
4173     }
4174 
on_vkQueueBindSparseAsyncGOOGLE(android::base::BumpPool * pool,VkQueue boxed_queue,uint32_t bindInfoCount,const VkBindSparseInfo * pBindInfo,VkFence fence)4175     void on_vkQueueBindSparseAsyncGOOGLE(
4176         android::base::BumpPool* pool,
4177         VkQueue boxed_queue,
4178         uint32_t bindInfoCount,
4179         const VkBindSparseInfo* pBindInfo, VkFence fence) {
4180         auto queue = unbox_VkQueue(boxed_queue);
4181         auto vk = dispatch_VkQueue(boxed_queue);
4182         (void)pool;
4183         vk->vkQueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
4184     }
4185 
on_vkGetLinearImageLayoutGOOGLE(android::base::BumpPool * pool,VkDevice boxed_device,VkFormat format,VkDeviceSize * pOffset,VkDeviceSize * pRowPitchAlignment)4186     void on_vkGetLinearImageLayoutGOOGLE(
4187         android::base::BumpPool* pool,
4188         VkDevice boxed_device,
4189         VkFormat format,
4190         VkDeviceSize* pOffset,
4191         VkDeviceSize* pRowPitchAlignment) {
4192 
4193         if (!mLinearImageProperties.hasValue()) {
4194             auto device = unbox_VkDevice(boxed_device);
4195             auto vk = dispatch_VkDevice(boxed_device);
4196 
4197             VkImageCreateInfo createInfo;
4198             createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4199             createInfo.pNext = nullptr;
4200             createInfo.flags = {};
4201             createInfo.imageType = VK_IMAGE_TYPE_2D;
4202             createInfo.format = format;
4203             createInfo.extent = {/*width*/ 1, /*height*/ 64, 1};
4204             createInfo.mipLevels = 1;
4205             createInfo.arrayLayers = 1;
4206             createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
4207             createInfo.tiling = VK_IMAGE_TILING_LINEAR;
4208             createInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4209             createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
4210             createInfo.queueFamilyIndexCount = 0;
4211             createInfo.pQueueFamilyIndices = nullptr;
4212             createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4213 
4214             VkImageSubresource subresource = {
4215                 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4216                 .mipLevel = 0,
4217                 .arrayLayer = 0,
4218             };
4219 
4220             VkImage image;
4221             VkSubresourceLayout subresourceLayout;
4222 
4223             VkDeviceSize offset = 0u;
4224             VkDeviceSize rowPitchAlignment = UINT_MAX;
4225 
4226             constexpr VkDeviceSize kMinWidth = 64;
4227             constexpr VkDeviceSize kMaxWidth = 2048;
4228             for (VkDeviceSize width = kMinWidth; width <= kMaxWidth; ++width) {
4229                 createInfo.extent.width = width;
4230                 VkResult result =
4231                         vk->vkCreateImage(device, &createInfo, nullptr, &image);
4232                 if (result != VK_SUCCESS) {
4233                     // fprintf(stderr, "%s: vkCreateImage failed. w h %u %u result 0x%x\n", __func__,
4234                             // width, createInfo.extent.height,
4235                             // result);
4236                     continue;
4237                 }
4238                 vk->vkGetImageSubresourceLayout(device, image, &subresource, &subresourceLayout);
4239                 vk->vkDestroyImage(device, image, nullptr);
4240 
4241                 if (width > kMinWidth && subresourceLayout.offset != offset) {
4242                     // fprintf(stderr, "Image size %u x %u has a different offset (%u), offset of other images %u, returned pOffset might be invalid.\n", width, createInfo.extent.height, offset);
4243                 }
4244                 offset = subresourceLayout.offset;
4245 
4246                 uint64_t rowPitch = subresourceLayout.rowPitch;
4247                 uint64_t currentAlignment = rowPitch & (~rowPitch + 1);
4248                 if (currentAlignment < rowPitchAlignment) {
4249                     rowPitchAlignment = currentAlignment;
4250                 }
4251             }
4252 
4253             mLinearImageProperties.emplace(LinearImageProperties {
4254                 .offset = offset,
4255                 .rowPitchAlignment = rowPitchAlignment,
4256             });
4257         }
4258 
4259         if (pOffset != nullptr) {
4260             *pOffset = mLinearImageProperties->offset;
4261         }
4262         if (pRowPitchAlignment != nullptr) {
4263             *pRowPitchAlignment = mLinearImageProperties->rowPitchAlignment;
4264         }
4265     }
4266 
4267 #include "VkSubDecoder.cpp"
4268 
on_vkQueueFlushCommandsGOOGLE(android::base::BumpPool * pool,VkQueue queue,VkCommandBuffer boxed_commandBuffer,VkDeviceSize dataSize,const void * pData)4269     void on_vkQueueFlushCommandsGOOGLE(
4270         android::base::BumpPool* pool,
4271         VkQueue queue,
4272         VkCommandBuffer boxed_commandBuffer,
4273         VkDeviceSize dataSize,
4274         const void* pData) {
4275         (void)queue;
4276 
4277         VkCommandBuffer commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
4278         VulkanDispatch* vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
4279         VulkanMemReadingStream* readStream = readstream_VkCommandBuffer(boxed_commandBuffer);
4280         subDecode(readStream, vk, boxed_commandBuffer, commandBuffer, dataSize, pData);
4281     }
4282 
getOrAllocateDescriptorSetFromPoolAndId(VulkanDispatch * vk,VkDevice device,VkDescriptorPool pool,VkDescriptorSetLayout setLayout,uint64_t poolId,uint32_t pendingAlloc,bool * didAlloc)4283     VkDescriptorSet getOrAllocateDescriptorSetFromPoolAndId(
4284         VulkanDispatch* vk,
4285         VkDevice device,
4286         VkDescriptorPool pool,
4287         VkDescriptorSetLayout setLayout,
4288         uint64_t poolId,
4289         uint32_t pendingAlloc,
4290         bool* didAlloc) {
4291 
4292         auto poolInfo = android::base::find(mDescriptorPoolInfo, pool);
4293         if (!poolInfo) {
4294             fprintf(stderr, "%s: FATAL: descriptor pool %p not found\n", __func__, pool);
4295             abort();
4296         }
4297 
4298         DispatchableHandleInfo<uint64_t>* setHandleInfo = sBoxedHandleManager.get(poolId);
4299 
4300         if (setHandleInfo->underlying) {
4301             if (pendingAlloc) {
4302                 VkDescriptorSet allocedSet;
4303                 vk->vkFreeDescriptorSets(device, pool, 1, (VkDescriptorSet*)(&setHandleInfo->underlying));
4304                 VkDescriptorSetAllocateInfo dsAi = {
4305                     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 0,
4306                     pool,
4307                     1,
4308                     &setLayout,
4309                 };
4310                 vk->vkAllocateDescriptorSets(device, &dsAi, &allocedSet);
4311                 setHandleInfo->underlying = (uint64_t)allocedSet;
4312                 initDescriptorSetInfoLocked(pool, setLayout, poolId, allocedSet);
4313                 *didAlloc = true;
4314                 return allocedSet;
4315             } else {
4316                 *didAlloc = false;
4317                 return (VkDescriptorSet)(setHandleInfo->underlying);
4318             }
4319         } else {
4320             if (pendingAlloc) {
4321                 VkDescriptorSet allocedSet;
4322                 VkDescriptorSetAllocateInfo dsAi = {
4323                     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 0,
4324                     pool,
4325                     1,
4326                     &setLayout,
4327                 };
4328                 vk->vkAllocateDescriptorSets(device, &dsAi, &allocedSet);
4329                 setHandleInfo->underlying = (uint64_t)allocedSet;
4330                 initDescriptorSetInfoLocked(pool, setLayout, poolId, allocedSet);
4331                 *didAlloc = true;
4332                 return allocedSet;
4333             } else {
4334                 fprintf(stderr, "%s: FATAL: descriptor pool %p wanted to get set with id 0x%llx but it wasn't allocated\n", __func__,
4335                         pool, (unsigned long long)poolId);
4336                 abort();
4337             }
4338         }
4339     }
4340 
on_vkQueueCommitDescriptorSetUpdatesGOOGLE(android::base::BumpPool * pool,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)4341     void on_vkQueueCommitDescriptorSetUpdatesGOOGLE(
4342         android::base::BumpPool* pool,
4343         VkQueue boxed_queue,
4344         uint32_t descriptorPoolCount,
4345         const VkDescriptorPool* pDescriptorPools,
4346         uint32_t descriptorSetCount,
4347         const VkDescriptorSetLayout* pDescriptorSetLayouts,
4348         const uint64_t* pDescriptorSetPoolIds,
4349         const uint32_t* pDescriptorSetWhichPool,
4350         const uint32_t* pDescriptorSetPendingAllocation,
4351         const uint32_t* pDescriptorWriteStartingIndices,
4352         uint32_t pendingDescriptorWriteCount,
4353         const VkWriteDescriptorSet* pPendingDescriptorWrites) {
4354 
4355         AutoLock lock(mLock);
4356 
4357         VkDevice device;
4358 
4359         auto queue = unbox_VkQueue(boxed_queue);
4360         auto vk = dispatch_VkQueue(boxed_queue);
4361 
4362         auto queueInfo = android::base::find(mQueueInfo, queue);
4363         if (queueInfo) {
4364             device = queueInfo->device;
4365         } else {
4366             fprintf(stderr, "%s: FATAL: queue %p (boxed: %p) with no device registered\n", __func__,
4367                     queue, boxed_queue);
4368             abort();
4369         }
4370 
4371         std::vector<VkDescriptorSet> setsToUpdate(descriptorSetCount, nullptr);
4372 
4373         bool didAlloc = false;
4374 
4375         for (uint32_t i = 0; i < descriptorSetCount; ++i) {
4376             uint64_t poolId = pDescriptorSetPoolIds[i];
4377             uint32_t whichPool = pDescriptorSetWhichPool[i];
4378             uint32_t pendingAlloc = pDescriptorSetPendingAllocation[i];
4379             bool didAllocThisTime;
4380             setsToUpdate[i] = getOrAllocateDescriptorSetFromPoolAndId(
4381                 vk, device,
4382                 pDescriptorPools[whichPool],
4383                 pDescriptorSetLayouts[i],
4384                 poolId,
4385                 pendingAlloc,
4386                 &didAllocThisTime);
4387 
4388             if (didAllocThisTime) didAlloc = true;
4389         }
4390 
4391         if (didAlloc) {
4392 
4393             std::vector<VkWriteDescriptorSet> writeDescriptorSetsForHostDriver(pendingDescriptorWriteCount);
4394             memcpy(writeDescriptorSetsForHostDriver.data(), pPendingDescriptorWrites, pendingDescriptorWriteCount * sizeof(VkWriteDescriptorSet));
4395 
4396             for (uint32_t i = 0; i < descriptorSetCount; ++i) {
4397                 uint32_t writeStartIndex = pDescriptorWriteStartingIndices[i];
4398                 uint32_t writeEndIndex;
4399                 if (i == descriptorSetCount - 1) {
4400                     writeEndIndex = pendingDescriptorWriteCount;
4401                 } else {
4402                     writeEndIndex = pDescriptorWriteStartingIndices[i + 1];
4403                 }
4404 
4405                 for (uint32_t j = writeStartIndex; j < writeEndIndex; ++j) {
4406                     writeDescriptorSetsForHostDriver[j].dstSet = setsToUpdate[i];
4407                 }
4408             }
4409             this->on_vkUpdateDescriptorSetsImpl(
4410                 pool, vk, device,
4411                 (uint32_t)writeDescriptorSetsForHostDriver.size(),
4412                 writeDescriptorSetsForHostDriver.data(), 0, nullptr);
4413         } else {
4414             this->on_vkUpdateDescriptorSetsImpl(
4415                 pool, vk, device,
4416                 pendingDescriptorWriteCount,
4417                 pPendingDescriptorWrites,
4418                 0, nullptr);
4419         }
4420     }
4421 
on_vkCollectDescriptorPoolIdsGOOGLE(android::base::BumpPool * pool,VkDevice device,VkDescriptorPool descriptorPool,uint32_t * pPoolIdCount,uint64_t * pPoolIds)4422     void on_vkCollectDescriptorPoolIdsGOOGLE(
4423             android::base::BumpPool* pool,
4424             VkDevice device,
4425             VkDescriptorPool descriptorPool,
4426             uint32_t* pPoolIdCount,
4427             uint64_t* pPoolIds) {
4428 
4429         AutoLock lock(mLock);
4430         auto& info = mDescriptorPoolInfo[descriptorPool];
4431         *pPoolIdCount = (uint32_t)info.poolIds.size();
4432 
4433         if (pPoolIds) {
4434             for (uint32_t i = 0; i < info.poolIds.size(); ++i) {
4435                 pPoolIds[i] = info.poolIds[i];
4436             }
4437         }
4438     }
4439 
waitForFence(VkFence boxed_fence,uint64_t timeout)4440     VkResult waitForFence(VkFence boxed_fence, uint64_t timeout) {
4441         AutoLock lock(mLock);
4442 
4443         VkFence fence = unbox_VkFence(boxed_fence);
4444         if (fence == VK_NULL_HANDLE || mFenceInfo.find(fence) == mFenceInfo.end()) {
4445             // No fence, could be a semaphore.
4446             // TODO: Async wait for semaphores
4447             return VK_SUCCESS;
4448         }
4449 
4450         const VkDevice device = mFenceInfo[fence].device;
4451         const VulkanDispatch* vk = mFenceInfo[fence].vk;
4452         lock.unlock();
4453 
4454         return vk->vkWaitForFences(device, /* fenceCount */ 1u, &fence,
4455                                    /* waitAll */ false, timeout);
4456     }
4457 
getFenceStatus(VkFence boxed_fence)4458     VkResult getFenceStatus(VkFence boxed_fence) {
4459         AutoLock lock(mLock);
4460 
4461         VkFence fence = unbox_VkFence(boxed_fence);
4462         if (fence == VK_NULL_HANDLE || mFenceInfo.find(fence) == mFenceInfo.end()) {
4463             // No fence, could be a semaphore.
4464             // TODO: Async get status for semaphores
4465             return VK_SUCCESS;
4466         }
4467 
4468         const VkDevice device = mFenceInfo[fence].device;
4469         const VulkanDispatch* vk = mFenceInfo[fence].vk;
4470         lock.unlock();
4471 
4472         return vk->vkGetFenceStatus(device, fence);
4473     }
4474 
4475 #define GUEST_EXTERNAL_MEMORY_HANDLE_TYPES                                \
4476     (VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID | \
4477      VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA |         \
4478      VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA)
4479 
4480     // Transforms
4481 
transformImpl_VkExternalMemoryProperties_tohost(const VkExternalMemoryProperties * props,uint32_t count)4482     void transformImpl_VkExternalMemoryProperties_tohost(
4483             const VkExternalMemoryProperties* props, uint32_t count) {
4484         VkExternalMemoryProperties* mut =
4485             (VkExternalMemoryProperties*)props;
4486         for (uint32_t i = 0; i < count; ++i) {
4487             mut[i] = transformExternalMemoryProperties_tohost(mut[i]);
4488         }
4489     }
transformImpl_VkExternalMemoryProperties_fromhost(const VkExternalMemoryProperties * props,uint32_t count)4490     void transformImpl_VkExternalMemoryProperties_fromhost(
4491             const VkExternalMemoryProperties* props, uint32_t count) {
4492         VkExternalMemoryProperties* mut =
4493             (VkExternalMemoryProperties*)props;
4494         for (uint32_t i = 0; i < count; ++i) {
4495             mut[i] = transformExternalMemoryProperties_fromhost(mut[i], GUEST_EXTERNAL_MEMORY_HANDLE_TYPES);
4496         }
4497     }
4498 
4499 #define DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(type, field) \
4500     void transformImpl_##type##_tohost(const type* props, uint32_t count) { \
4501         type* mut = (type*)props; \
4502         for (uint32_t i = 0; i < count; ++i) { \
4503             mut[i].field = (VkExternalMemoryHandleTypeFlagBits) \
4504             transformExternalMemoryHandleTypeFlags_tohost( \
4505                     mut[i].field); \
4506         } \
4507     } \
4508     void transformImpl_##type##_fromhost(const type* props, uint32_t count) { \
4509         type* mut = (type*)props; \
4510         for (uint32_t i = 0; i < count; ++i) { \
4511             mut[i].field = (VkExternalMemoryHandleTypeFlagBits) \
4512             transformExternalMemoryHandleTypeFlags_fromhost( \
4513                     mut[i].field, GUEST_EXTERNAL_MEMORY_HANDLE_TYPES); \
4514         } \
4515     } \
4516 
4517 #define DEFINE_EXTERNAL_MEMORY_PROPERTIES_TRANSFORM(type) \
4518     void transformImpl_##type##_tohost(const type* props, uint32_t count) { \
4519         type* mut = (type*)props; \
4520         for (uint32_t i = 0; i < count; ++i) { \
4521             mut[i].externalMemoryProperties = transformExternalMemoryProperties_tohost( \
4522                     mut[i].externalMemoryProperties); \
4523         } \
4524     } \
4525     void transformImpl_##type##_fromhost(const type* props, uint32_t count) { \
4526         type* mut = (type*)props; \
4527         for (uint32_t i = 0; i < count; ++i) { \
4528             mut[i].externalMemoryProperties = transformExternalMemoryProperties_fromhost( \
4529                     mut[i].externalMemoryProperties, GUEST_EXTERNAL_MEMORY_HANDLE_TYPES); \
4530         } \
4531     } \
4532 
DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(VkPhysicalDeviceExternalImageFormatInfo,handleType)4533     DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(VkPhysicalDeviceExternalImageFormatInfo, handleType)
4534         DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(VkPhysicalDeviceExternalBufferInfo, handleType)
4535         DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(VkExternalMemoryImageCreateInfo, handleTypes)
4536         DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(VkExternalMemoryBufferCreateInfo, handleTypes)
4537         DEFINE_EXTERNAL_HANDLE_TYPE_TRANSFORM(VkExportMemoryAllocateInfo, handleTypes)
4538         DEFINE_EXTERNAL_MEMORY_PROPERTIES_TRANSFORM(VkExternalImageFormatProperties)
4539         DEFINE_EXTERNAL_MEMORY_PROPERTIES_TRANSFORM(VkExternalBufferProperties)
4540 
4541     uint64_t newGlobalHandle(const DispatchableHandleInfo<uint64_t>& item, BoxedHandleTypeTag typeTag) {
4542         if (!mCreatedHandlesForSnapshotLoad.empty() &&
4543                 (mCreatedHandlesForSnapshotLoad.size() - mCreatedHandlesForSnapshotLoadIndex > 0)) {
4544             auto handle = mCreatedHandlesForSnapshotLoad[mCreatedHandlesForSnapshotLoadIndex];
4545             VKDGS_LOG("use handle: %p", handle);
4546             ++mCreatedHandlesForSnapshotLoadIndex;
4547             auto res = sBoxedHandleManager.addFixed(handle, item, typeTag);
4548             return res;
4549         } else {
4550             return sBoxedHandleManager.add(item, typeTag);
4551         }
4552     }
4553 
4554 #define DEFINE_BOXED_DISPATCHABLE_HANDLE_API_IMPL(type) \
4555     type new_boxed_##type(type underlying, VulkanDispatch* dispatch, bool ownDispatch) { \
4556         DispatchableHandleInfo<uint64_t> item; \
4557         item.underlying = (uint64_t)underlying; \
4558         item.dispatch = dispatch ? dispatch : new VulkanDispatch; \
4559         item.ownDispatch = ownDispatch; \
4560         item.ordMaintInfo = new OrderMaintenanceInfo; \
4561         item.readStream = nullptr; \
4562         auto res = (type)newGlobalHandle(item, Tag_##type); \
4563         return res; \
4564     } \
4565     void delete_##type(type boxed) { \
4566         if (!boxed) return; \
4567         auto elt = sBoxedHandleManager.get( \
4568                 (uint64_t)(uintptr_t)boxed); \
4569         if (!elt) return; \
4570         releaseOrderMaintInfo(elt->ordMaintInfo); \
4571         if (elt->readStream) { \
4572             sReadStreamRegistry.push(elt->readStream); \
4573             elt->readStream = nullptr; \
4574         } \
4575         sBoxedHandleManager.remove((uint64_t)boxed); \
4576     } \
4577     type unbox_##type(type boxed) { \
4578         auto elt = sBoxedHandleManager.get( \
4579                 (uint64_t)(uintptr_t)boxed); \
4580         if (!elt) return VK_NULL_HANDLE; \
4581         return (type)elt->underlying; \
4582     } \
4583     OrderMaintenanceInfo* ordmaint_##type(type boxed) { \
4584         auto elt = sBoxedHandleManager.get( \
4585                 (uint64_t)(uintptr_t)boxed); \
4586         if (!elt) return 0; \
4587         auto info = elt->ordMaintInfo; \
4588         if (!info) return 0; \
4589         acquireOrderMaintInfo(info); return info; \
4590     } \
4591     VulkanMemReadingStream* readstream_##type(type boxed) { \
4592         auto elt = sBoxedHandleManager.get( \
4593                 (uint64_t)(uintptr_t)boxed); \
4594         if (!elt) return 0; \
4595         auto stream = elt->readStream; \
4596         if (!stream) { \
4597             stream = sReadStreamRegistry.pop(); \
4598             elt->readStream = stream; \
4599         } \
4600         return stream; \
4601     } \
4602     type unboxed_to_boxed_##type(type unboxed) { \
4603         AutoLock lock(sBoxedHandleManager.lock); \
4604         return (type)sBoxedHandleManager.getBoxedFromUnboxedLocked( \
4605                 (uint64_t)(uintptr_t)unboxed); \
4606     } \
4607     VulkanDispatch* dispatch_##type(type boxed) { \
4608         auto elt = sBoxedHandleManager.get( \
4609                 (uint64_t)(uintptr_t)boxed); \
4610         if (!elt) { fprintf(stderr, "%s: err not found boxed %p\n", __func__, boxed); return nullptr; } \
4611         return elt->dispatch; \
4612     } \
4613 
4614 #define DEFINE_BOXED_NON_DISPATCHABLE_HANDLE_API_IMPL(type) \
4615     type new_boxed_non_dispatchable_##type(type underlying) { \
4616         DispatchableHandleInfo<uint64_t> item; \
4617         item.underlying = (uint64_t)underlying; \
4618         auto res = (type)newGlobalHandle(item, Tag_##type); \
4619         return res; \
4620     } \
4621     void delayed_delete_##type(type boxed, VkDevice device, std::function<void()> callback) { \
4622         sBoxedHandleManager.removeDelayed((uint64_t)boxed, device, callback); \
4623     } \
4624     void delete_##type(type boxed) { \
4625         sBoxedHandleManager.remove((uint64_t)boxed); \
4626     } \
4627     type unboxed_to_boxed_non_dispatchable_##type(type unboxed) { \
4628         AutoLock lock(sBoxedHandleManager.lock); \
4629         return (type)sBoxedHandleManager.getBoxedFromUnboxedLocked( \
4630                 (uint64_t)(uintptr_t)unboxed); \
4631     } \
4632     type unbox_##type(type boxed) { \
4633         auto elt = sBoxedHandleManager.get( \
4634                 (uint64_t)(uintptr_t)boxed); \
4635         if (!elt) { fprintf(stderr, "%s: unbox %p failed, not found\n", __func__, boxed); abort(); return VK_NULL_HANDLE; } \
4636         return (type)elt->underlying; \
4637     } \
4638 
4639     GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(DEFINE_BOXED_DISPATCHABLE_HANDLE_API_IMPL)
GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(DEFINE_BOXED_NON_DISPATCHABLE_HANDLE_API_IMPL)4640         GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(DEFINE_BOXED_NON_DISPATCHABLE_HANDLE_API_IMPL)
4641 
4642         VkDecoderSnapshot* snapshot() { return &mSnapshot; }
4643 
4644 private:
4645     static const bool kEmulateAstc = true;
isEmulatedExtension(const char * name) const4646     bool isEmulatedExtension(const char* name) const {
4647         for (auto emulatedExt : kEmulatedExtensions) {
4648             if (!strcmp(emulatedExt, name)) return true;
4649         }
4650         return false;
4651     }
4652 
supportEmulatedCompressedImageFormatProperty(VkFormat compressedFormat,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags)4653     bool supportEmulatedCompressedImageFormatProperty(
4654         VkFormat compressedFormat,
4655         VkImageType type,
4656         VkImageTiling tiling,
4657         VkImageUsageFlags usage,
4658         VkImageCreateFlags flags
4659     ) {
4660         // BUG: 139193497
4661         return !(usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
4662             && !(type == VK_IMAGE_TYPE_1D);
4663     }
4664 
4665     std::vector<const char*>
filteredExtensionNames(uint32_t count,const char * const * extNames)4666         filteredExtensionNames(
4667                 uint32_t count, const char* const* extNames) {
4668             std::vector<const char*> res;
4669             for (uint32_t i = 0; i < count; ++i) {
4670                 auto extName = extNames[i];
4671                 if (!isEmulatedExtension(extName)) {
4672                     res.push_back(extName);
4673                 }
4674                 if (m_emu->instanceSupportsMoltenVK) {
4675                     continue;
4676                 }
4677                 if (!strcmp("VK_KHR_external_memory_capabilities", extName)) {
4678                     res.push_back("VK_KHR_external_memory_capabilities");
4679                 }
4680                 if (!strcmp("VK_KHR_external_memory", extName)) {
4681                     res.push_back("VK_KHR_external_memory");
4682                 }
4683                 if (!strcmp("VK_KHR_external_semaphore_capabilities", extName)) {
4684                     res.push_back("VK_KHR_external_semaphore_capabilities");
4685                 }
4686                 if (!strcmp("VK_KHR_external_semaphore", extName)) {
4687                     res.push_back("VK_KHR_external_semaphore");
4688                 }
4689                 if (!strcmp("VK_ANDROID_external_memory_android_hardware_buffer", extName) ||
4690                     !strcmp("VK_FUCHSIA_external_memory", extName)) {
4691 #ifdef _WIN32
4692                     res.push_back("VK_KHR_external_memory_win32");
4693 #else
4694                     res.push_back("VK_KHR_external_memory_fd");
4695 #endif
4696                 }
4697                 // External semaphore maps to the win32 version on windows,
4698                 // continues with external semaphore fd on non-windows
4699                 if (!strcmp("VK_KHR_external_semaphore_fd", extName)) {
4700 #ifdef _WIN32
4701                     res.push_back("VK_KHR_external_semaphore_win32");
4702 #else
4703                     res.push_back("VK_KHR_external_semaphore_fd");
4704 #endif
4705                 }
4706             }
4707             return res;
4708         }
4709 
memPropsOfDeviceLocked(VkDevice device)4710     VkPhysicalDeviceMemoryProperties* memPropsOfDeviceLocked(VkDevice device) {
4711         auto physdev = android::base::find(mDeviceToPhysicalDevice, device);
4712         if (!physdev) return nullptr;
4713 
4714         auto physdevInfo = android::base::find(mPhysdevInfo, *physdev);
4715         if (!physdevInfo) return nullptr;
4716 
4717         return &physdevInfo->memoryProperties;
4718     }
4719 
queueFamilyIndexOfQueueLocked(VkQueue queue)4720     Optional<uint32_t> queueFamilyIndexOfQueueLocked(VkQueue queue) {
4721         auto info = android::base::find(mQueueInfo, queue);
4722         if (!info) return {};
4723 
4724         return info->queueFamilyIndex;
4725     }
4726 
getDefaultQueueForDeviceLocked(VkDevice device,VkQueue * queue,uint32_t * queueFamilyIndex)4727     bool getDefaultQueueForDeviceLocked(
4728             VkDevice device, VkQueue* queue, uint32_t* queueFamilyIndex) {
4729 
4730         auto deviceInfo = android::base::find(mDeviceInfo, device);
4731         if (!deviceInfo) return false;
4732 
4733         auto zeroIt = deviceInfo->queues.find(0);
4734         if (zeroIt == deviceInfo->queues.end() ||
4735                 zeroIt->second.size() == 0) {
4736             // Get the first queue / queueFamilyIndex
4737             // that does show up.
4738             for (auto it : deviceInfo->queues) {
4739                 auto index = it.first;
4740                 for (auto deviceQueue : it.second) {
4741                     *queue = deviceQueue;
4742                     *queueFamilyIndex = index;
4743                     return true;
4744                 }
4745             }
4746             // Didn't find anything, fail.
4747             return false;
4748         } else {
4749             // Use queue family index 0.
4750             *queue = zeroIt->second[0];
4751             *queueFamilyIndex = 0;
4752             return true;
4753         }
4754 
4755         return false;
4756     }
4757 
loadDecompressionShaderSource(const char * filename)4758     static SpvFileEntry loadDecompressionShaderSource(const char* filename) {
4759         size_t numDecompressionShaderFileEntries = arraySize(sDecompressionShaderFileEntries);
4760 
4761         for (size_t i = 0; i < numDecompressionShaderFileEntries; ++i) {
4762             if (!strcmp(filename, sDecompressionShaderFileEntries[i].name)) {
4763                 return sDecompressionShaderFileEntries[i];
4764             }
4765         }
4766 
4767         SpvFileEntry invalid = {
4768             filename, nullptr, 0,
4769         };
4770         fprintf(stderr, "WARNING: shader source open failed! %s\n",
4771                 filename);
4772         return invalid;
4773     }
4774 
4775     struct CompressedImageInfo {
4776         bool isCompressed = false;
4777         bool isEtc2 = false;
4778         bool isAstc = false;
4779         VkDevice device = 0;
4780         VkFormat compFormat;  // The compressed format
4781         VkImageType imageType;
4782         VkImageCreateInfo sizeCompImgCreateInfo;
4783         std::vector<uint32_t> sizeCompImgQueueFamilyIndices;
4784         VkFormat sizeCompFormat;  // Size compatible format
4785         VkDeviceSize alignment = 0;
4786         std::vector<VkDeviceSize> memoryOffsets = {};
4787         std::vector<VkImage> sizeCompImgs;  // Size compatible images
4788         VkFormat decompFormat =
4789             VK_FORMAT_R8G8B8A8_UNORM;  // Decompressed format
4790         VkImage decompImg = 0;  // Decompressed image
4791         VkExtent3D extent;
4792         uint32_t compressedBlockWidth = 1;
4793         uint32_t compressedBlockHeight = 1;
4794         uint32_t layerCount;
4795         uint32_t mipLevels = 1;
mipmapWidthgoldfish_vk::VkDecoderGlobalState::Impl::CompressedImageInfo4796         uint32_t mipmapWidth(uint32_t level) {
4797             return std::max<uint32_t>(extent.width >> level, 1);
4798         }
mipmapHeightgoldfish_vk::VkDecoderGlobalState::Impl::CompressedImageInfo4799         uint32_t mipmapHeight(uint32_t level) {
4800             return std::max<uint32_t>(extent.height >> level, 1);
4801         }
mipmapDepthgoldfish_vk::VkDecoderGlobalState::Impl::CompressedImageInfo4802         uint32_t mipmapDepth(uint32_t level) {
4803             return std::max<uint32_t>(extent.depth >> level, 1);
4804         }
sizeCompMipmapWidthgoldfish_vk::VkDecoderGlobalState::Impl::CompressedImageInfo4805         uint32_t sizeCompMipmapWidth(uint32_t level) {
4806             return (mipmapWidth(level) + compressedBlockWidth - 1) /
4807                    compressedBlockWidth;
4808         }
sizeCompMipmapHeightgoldfish_vk::VkDecoderGlobalState::Impl::CompressedImageInfo4809         uint32_t sizeCompMipmapHeight(uint32_t level) {
4810             if (imageType != VK_IMAGE_TYPE_1D) {
4811                 return (mipmapHeight(level) + compressedBlockHeight - 1) /
4812                        compressedBlockHeight;
4813             } else {
4814                 return 1;
4815             }
4816         }
sizeCompMipmapDepthgoldfish_vk::VkDecoderGlobalState::Impl::CompressedImageInfo4817         uint32_t sizeCompMipmapDepth(uint32_t level) {
4818             return mipmapDepth(level);
4819         }
decompPixelSizegoldfish_vk::VkDecoderGlobalState::Impl::CompressedImageInfo4820         VkDeviceSize decompPixelSize() {
4821             return getLinearFormatPixelSize(decompFormat);
4822         }
needEmulatedAlphagoldfish_vk::VkDecoderGlobalState::Impl::CompressedImageInfo4823         bool needEmulatedAlpha() {
4824             if (!isCompressed) {
4825                 return false;
4826             }
4827             switch (compFormat) {
4828                 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
4829                 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
4830                     return true;
4831                 default:
4832                     return false;
4833             }
4834         }
4835 
4836         struct Etc2PushConstant {
4837             uint32_t compFormat;
4838             uint32_t baseLayer;
4839         };
4840 
4841         struct AstcPushConstant {
4842             uint32_t blockSize[2];
4843             uint32_t compFormat;
4844             uint32_t baseLayer;
4845             uint32_t sRGB;
4846             uint32_t smallBlock;
4847         };
4848         VkDescriptorSetLayout decompDescriptorSetLayout = 0;
4849         VkDescriptorPool decompDescriptorPool = 0;
4850         std::vector<VkDescriptorSet> decompDescriptorSets = {};
4851         VkShaderModule decompShader = 0;
4852         VkPipelineLayout decompPipelineLayout = 0;
4853         VkPipeline decompPipeline = 0;
4854         std::vector<VkImageView> sizeCompImageViews = {};
4855         std::vector<VkImageView> decompImageViews = {};
4856 
createDefaultImageViewgoldfish_vk::VkDecoderGlobalState::Impl::CompressedImageInfo4857         static VkImageView createDefaultImageView(
4858                 goldfish_vk::VulkanDispatch* vk,
4859                 VkDevice device,
4860                 VkImage image,
4861                 VkFormat format,
4862                 VkImageType imageType,
4863                 uint32_t mipLevel,
4864                 uint32_t layerCount) {
4865             VkImageViewCreateInfo imageViewInfo = {};
4866             imageViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
4867             imageViewInfo.image = image;
4868             switch (imageType) {
4869                 case VK_IMAGE_TYPE_1D:
4870                     imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_1D_ARRAY;
4871                     break;
4872                 case VK_IMAGE_TYPE_2D:
4873                     imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
4874                     break;
4875                 case VK_IMAGE_TYPE_3D:
4876                     imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_3D;
4877                     break;
4878                 default:
4879                     imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
4880                     break;
4881             }
4882             imageViewInfo.format = format;
4883             imageViewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
4884             imageViewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
4885             imageViewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
4886             imageViewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
4887             imageViewInfo.subresourceRange.aspectMask =
4888                 VK_IMAGE_ASPECT_COLOR_BIT;
4889             imageViewInfo.subresourceRange.baseMipLevel = mipLevel;
4890             imageViewInfo.subresourceRange.levelCount = 1;
4891             imageViewInfo.subresourceRange.baseArrayLayer = 0;
4892             imageViewInfo.subresourceRange.layerCount = layerCount;
4893             VkImageView imageView;
4894             if (VK_SUCCESS != vk->vkCreateImageView(device, &imageViewInfo,
4895                         nullptr, &imageView)) {
4896                 fprintf(stderr, "Warning: %s %s:%d failure\n", __func__,
4897                         __FILE__, __LINE__);
4898                 return 0;
4899             }
4900             return imageView;
4901         }
4902 
initDecompgoldfish_vk::VkDecoderGlobalState::Impl::CompressedImageInfo4903         VkResult initDecomp(goldfish_vk::VulkanDispatch* vk,
4904                 VkDevice device,
4905                 VkImage image) {
4906             if (decompPipeline != 0) {
4907                 return VK_SUCCESS;
4908             }
4909             // TODO: release resources on failure
4910 
4911 #define _RETURN_ON_FAILURE(cmd)                                                \
4912             {                                                                          \
4913                 VkResult result = cmd;                                                 \
4914                 if (VK_SUCCESS != result) {                                            \
4915                     fprintf(stderr, "Warning: %s %s:%d vulkan failure %d\n", __func__, \
4916                             __FILE__, __LINE__, result);                               \
4917                     return (result);                                                   \
4918                 }                                                                      \
4919             }
4920 
4921             std::string shaderSrcFileName;
4922             switch (compFormat) {
4923                 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
4924                 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
4925                 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
4926                 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
4927                     shaderSrcFileName = "Etc2RGB8_";
4928                     break;
4929                 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
4930                 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
4931                     shaderSrcFileName = "Etc2RGBA8_";
4932                     break;
4933                 case VK_FORMAT_EAC_R11_UNORM_BLOCK:
4934                     shaderSrcFileName = "EacR11Unorm_";
4935                     break;
4936                 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
4937                     shaderSrcFileName = "EacR11Snorm_";
4938                     break;
4939                 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
4940                     shaderSrcFileName = "EacRG11Unorm_";
4941                     break;
4942                 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
4943                     shaderSrcFileName = "EacRG11Snorm_";
4944                     break;
4945                 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
4946                 case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
4947                 case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
4948                 case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
4949                 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
4950                 case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
4951                 case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
4952                 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
4953                 case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
4954                 case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
4955                 case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
4956                 case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
4957                 case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
4958                 case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
4959                 case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
4960                 case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
4961                 case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
4962                 case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
4963                 case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
4964                 case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
4965                 case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
4966                 case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
4967                 case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
4968                 case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
4969                 case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
4970                 case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
4971                 case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
4972                 case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
4973                     shaderSrcFileName = "Astc_";
4974                     break;
4975                 default:
4976                     shaderSrcFileName = "Etc2RGB8_";
4977                     break;
4978             }
4979             if (imageType == VK_IMAGE_TYPE_1D) {
4980                 shaderSrcFileName += "1DArray.spv";
4981             } else if (imageType == VK_IMAGE_TYPE_3D) {
4982                 shaderSrcFileName += "3D.spv";
4983             } else {
4984                 shaderSrcFileName += "2DArray.spv";
4985             }
4986 
4987             SpvFileEntry shaderSource = VkDecoderGlobalState::Impl::loadDecompressionShaderSource(
4988                     shaderSrcFileName.c_str());
4989 
4990             if (!shaderSource.size)  {
4991                 return VK_ERROR_OUT_OF_HOST_MEMORY;
4992             }
4993 
4994             VkShaderModuleCreateInfo shaderInfo = {};
4995             shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
4996             shaderInfo.codeSize = shaderSource.size;
4997             // DecompressionShaders.h declares everything as aligned to 4 bytes,
4998             // so it is safe to cast
4999             shaderInfo.pCode =
5000                 reinterpret_cast<const uint32_t*>(shaderSource.base);
5001             _RETURN_ON_FAILURE(vk->vkCreateShaderModule(
5002                         device, &shaderInfo, nullptr, &decompShader));
5003 
5004             VkDescriptorSetLayoutBinding dsLayoutBindings[] = {
5005                 {
5006                     0,                                 // bindings
5007                     VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,  // descriptorType
5008                     1,                            // descriptorCount
5009                     VK_SHADER_STAGE_COMPUTE_BIT,  // stageFlags
5010                     0,                            // pImmutableSamplers
5011                 },
5012                 {
5013                     1,                                 // bindings
5014                     VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,  // descriptorType
5015                     1,                            // descriptorCount
5016                     VK_SHADER_STAGE_COMPUTE_BIT,  // stageFlags
5017                     0,                            // pImmutableSamplers
5018                 },
5019             };
5020             VkDescriptorSetLayoutCreateInfo dsLayoutInfo = {};
5021             dsLayoutInfo.sType =
5022                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
5023             dsLayoutInfo.bindingCount = sizeof(dsLayoutBindings) /
5024                 sizeof(VkDescriptorSetLayoutBinding);
5025             dsLayoutInfo.pBindings = dsLayoutBindings;
5026             _RETURN_ON_FAILURE(vk->vkCreateDescriptorSetLayout(
5027                         device, &dsLayoutInfo, nullptr,
5028                         &decompDescriptorSetLayout));
5029 
5030             VkDescriptorPoolSize poolSize[1] = {
5031                 {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2 * mipLevels},
5032             };
5033             VkDescriptorPoolCreateInfo dsPoolInfo = {};
5034             dsPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
5035             dsPoolInfo.flags =
5036                 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
5037             dsPoolInfo.maxSets = mipLevels;
5038             dsPoolInfo.poolSizeCount = 1;
5039             dsPoolInfo.pPoolSizes = poolSize;
5040             _RETURN_ON_FAILURE(vk->vkCreateDescriptorPool(
5041                         device, &dsPoolInfo, nullptr, &decompDescriptorPool));
5042             std::vector<VkDescriptorSetLayout> layouts(
5043                     mipLevels, decompDescriptorSetLayout);
5044 
5045             VkDescriptorSetAllocateInfo dsInfo = {};
5046             dsInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
5047             dsInfo.descriptorPool = decompDescriptorPool;
5048             dsInfo.descriptorSetCount = mipLevels;
5049             dsInfo.pSetLayouts = layouts.data();
5050             decompDescriptorSets.resize(mipLevels);
5051             _RETURN_ON_FAILURE(vk->vkAllocateDescriptorSets(
5052                         device, &dsInfo, decompDescriptorSets.data()));
5053 
5054             VkPushConstantRange pushConstant = {};
5055             pushConstant.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
5056             pushConstant.offset = 0;
5057             if (isEtc2) {
5058                 pushConstant.size = sizeof(Etc2PushConstant);
5059             } else if (isAstc) {
5060                 pushConstant.size = sizeof(AstcPushConstant);
5061             }
5062 
5063             VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
5064             pipelineLayoutInfo.sType =
5065                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
5066             pipelineLayoutInfo.setLayoutCount = 1;
5067             pipelineLayoutInfo.pSetLayouts = &decompDescriptorSetLayout;
5068             pipelineLayoutInfo.pushConstantRangeCount = 1;
5069             pipelineLayoutInfo.pPushConstantRanges = &pushConstant;
5070             _RETURN_ON_FAILURE(
5071                     vk->vkCreatePipelineLayout(device, &pipelineLayoutInfo,
5072                         nullptr, &decompPipelineLayout));
5073 
5074             VkComputePipelineCreateInfo computePipelineInfo = {};
5075             computePipelineInfo.sType =
5076                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
5077             computePipelineInfo.stage.sType =
5078                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
5079             computePipelineInfo.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
5080             computePipelineInfo.stage.module = decompShader;
5081             computePipelineInfo.stage.pName = "main";
5082             computePipelineInfo.layout = decompPipelineLayout;
5083             _RETURN_ON_FAILURE(vk->vkCreateComputePipelines(
5084                         device, 0, 1, &computePipelineInfo, nullptr,
5085                         &decompPipeline));
5086 
5087             VkFormat intermediateFormat = decompFormat;
5088             switch (compFormat) {
5089                 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
5090                 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
5091                 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
5092                 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
5093                 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
5094                 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
5095                     intermediateFormat = VK_FORMAT_R8G8B8A8_UINT;
5096                     break;
5097                 case VK_FORMAT_EAC_R11_UNORM_BLOCK:
5098                 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
5099                 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
5100                 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
5101                     intermediateFormat = decompFormat;
5102                     break;
5103                 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
5104                 case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
5105                 case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
5106                 case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
5107                 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
5108                 case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
5109                 case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
5110                 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
5111                 case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
5112                 case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
5113                 case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
5114                 case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
5115                 case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
5116                 case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
5117                 case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
5118                 case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
5119                 case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
5120                 case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
5121                 case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
5122                 case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
5123                 case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
5124                 case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
5125                 case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
5126                 case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
5127                 case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
5128                 case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
5129                 case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
5130                 case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
5131                     intermediateFormat = VK_FORMAT_R8G8B8A8_UINT;
5132                     break;
5133                 default:
5134                     intermediateFormat = decompFormat;
5135                     break;  // should not happen
5136             }
5137 
5138             sizeCompImageViews.resize(mipLevels);
5139             decompImageViews.resize(mipLevels);
5140             VkDescriptorImageInfo sizeCompDescriptorImageInfo[1] = {{}};
5141             sizeCompDescriptorImageInfo[0].sampler = 0;
5142             sizeCompDescriptorImageInfo[0].imageLayout =
5143                 VK_IMAGE_LAYOUT_GENERAL;
5144 
5145             VkDescriptorImageInfo decompDescriptorImageInfo[1] = {{}};
5146             decompDescriptorImageInfo[0].sampler = 0;
5147             decompDescriptorImageInfo[0].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
5148 
5149             VkWriteDescriptorSet writeDescriptorSets[2] = {{}, {}};
5150             writeDescriptorSets[0].sType =
5151                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
5152             writeDescriptorSets[0].dstBinding = 0;
5153             writeDescriptorSets[0].descriptorCount = 1;
5154             writeDescriptorSets[0].descriptorType =
5155                 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
5156             writeDescriptorSets[0].pImageInfo = sizeCompDescriptorImageInfo;
5157 
5158             writeDescriptorSets[1].sType =
5159                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
5160             writeDescriptorSets[1].dstBinding = 1;
5161             writeDescriptorSets[1].descriptorCount = 1;
5162             writeDescriptorSets[1].descriptorType =
5163                 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
5164             writeDescriptorSets[1].pImageInfo = decompDescriptorImageInfo;
5165 
5166             for (uint32_t i = 0; i < mipLevels; i++) {
5167                 sizeCompImageViews[i] = createDefaultImageView(
5168                         vk, device, sizeCompImgs[i], sizeCompFormat, imageType,
5169                         0, layerCount);
5170                 decompImageViews[i] = createDefaultImageView(
5171                         vk, device, decompImg, intermediateFormat, imageType, i,
5172                         layerCount);
5173                 sizeCompDescriptorImageInfo[0].imageView =
5174                     sizeCompImageViews[i];
5175                 decompDescriptorImageInfo[0].imageView = decompImageViews[i];
5176                 writeDescriptorSets[0].dstSet = decompDescriptorSets[i];
5177                 writeDescriptorSets[1].dstSet = decompDescriptorSets[i];
5178                 vk->vkUpdateDescriptorSets(device, 2, writeDescriptorSets, 0,
5179                         nullptr);
5180             }
5181             return VK_SUCCESS;
5182         }
5183 
cmdDecompressgoldfish_vk::VkDecoderGlobalState::Impl::CompressedImageInfo5184         void cmdDecompress(goldfish_vk::VulkanDispatch* vk,
5185                 VkCommandBuffer commandBuffer,
5186                 VkPipelineStageFlags dstStageMask,
5187                 VkImageLayout newLayout,
5188                 VkAccessFlags dstAccessMask,
5189                 uint32_t baseMipLevel,
5190                 uint32_t levelCount,
5191                 uint32_t baseLayer,
5192                 uint32_t _layerCount) {
5193             vk->vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE,
5194                     decompPipeline);
5195             int dispatchZ = _layerCount;
5196 
5197             if (isEtc2) {
5198                 Etc2PushConstant pushConstant = {(uint32_t)compFormat, baseLayer};
5199                 if (extent.depth > 1) {
5200                     // 3D texture
5201                     pushConstant.baseLayer = 0;
5202                     dispatchZ = extent.depth;
5203                 }
5204                 vk->vkCmdPushConstants(commandBuffer, decompPipelineLayout,
5205                                        VK_SHADER_STAGE_COMPUTE_BIT, 0,
5206                                        sizeof(pushConstant), &pushConstant);
5207             } else if (isAstc) {
5208                 uint32_t srgb = false;
5209                 uint32_t smallBlock = false;
5210                 switch (compFormat) {
5211                     case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
5212                     case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
5213                     case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
5214                     case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
5215                     case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
5216                     case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
5217                     case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
5218                     case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
5219                     case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
5220                     case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
5221                     case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
5222                     case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
5223                     case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
5224                     case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
5225                         srgb = true;
5226                         break;
5227                     default:
5228                         break;
5229                 }
5230                 switch (compFormat) {
5231                     case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
5232                     case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
5233                     case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
5234                     case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
5235                     case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
5236                     case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
5237                     case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
5238                     case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
5239                         smallBlock = true;
5240                         break;
5241                     default:
5242                         break;
5243                 }
5244                 AstcPushConstant pushConstant = {
5245                         {compressedBlockWidth, compressedBlockHeight},
5246                         (uint32_t)compFormat,
5247                         baseLayer,
5248                         srgb,
5249                         smallBlock,
5250                 };
5251                 if (extent.depth > 1) {
5252                     // 3D texture
5253                     pushConstant.baseLayer = 0;
5254                     dispatchZ = extent.depth;
5255                 }
5256                 vk->vkCmdPushConstants(commandBuffer, decompPipelineLayout,
5257                                        VK_SHADER_STAGE_COMPUTE_BIT, 0,
5258                                        sizeof(pushConstant), &pushConstant);
5259             }
5260             for (uint32_t i = baseMipLevel; i < baseMipLevel + levelCount;
5261                     i++) {
5262                 vk->vkCmdBindDescriptorSets(
5263                         commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE,
5264                         decompPipelineLayout, 0, 1,
5265                         decompDescriptorSets.data() + i, 0, nullptr);
5266 
5267                 vk->vkCmdDispatch(commandBuffer, sizeCompMipmapWidth(i),
5268                                   sizeCompMipmapHeight(i), dispatchZ);
5269             }
5270         }
5271     };
5272 
createSizeCompImages(goldfish_vk::VulkanDispatch * vk,CompressedImageInfo * cmpInfo)5273     void createSizeCompImages(goldfish_vk::VulkanDispatch* vk,
5274             CompressedImageInfo* cmpInfo) {
5275         if (cmpInfo->sizeCompImgs.size() > 0) {
5276             return;
5277         }
5278         VkDevice device = cmpInfo->device;
5279         uint32_t mipLevels = cmpInfo->mipLevels;
5280         cmpInfo->sizeCompImgs.resize(mipLevels);
5281         VkImageCreateInfo imageInfo = cmpInfo->sizeCompImgCreateInfo;
5282         imageInfo.mipLevels = 1;
5283         for (uint32_t i = 0; i < mipLevels; i++) {
5284             imageInfo.extent.width = cmpInfo->sizeCompMipmapWidth(i);
5285             imageInfo.extent.height = cmpInfo->sizeCompMipmapHeight(i);
5286             imageInfo.extent.depth = cmpInfo->sizeCompMipmapDepth(i);
5287             VkDevice device = cmpInfo->device;
5288             vk->vkCreateImage(device, &imageInfo, nullptr,
5289                     cmpInfo->sizeCompImgs.data() + i);
5290         }
5291 
5292         VkPhysicalDevice physicalDevice = mDeviceInfo[device].physicalDevice;
5293         int32_t memIdx = -1;
5294         VkDeviceSize& alignment = cmpInfo->alignment;
5295         std::vector<VkDeviceSize> memSizes(mipLevels);
5296         VkDeviceSize decompImageSize = 0;
5297         {
5298             VkMemoryRequirements memRequirements;
5299             vk->vkGetImageMemoryRequirements(device, cmpInfo->decompImg,
5300                     &memRequirements);
5301             memIdx = findProperties(physicalDevice,
5302                     memRequirements.memoryTypeBits,
5303                     VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
5304             if (memIdx < 0) {
5305                 fprintf(stderr, "Error: cannot find memory property!\n");
5306                 return;
5307             }
5308             alignment = std::max(alignment, memRequirements.alignment);
5309             decompImageSize = memRequirements.size;
5310         }
5311         for (size_t i = 0; i < mipLevels; i++) {
5312             VkMemoryRequirements memRequirements;
5313             vk->vkGetImageMemoryRequirements(device, cmpInfo->sizeCompImgs[i],
5314                     &memRequirements);
5315             alignment = std::max(alignment, memRequirements.alignment);
5316             memSizes[i] = memRequirements.size;
5317         }
5318         auto& memoryOffsets = cmpInfo->memoryOffsets;
5319         memoryOffsets.resize(mipLevels + 1);
5320         {
5321             VkDeviceSize alignedSize = decompImageSize;
5322             if (alignment != 0) {
5323                 alignedSize =
5324                     (alignedSize + alignment - 1) / alignment * alignment;
5325             }
5326             memoryOffsets[0] = alignedSize;
5327         }
5328         for (size_t i = 0; i < cmpInfo->sizeCompImgs.size(); i++) {
5329             VkDeviceSize alignedSize = memSizes[i];
5330             if (alignment != 0) {
5331                 alignedSize =
5332                     (alignedSize + alignment - 1) / alignment * alignment;
5333             }
5334             memoryOffsets[i + 1] = memoryOffsets[i] + alignedSize;
5335         }
5336     }
5337 
updateImageMemorySizeLocked(VkDevice device,VkImage image,VkMemoryRequirements * pMemoryRequirements)5338     void updateImageMemorySizeLocked(
5339             VkDevice device,
5340             VkImage image,
5341             VkMemoryRequirements* pMemoryRequirements) {
5342         auto deviceInfoIt = mDeviceInfo.find(device);
5343         if (!deviceInfoIt->second.emulateTextureEtc2 &&
5344             !deviceInfoIt->second.emulateTextureAstc) {
5345             return;
5346         }
5347         auto it = mImageInfo.find(image);
5348         if (it == mImageInfo.end()) {
5349             return;
5350         }
5351         CompressedImageInfo& cmpInfo = it->second.cmpInfo;
5352         if (!deviceInfoIt->second.needEmulatedDecompression(cmpInfo)) {
5353             return;
5354         }
5355         pMemoryRequirements->alignment =
5356             std::max(pMemoryRequirements->alignment, cmpInfo.alignment);
5357         pMemoryRequirements->size += cmpInfo.memoryOffsets[cmpInfo.mipLevels];
5358     }
5359 
needEmulatedEtc2(VkPhysicalDevice physicalDevice,goldfish_vk::VulkanDispatch * vk)5360     static bool needEmulatedEtc2(VkPhysicalDevice physicalDevice,
5361             goldfish_vk::VulkanDispatch* vk) {
5362         VkPhysicalDeviceFeatures feature;
5363         vk->vkGetPhysicalDeviceFeatures(physicalDevice, &feature);
5364         return !feature.textureCompressionETC2;
5365     }
5366 
needEmulatedAstc(VkPhysicalDevice physicalDevice,goldfish_vk::VulkanDispatch * vk)5367     static bool needEmulatedAstc(VkPhysicalDevice physicalDevice,
5368                                  goldfish_vk::VulkanDispatch* vk) {
5369         if (!kEmulateAstc) {
5370             return false;
5371         }
5372         VkPhysicalDeviceFeatures feature;
5373         vk->vkGetPhysicalDeviceFeatures(physicalDevice, &feature);
5374         return !feature.textureCompressionASTC_LDR;
5375     }
5376 
getEtc2Format(VkFormat fmt)5377     static ETC2ImageFormat getEtc2Format(VkFormat fmt) {
5378         switch (fmt) {
5379             case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
5380             case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
5381                 return EtcRGB8;
5382             case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
5383             case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
5384                 return EtcRGBA8;
5385             case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
5386             case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
5387                 return EtcRGB8A1;
5388             case VK_FORMAT_EAC_R11_UNORM_BLOCK:
5389                 return EtcR11;
5390             case VK_FORMAT_EAC_R11_SNORM_BLOCK:
5391                 return EtcSignedR11;
5392             case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
5393                 return EtcRG11;
5394             case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
5395                 return EtcSignedRG11;
5396             default:
5397                 fprintf(stderr,
5398                         "TODO: unsupported compressed texture format %d\n",
5399                         fmt);
5400                 return EtcRGB8;
5401         }
5402     }
5403 
getDecompFormat(VkFormat compFmt)5404     static VkFormat getDecompFormat(VkFormat compFmt) {
5405         switch (compFmt) {
5406             case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
5407             case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
5408             case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
5409                 return VK_FORMAT_R8G8B8A8_UNORM;
5410             case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
5411             case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
5412             case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
5413                 return VK_FORMAT_R8G8B8A8_SRGB;
5414             case VK_FORMAT_EAC_R11_UNORM_BLOCK:
5415                 return VK_FORMAT_R16_UNORM;
5416             case VK_FORMAT_EAC_R11_SNORM_BLOCK:
5417                 return VK_FORMAT_R16_SNORM;
5418             case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
5419                 return VK_FORMAT_R16G16_UNORM;
5420             case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
5421                 return VK_FORMAT_R16G16_SNORM;
5422             case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
5423             case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
5424             case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
5425             case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
5426             case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
5427             case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
5428             case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
5429             case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
5430             case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
5431             case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
5432             case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
5433             case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
5434             case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
5435             case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
5436                 return VK_FORMAT_R8G8B8A8_UNORM;
5437             case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
5438             case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
5439             case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
5440             case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
5441             case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
5442             case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
5443             case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
5444             case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
5445             case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
5446             case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
5447             case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
5448             case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
5449             case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
5450             case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
5451                 return VK_FORMAT_R8G8B8A8_SRGB;
5452             default:
5453                 return compFmt;
5454         }
5455     }
5456 
getSizeCompFormat(VkFormat compFmt)5457     VkFormat getSizeCompFormat(VkFormat compFmt) {
5458         switch (compFmt) {
5459             case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
5460             case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
5461             case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
5462             case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
5463                 return VK_FORMAT_R16G16B16A16_UINT;
5464             case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
5465             case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
5466                 return VK_FORMAT_R32G32B32A32_UINT;
5467             case VK_FORMAT_EAC_R11_UNORM_BLOCK:
5468             case VK_FORMAT_EAC_R11_SNORM_BLOCK:
5469                 return VK_FORMAT_R32G32_UINT;
5470             case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
5471             case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
5472                 return VK_FORMAT_R32G32B32A32_UINT;
5473             case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
5474             case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
5475             case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
5476             case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
5477             case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
5478             case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
5479             case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
5480             case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
5481             case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
5482             case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
5483             case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
5484             case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
5485             case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
5486             case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
5487             case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
5488             case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
5489             case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
5490             case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
5491             case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
5492             case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
5493             case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
5494             case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
5495             case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
5496             case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
5497             case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
5498             case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
5499             case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
5500             case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
5501                 return VK_FORMAT_R32G32B32A32_UINT;
5502             default:
5503                 return compFmt;
5504         }
5505     }
5506 
isEtc2Compatible(VkFormat compFmt1,VkFormat compFmt2)5507     bool isEtc2Compatible(VkFormat compFmt1, VkFormat compFmt2) {
5508         const VkFormat kCmpSets[][2] = {
5509             {VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
5510                 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK},
5511             {VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
5512                 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK},
5513             {VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
5514                 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK},
5515             {VK_FORMAT_EAC_R11_UNORM_BLOCK, VK_FORMAT_EAC_R11_SNORM_BLOCK},
5516             {VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
5517                 VK_FORMAT_EAC_R11G11_SNORM_BLOCK},
5518         };
5519         if (compFmt1 == compFmt2) {
5520             return true;
5521         }
5522         for (auto& cmpSet : kCmpSets) {
5523             if (compFmt1 == cmpSet[0] || compFmt1 == cmpSet[1]) {
5524                 return compFmt2 == cmpSet[0] || compFmt2 == cmpSet[1];
5525             }
5526         }
5527         return false;
5528     }
createCompressedImageInfo(VkFormat compFmt)5529     CompressedImageInfo createCompressedImageInfo(VkFormat compFmt) {
5530         CompressedImageInfo cmpInfo;
5531         cmpInfo.compFormat = compFmt;
5532         cmpInfo.decompFormat = getDecompFormat(compFmt);
5533         cmpInfo.sizeCompFormat = getSizeCompFormat(compFmt);
5534         cmpInfo.isCompressed = (cmpInfo.decompFormat != compFmt);
5535 
5536         if (cmpInfo.isCompressed) {
5537             switch (compFmt) {
5538                 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
5539                 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
5540                 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
5541                 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
5542                 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
5543                 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
5544                 case VK_FORMAT_EAC_R11_UNORM_BLOCK:
5545                 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
5546                 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
5547                 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
5548                     cmpInfo.compressedBlockWidth = 4;
5549                     cmpInfo.compressedBlockHeight = 4;
5550                     cmpInfo.isEtc2 = true;
5551                     break;
5552                 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
5553                 case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
5554                     cmpInfo.compressedBlockWidth = 4;
5555                     cmpInfo.compressedBlockHeight = 4;
5556                     cmpInfo.isAstc = true;
5557                     break;
5558                 case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
5559                 case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
5560                     cmpInfo.compressedBlockWidth = 5;
5561                     cmpInfo.compressedBlockHeight = 4;
5562                     cmpInfo.isAstc = true;
5563                     break;
5564                 case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
5565                 case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
5566                     cmpInfo.compressedBlockWidth = 5;
5567                     cmpInfo.compressedBlockHeight = 5;
5568                     cmpInfo.isAstc = true;
5569                     break;
5570                 case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
5571                 case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
5572                     cmpInfo.compressedBlockWidth = 6;
5573                     cmpInfo.compressedBlockHeight = 5;
5574                     cmpInfo.isAstc = true;
5575                     break;
5576                 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
5577                 case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
5578                     cmpInfo.compressedBlockWidth = 6;
5579                     cmpInfo.compressedBlockHeight = 6;
5580                     cmpInfo.isAstc = true;
5581                     break;
5582                 case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
5583                 case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
5584                     cmpInfo.compressedBlockWidth = 8;
5585                     cmpInfo.compressedBlockHeight = 5;
5586                     cmpInfo.isAstc = true;
5587                     break;
5588                 case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
5589                 case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
5590                     cmpInfo.compressedBlockWidth = 8;
5591                     cmpInfo.compressedBlockHeight = 6;
5592                     cmpInfo.isAstc = true;
5593                     break;
5594                 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
5595                 case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
5596                     cmpInfo.compressedBlockWidth = 8;
5597                     cmpInfo.compressedBlockHeight = 8;
5598                     cmpInfo.isAstc = true;
5599                     break;
5600                 case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
5601                 case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
5602                     cmpInfo.compressedBlockWidth = 10;
5603                     cmpInfo.compressedBlockHeight = 5;
5604                     cmpInfo.isAstc = true;
5605                     break;
5606                 case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
5607                 case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
5608                     cmpInfo.compressedBlockWidth = 10;
5609                     cmpInfo.compressedBlockHeight = 6;
5610                     cmpInfo.isAstc = true;
5611                     break;
5612                 case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
5613                 case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
5614                     cmpInfo.compressedBlockWidth = 10;
5615                     cmpInfo.compressedBlockHeight = 8;
5616                     cmpInfo.isAstc = true;
5617                     break;
5618                 case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
5619                 case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
5620                     cmpInfo.compressedBlockWidth = 10;
5621                     cmpInfo.compressedBlockHeight = 10;
5622                     cmpInfo.isAstc = true;
5623                     break;
5624                 case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
5625                 case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
5626                     cmpInfo.compressedBlockWidth = 12;
5627                     cmpInfo.compressedBlockHeight = 10;
5628                     cmpInfo.isAstc = true;
5629                     break;
5630                 case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
5631                 case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
5632                     cmpInfo.compressedBlockWidth = 12;
5633                     cmpInfo.compressedBlockHeight = 12;
5634                     cmpInfo.isAstc = true;
5635                     break;
5636                 default:
5637                     break;
5638             }
5639         }
5640 
5641         return cmpInfo;
5642     }
5643 
5644     static const VkFormatFeatureFlags kEmulatedEtc2BufferFeatureMask =
5645         VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
5646         VK_FORMAT_FEATURE_BLIT_SRC_BIT |
5647         VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
5648 
maskFormatPropertiesForEmulatedEtc2(VkFormatProperties * pFormatProperties)5649     void maskFormatPropertiesForEmulatedEtc2(
5650             VkFormatProperties* pFormatProperties) {
5651         pFormatProperties->bufferFeatures &= kEmulatedEtc2BufferFeatureMask;
5652         pFormatProperties->optimalTilingFeatures &= kEmulatedEtc2BufferFeatureMask;
5653     }
5654 
maskFormatPropertiesForEmulatedEtc2(VkFormatProperties2 * pFormatProperties)5655     void maskFormatPropertiesForEmulatedEtc2(
5656             VkFormatProperties2* pFormatProperties) {
5657         pFormatProperties->formatProperties.bufferFeatures &=
5658             kEmulatedEtc2BufferFeatureMask;
5659         pFormatProperties->formatProperties.optimalTilingFeatures &=
5660             kEmulatedEtc2BufferFeatureMask;
5661     }
5662 
5663     template <class VkFormatProperties1or2>
getPhysicalDeviceFormatPropertiesCore(std::function<void (VkPhysicalDevice,VkFormat,VkFormatProperties1or2 *)> getPhysicalDeviceFormatPropertiesFunc,goldfish_vk::VulkanDispatch * vk,VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties1or2 * pFormatProperties)5664         void getPhysicalDeviceFormatPropertiesCore(
5665                 std::function<
5666                 void(VkPhysicalDevice, VkFormat, VkFormatProperties1or2*)>
5667                 getPhysicalDeviceFormatPropertiesFunc,
5668                 goldfish_vk::VulkanDispatch* vk,
5669                 VkPhysicalDevice physicalDevice,
5670                 VkFormat format,
5671                 VkFormatProperties1or2* pFormatProperties) {
5672             switch (format) {
5673                 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
5674                 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
5675                 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
5676                 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
5677                 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
5678                 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
5679                 case VK_FORMAT_EAC_R11_UNORM_BLOCK:
5680                 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
5681                 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
5682                 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: {
5683                     if (!needEmulatedEtc2(physicalDevice, vk)) {
5684                         // Hardware supported ETC2
5685                         getPhysicalDeviceFormatPropertiesFunc(
5686                                 physicalDevice, format, pFormatProperties);
5687                         return;
5688                     }
5689                     // Emulate ETC formats
5690                     CompressedImageInfo cmpInfo =
5691                             createCompressedImageInfo(format);
5692                     getPhysicalDeviceFormatPropertiesFunc(physicalDevice,
5693                                                           cmpInfo.decompFormat,
5694                                                           pFormatProperties);
5695                     maskFormatPropertiesForEmulatedEtc2(pFormatProperties);
5696                     break;
5697                 }
5698                 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
5699                 case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
5700                 case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
5701                 case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
5702                 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
5703                 case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
5704                 case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
5705                 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
5706                 case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
5707                 case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
5708                 case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
5709                 case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
5710                 case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
5711                 case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
5712                 case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
5713                 case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
5714                 case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
5715                 case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
5716                 case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
5717                 case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
5718                 case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
5719                 case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
5720                 case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
5721                 case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
5722                 case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
5723                 case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
5724                 case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
5725                 case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: {
5726                     if (!needEmulatedAstc(physicalDevice, vk)) {
5727                         // Hardware supported ETC2
5728                         getPhysicalDeviceFormatPropertiesFunc(
5729                                 physicalDevice, format, pFormatProperties);
5730                         return;
5731                     }
5732                     // Emulate ETC formats
5733                     CompressedImageInfo cmpInfo =
5734                             createCompressedImageInfo(format);
5735                     getPhysicalDeviceFormatPropertiesFunc(physicalDevice,
5736                                                           cmpInfo.decompFormat,
5737                                                           pFormatProperties);
5738                     maskFormatPropertiesForEmulatedEtc2(pFormatProperties);
5739                     break;
5740                 }
5741                 default:
5742                     getPhysicalDeviceFormatPropertiesFunc(
5743                             physicalDevice, format, pFormatProperties);
5744                     break;
5745             }
5746         }
5747 
5748 
executePreprocessRecursive(int level,VkCommandBuffer cmdBuffer)5749     void executePreprocessRecursive(int level, VkCommandBuffer cmdBuffer) {
5750         auto cmdBufferIt = mCmdBufferInfo.find(cmdBuffer);
5751         if (cmdBufferIt == mCmdBufferInfo.end()) {
5752             return;
5753         }
5754         for (const auto& func : cmdBufferIt->second.preprocessFuncs) {
5755             func();
5756         }
5757         // TODO: fix
5758         // for (const auto& subCmd : cmdBufferIt->second.subCmds) {
5759         // executePreprocessRecursive(level + 1, subCmd);
5760         // }
5761     }
5762 
teardownInstanceLocked(VkInstance instance)5763     void teardownInstanceLocked(VkInstance instance) {
5764 
5765         std::vector<VkDevice> devicesToDestroy;
5766         std::vector<VulkanDispatch*> devicesToDestroyDispatches;
5767 
5768         for (auto it : mDeviceToPhysicalDevice) {
5769             auto otherInstance = android::base::find(mPhysicalDeviceToInstance, it.second);
5770             if (!otherInstance) continue;
5771 
5772             if (instance == *otherInstance) {
5773                 devicesToDestroy.push_back(it.first);
5774                 devicesToDestroyDispatches.push_back(
5775                         dispatch_VkDevice(
5776                             mDeviceInfo[it.first].boxed));
5777             }
5778         }
5779 
5780         for (uint32_t i = 0; i < devicesToDestroy.size(); ++i) {
5781             // https://bugs.chromium.org/p/chromium/issues/detail?id=1074600
5782             // it's important to idle the device before destroying it!
5783             devicesToDestroyDispatches[i]->vkDeviceWaitIdle(devicesToDestroy[i]);
5784             {
5785                 std::vector<VkDeviceMemory> toDestroy;
5786                 auto it = mMapInfo.begin();
5787                 while (it != mMapInfo.end()) {
5788                     if (it->second.device == devicesToDestroy[i]) {
5789                         toDestroy.push_back(it->first);
5790                     }
5791                     ++it;
5792                 }
5793 
5794                 for (auto mem: toDestroy) {
5795                     freeMemoryLocked(devicesToDestroyDispatches[i],
5796                             devicesToDestroy[i],
5797                             mem, nullptr);
5798                 }
5799             }
5800 
5801             // Free all command buffers and command pools
5802             {
5803                 std::vector<VkCommandBuffer> toDestroy;
5804                 std::vector<VkCommandPool> toDestroyPools;
5805                 auto it = mCmdBufferInfo.begin();
5806                 while (it != mCmdBufferInfo.end()) {
5807                     if (it->second.device == devicesToDestroy[i]) {
5808                         toDestroy.push_back(it->first);
5809                         toDestroyPools.push_back(it->second.cmdPool);
5810                     }
5811                     ++it;
5812                 }
5813 
5814                 for (int j = 0; j < toDestroy.size(); ++j) {
5815                     devicesToDestroyDispatches[i]->vkFreeCommandBuffers(devicesToDestroy[i], toDestroyPools[j], 1, &toDestroy[j]);
5816                     VkCommandBuffer boxed = unboxed_to_boxed_VkCommandBuffer(toDestroy[j]);
5817                     delete_VkCommandBuffer(boxed);
5818                     mCmdBufferInfo.erase(toDestroy[j]);
5819                 }
5820             }
5821 
5822             {
5823                 std::vector<VkCommandPool> toDestroy;
5824                 std::vector<VkCommandPool> toDestroyBoxed;
5825                 auto it = mCmdPoolInfo.begin();
5826                 while (it != mCmdPoolInfo.end()) {
5827                     if (it->second.device == devicesToDestroy[i]) {
5828                         toDestroy.push_back(it->first);
5829                         toDestroyBoxed.push_back(it->second.boxed);
5830                     }
5831                     ++it;
5832                 }
5833 
5834                 for (int j = 0; j < toDestroy.size(); ++j) {
5835                     devicesToDestroyDispatches[i]->vkDestroyCommandPool(devicesToDestroy[i], toDestroy[j], 0);
5836                     delete_VkCommandPool(toDestroyBoxed[j]);
5837                     mCmdPoolInfo.erase(toDestroy[j]);
5838                 }
5839             }
5840 
5841             {
5842                 std::vector<VkDescriptorPool> toDestroy;
5843                 std::vector<VkDescriptorPool> toDestroyBoxed;
5844                 auto it = mDescriptorPoolInfo.begin();
5845                 while (it != mDescriptorPoolInfo.end()) {
5846                     if (it->second.device == devicesToDestroy[i]) {
5847                         toDestroy.push_back(it->first);
5848                         toDestroyBoxed.push_back(it->second.boxed);
5849                     }
5850                     ++it;
5851                 }
5852 
5853                 for (int j = 0; j < toDestroy.size(); ++j) {
5854                     devicesToDestroyDispatches[i]->vkDestroyDescriptorPool(devicesToDestroy[i], toDestroy[j], 0);
5855                     delete_VkDescriptorPool(toDestroyBoxed[j]);
5856                     mDescriptorPoolInfo.erase(toDestroy[j]);
5857                 }
5858             }
5859 
5860             {
5861                 std::vector<VkDescriptorSetLayout> toDestroy;
5862                 std::vector<VkDescriptorSetLayout> toDestroyBoxed;
5863                 auto it = mDescriptorSetLayoutInfo.begin();
5864                 while (it != mDescriptorSetLayoutInfo.end()) {
5865                     if (it->second.device == devicesToDestroy[i]) {
5866                         toDestroy.push_back(it->first);
5867                         toDestroyBoxed.push_back(it->second.boxed);
5868                     }
5869                     ++it;
5870                 }
5871 
5872                 for (int j = 0; j < toDestroy.size(); ++j) {
5873                     devicesToDestroyDispatches[i]->vkDestroyDescriptorSetLayout(devicesToDestroy[i], toDestroy[j], 0);
5874                     delete_VkDescriptorSetLayout(toDestroyBoxed[j]);
5875                     mDescriptorSetLayoutInfo.erase(toDestroy[j]);
5876                 }
5877             }
5878         }
5879 
5880         for (uint32_t i = 0; i < devicesToDestroy.size(); ++i) {
5881             destroyDeviceLocked(devicesToDestroy[i], nullptr);
5882             mDeviceInfo.erase(devicesToDestroy[i]);
5883             mDeviceToPhysicalDevice.erase(devicesToDestroy[i]);
5884         }
5885     }
5886 
5887     typedef std::function<void()> PreprocessFunc;
5888     struct CommandBufferInfo {
5889         std::vector<PreprocessFunc> preprocessFuncs = {};
5890         std::vector<VkCommandBuffer> subCmds = {};
5891         VkDevice device = 0;
5892         VkCommandPool cmdPool = nullptr;
5893         VkCommandBuffer boxed = nullptr;
5894         VkPipeline computePipeline = 0;
5895         uint32_t firstSet = 0;
5896         VkPipelineLayout descriptorLayout = 0;
5897         std::vector<VkDescriptorSet> descriptorSets;
5898         uint32_t sequenceNumber = 0;
5899     };
5900 
5901     struct CommandPoolInfo {
5902         VkDevice device = 0;
5903         VkCommandPool boxed = 0;
5904         std::unordered_set<VkCommandBuffer> cmdBuffers = {};
5905     };
5906 
removeCommandBufferInfo(const std::unordered_set<VkCommandBuffer> & cmdBuffers)5907     void removeCommandBufferInfo(
5908             const std::unordered_set<VkCommandBuffer>& cmdBuffers) {
5909         for (const auto& cmdBuffer : cmdBuffers) {
5910             mCmdBufferInfo.erase(cmdBuffer);
5911         }
5912     }
5913 
isDescriptorTypeImageInfo(VkDescriptorType descType)5914     bool isDescriptorTypeImageInfo(VkDescriptorType descType) {
5915         return (descType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
5916             (descType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
5917             (descType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
5918             (descType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
5919             (descType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
5920     }
5921 
isDescriptorTypeBufferInfo(VkDescriptorType descType)5922     bool isDescriptorTypeBufferInfo(VkDescriptorType descType) {
5923         return (descType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
5924             (descType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
5925             (descType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
5926             (descType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
5927     }
5928 
isDescriptorTypeBufferView(VkDescriptorType descType)5929     bool isDescriptorTypeBufferView(VkDescriptorType descType) {
5930         return (descType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
5931             (descType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
5932     }
5933 
5934     struct DescriptorUpdateTemplateInfo {
5935         VkDescriptorUpdateTemplateCreateInfo createInfo;
5936         std::vector<VkDescriptorUpdateTemplateEntry>
5937             linearizedTemplateEntries;
5938         // Preallocated pData
5939         std::vector<uint8_t> data;
5940         size_t imageInfoStart;
5941         size_t bufferInfoStart;
5942         size_t bufferViewStart;
5943     };
5944 
calcLinearizedDescriptorUpdateTemplateInfo(const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo)5945     DescriptorUpdateTemplateInfo calcLinearizedDescriptorUpdateTemplateInfo(
5946             const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo) {
5947 
5948         DescriptorUpdateTemplateInfo res;
5949         res.createInfo = *pCreateInfo;
5950 
5951         size_t numImageInfos = 0;
5952         size_t numBufferInfos = 0;
5953         size_t numBufferViews = 0;
5954 
5955         for (uint32_t i = 0; i < pCreateInfo->descriptorUpdateEntryCount; ++i) {
5956             const auto& entry = pCreateInfo->pDescriptorUpdateEntries[i];
5957             auto type = entry.descriptorType;
5958             auto count = entry.descriptorCount;
5959             if (isDescriptorTypeImageInfo(type)) {
5960                 numImageInfos += count;
5961             } else if (isDescriptorTypeBufferInfo(type)) {
5962                 numBufferInfos += count;
5963             } else if (isDescriptorTypeBufferView(type)) {
5964                 numBufferViews += count;
5965             } else {
5966                 fprintf(stderr, "%s: fatal: unknown descriptor type 0x%x\n", __func__, type);
5967                 abort();
5968             }
5969         }
5970 
5971         size_t imageInfoBytes = numImageInfos * sizeof(VkDescriptorImageInfo);
5972         size_t bufferInfoBytes = numBufferInfos * sizeof(VkDescriptorBufferInfo);
5973         size_t bufferViewBytes = numBufferViews * sizeof(VkBufferView);
5974 
5975         res.data.resize(imageInfoBytes + bufferInfoBytes + bufferViewBytes);
5976         res.imageInfoStart = 0;
5977         res.bufferInfoStart = imageInfoBytes;
5978         res.bufferViewStart = imageInfoBytes + bufferInfoBytes;
5979 
5980         size_t imageInfoCount = 0;
5981         size_t bufferInfoCount = 0;
5982         size_t bufferViewCount = 0;
5983 
5984         for (uint32_t i = 0; i < pCreateInfo->descriptorUpdateEntryCount; ++i) {
5985 
5986             const auto& entry = pCreateInfo->pDescriptorUpdateEntries[i];
5987             VkDescriptorUpdateTemplateEntry entryForHost = entry;
5988 
5989             auto type = entry.descriptorType;
5990 
5991             if (isDescriptorTypeImageInfo(type)) {
5992                 entryForHost.offset =
5993                     res.imageInfoStart +
5994                     imageInfoCount * sizeof(VkDescriptorImageInfo);
5995                 entryForHost.stride = sizeof(VkDescriptorImageInfo);
5996                 ++imageInfoCount;
5997             } else if (isDescriptorTypeBufferInfo(type)) {
5998                 entryForHost.offset =
5999                     res.bufferInfoStart +
6000                     bufferInfoCount * sizeof(VkDescriptorBufferInfo);
6001                 entryForHost.stride = sizeof(VkDescriptorBufferInfo);
6002                 ++bufferInfoCount;
6003             } else if (isDescriptorTypeBufferView(type)) {
6004                 entryForHost.offset =
6005                     res.bufferViewStart +
6006                     bufferViewCount * sizeof(VkBufferView);
6007                 entryForHost.stride = sizeof(VkBufferView);
6008                 ++bufferViewCount;
6009             } else {
6010                 fprintf(stderr, "%s: fatal: unknown descriptor type 0x%x\n", __func__, type);
6011                 abort();
6012             }
6013 
6014             res.linearizedTemplateEntries.push_back(entryForHost);
6015         }
6016 
6017         res.createInfo.pDescriptorUpdateEntries =
6018             res.linearizedTemplateEntries.data();
6019 
6020         return res;
6021     }
6022 
registerDescriptorUpdateTemplate(VkDescriptorUpdateTemplate descriptorUpdateTemplate,const DescriptorUpdateTemplateInfo & info)6023     void registerDescriptorUpdateTemplate(
6024             VkDescriptorUpdateTemplate descriptorUpdateTemplate,
6025             const DescriptorUpdateTemplateInfo& info) {
6026         AutoLock lock(mLock);
6027         mDescriptorUpdateTemplateInfo[descriptorUpdateTemplate] = info;
6028     }
6029 
unregisterDescriptorUpdateTemplate(VkDescriptorUpdateTemplate descriptorUpdateTemplate)6030     void unregisterDescriptorUpdateTemplate(
6031             VkDescriptorUpdateTemplate descriptorUpdateTemplate) {
6032         AutoLock lock(mLock);
6033         mDescriptorUpdateTemplateInfo.erase(descriptorUpdateTemplate);
6034     }
6035 
6036     // Returns the momory property index when succeeds; returns -1 when fails.
findProperties(VkPhysicalDevice physicalDevice,uint32_t memoryTypeBitsRequirement,VkMemoryPropertyFlags requiredProperties)6037     int32_t findProperties(VkPhysicalDevice physicalDevice,
6038             uint32_t memoryTypeBitsRequirement,
6039             VkMemoryPropertyFlags requiredProperties) {
6040         VkPhysicalDeviceMemoryProperties memProperties;
6041         auto ivk = dispatch_VkInstance(
6042                 mInstanceInfo[mPhysicalDeviceToInstance[physicalDevice]].boxed);
6043 
6044         ivk->vkGetPhysicalDeviceMemoryProperties(physicalDevice,
6045                 &memProperties);
6046 
6047         const uint32_t memoryCount = memProperties.memoryTypeCount;
6048         for (uint32_t memoryIndex = 0; memoryIndex < memoryCount;
6049                 ++memoryIndex) {
6050             const uint32_t memoryTypeBits = (1 << memoryIndex);
6051             const bool isRequiredMemoryType =
6052                 memoryTypeBitsRequirement & memoryTypeBits;
6053 
6054             const VkMemoryPropertyFlags properties =
6055                 memProperties.memoryTypes[memoryIndex].propertyFlags;
6056             const bool hasRequiredProperties =
6057                 (properties & requiredProperties) == requiredProperties;
6058 
6059             if (isRequiredMemoryType && hasRequiredProperties)
6060                 return static_cast<int32_t>(memoryIndex);
6061         }
6062 
6063         // failed to find memory type
6064         return -1;
6065     }
6066 
6067     VulkanDispatch* m_vk;
6068     VkEmulation* m_emu;
6069     bool mSnapshotsEnabled = false;
6070     bool mVkCleanupEnabled = true;
6071     bool mLogging = false;
6072     bool mVerbosePrints = false;
6073     bool mUseOldMemoryCleanupPath = false;
6074     bool mGuestUsesAngle = false;
6075 
6076     Lock mLock;
6077 
6078     // We always map the whole size on host.
6079     // This makes it much easier to implement
6080     // the memory map API.
6081     struct MappedMemoryInfo {
6082         // This indicates whether the VkDecoderGlobalState needs to clean up
6083         // and unmap the mapped memory; only the owner of the mapped memory
6084         // should call unmap.
6085         bool needUnmap = false;
6086         // When ptr is null, it means the VkDeviceMemory object
6087         // was not allocated with the HOST_VISIBLE property.
6088         void* ptr = nullptr;
6089         VkDeviceSize size;
6090         // GLDirectMem info
6091         bool directMapped = false;
6092         bool virtioGpuMapped = false;
6093         uint64_t guestPhysAddr = 0;
6094         void* pageAlignedHva = nullptr;
6095         uint64_t sizeToPage = 0;
6096         uint64_t hostmemId = 0;
6097         VkDevice device = VK_NULL_HANDLE;
6098         MTLTextureRef mtlTexture = nullptr;
6099     };
6100 
6101     struct InstanceInfo {
6102         std::vector<std::string> enabledExtensionNames;
6103         uint32_t apiVersion = VK_MAKE_VERSION(1, 0, 0);
6104         VkInstance boxed = nullptr;
6105     };
6106 
6107     struct PhysicalDeviceInfo {
6108         VkPhysicalDeviceProperties props;
6109         VkPhysicalDeviceMemoryProperties memoryProperties;
6110         std::vector<VkQueueFamilyProperties> queueFamilyProperties;
6111         VkPhysicalDevice boxed = nullptr;
6112     };
6113 
6114     struct DeviceInfo {
6115         std::unordered_map<uint32_t, std::vector<VkQueue>> queues;
6116         std::vector<std::string> enabledExtensionNames;
6117         bool emulateTextureEtc2 = false;
6118         bool emulateTextureAstc = false;
6119         VkPhysicalDevice physicalDevice;
6120         VkDevice boxed = nullptr;
needEmulatedDecompressiongoldfish_vk::VkDecoderGlobalState::Impl::DeviceInfo6121         bool needEmulatedDecompression(const CompressedImageInfo& imageInfo) {
6122             return imageInfo.isCompressed &&
6123                    ((imageInfo.isEtc2 && emulateTextureEtc2) ||
6124                     (imageInfo.isAstc && emulateTextureAstc));
6125         }
needEmulatedDecompressiongoldfish_vk::VkDecoderGlobalState::Impl::DeviceInfo6126         bool needEmulatedDecompression(VkFormat format) {
6127             switch (format) {
6128                 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
6129                 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
6130                 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
6131                 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
6132                 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
6133                 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
6134                 case VK_FORMAT_EAC_R11_UNORM_BLOCK:
6135                 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
6136                 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
6137                 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
6138                     return emulateTextureEtc2;
6139                 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
6140                 case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
6141                 case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
6142                 case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
6143                 case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
6144                 case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
6145                 case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
6146                 case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
6147                 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
6148                 case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
6149                 case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
6150                 case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
6151                 case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
6152                 case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
6153                 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
6154                 case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
6155                 case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
6156                 case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
6157                 case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
6158                 case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
6159                 case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
6160                 case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
6161                 case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
6162                 case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
6163                 case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
6164                 case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
6165                 case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
6166                 case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
6167                     return emulateTextureAstc;
6168                 default:
6169                     return false;
6170             }
6171         }
6172     };
6173 
6174     struct QueueInfo {
6175         Lock* lock = nullptr;
6176         VkDevice device;
6177         uint32_t queueFamilyIndex;
6178         VkQueue boxed = nullptr;
6179         uint32_t sequenceNumber = 0;
6180     };
6181 
6182     struct BufferInfo {
6183         VkDevice device;
6184         VkDeviceMemory memory = 0;
6185         VkDeviceSize memoryOffset = 0;
6186         VkDeviceSize size;
6187         // For compressed texture emulation
6188         VulkanDispatch* vk = nullptr;
6189     };
6190 
6191     struct ImageInfo {
6192         AndroidNativeBufferInfo anbInfo;
6193         CompressedImageInfo cmpInfo;
6194     };
6195 
6196     struct ImageViewInfo {
6197         bool needEmulatedAlpha = false;
6198     };
6199 
6200     struct SamplerInfo {
6201         bool needEmulatedAlpha = false;
6202         VkSamplerCreateInfo createInfo = {};
6203         VkSampler emulatedborderSampler = VK_NULL_HANDLE;
6204     };
6205 
6206     struct FenceInfo {
6207         VkDevice device = VK_NULL_HANDLE;
6208         VkFence boxed = VK_NULL_HANDLE;
6209         VulkanDispatch* vk = nullptr;
6210     };
6211 
6212     struct SemaphoreInfo {
6213         int externalHandleId = 0;
6214         VK_EXT_MEMORY_HANDLE externalHandle =
6215             VK_EXT_MEMORY_HANDLE_INVALID;
6216     };
6217 
6218     struct DescriptorSetLayoutInfo  {
6219         VkDevice device = 0;
6220         VkDescriptorSetLayout boxed = 0;
6221         VkDescriptorSetLayoutCreateInfo createInfo;
6222         std::vector<VkDescriptorSetLayoutBinding> bindings;
6223     };
6224 
6225     struct DescriptorPoolInfo {
6226         VkDevice device = 0;
6227         VkDescriptorPool boxed = 0;
6228         struct PoolState {
6229             VkDescriptorType type;
6230             uint32_t descriptorCount;
6231             uint32_t used;
6232         };
6233 
6234         VkDescriptorPoolCreateInfo createInfo;
6235         uint32_t maxSets;
6236         uint32_t usedSets;
6237         std::vector<PoolState> pools;
6238 
6239         std::unordered_map<VkDescriptorSet, VkDescriptorSet> allocedSetsToBoxed;
6240         std::vector<uint64_t> poolIds;
6241     };
6242 
6243     struct DescriptorSetInfo {
6244         VkDescriptorPool pool;
6245         std::vector<VkDescriptorSetLayoutBinding> bindings;
6246     };
6247 
isBindingFeasibleForAlloc(const DescriptorPoolInfo::PoolState & poolState,const VkDescriptorSetLayoutBinding & binding)6248     bool isBindingFeasibleForAlloc(const DescriptorPoolInfo::PoolState& poolState, const VkDescriptorSetLayoutBinding& binding) {
6249         if (binding.descriptorCount && (poolState.type != binding.descriptorType)) {
6250             return false;
6251         }
6252 
6253         uint32_t availDescriptorCount =
6254             poolState.descriptorCount - poolState.used;
6255 
6256         if (availDescriptorCount < binding.descriptorCount) {
6257             return false;
6258         }
6259 
6260         return true;
6261     }
6262 
isBindingFeasibleForFree(const DescriptorPoolInfo::PoolState & poolState,const VkDescriptorSetLayoutBinding & binding)6263     bool isBindingFeasibleForFree(const DescriptorPoolInfo::PoolState& poolState, const VkDescriptorSetLayoutBinding& binding) {
6264         if (poolState.type != binding.descriptorType) return false;
6265         if (poolState.used < binding.descriptorCount) return false;
6266         return true;
6267     }
6268 
allocBindingFeasible(const VkDescriptorSetLayoutBinding & binding,DescriptorPoolInfo::PoolState & poolState)6269     void allocBindingFeasible(
6270         const VkDescriptorSetLayoutBinding& binding,
6271         DescriptorPoolInfo::PoolState& poolState) {
6272         poolState.used += binding.descriptorCount;
6273     }
6274 
freeBindingFeasible(const VkDescriptorSetLayoutBinding & binding,DescriptorPoolInfo::PoolState & poolState)6275     void freeBindingFeasible(
6276         const VkDescriptorSetLayoutBinding& binding,
6277         DescriptorPoolInfo::PoolState& poolState) {
6278         poolState.used -= binding.descriptorCount;
6279     }
6280 
validateDescriptorSetAllocLocked(const VkDescriptorSetAllocateInfo * pAllocateInfo)6281     VkResult validateDescriptorSetAllocLocked(const VkDescriptorSetAllocateInfo* pAllocateInfo) {
6282         auto poolInfo = android::base::find(mDescriptorPoolInfo, pAllocateInfo->descriptorPool);
6283         if (!poolInfo) return VK_ERROR_INITIALIZATION_FAILED;
6284 
6285         // Check the number of sets available.
6286         auto setsAvailable = poolInfo->maxSets - poolInfo->usedSets;
6287 
6288         if (setsAvailable < pAllocateInfo->descriptorSetCount) {
6289             return VK_ERROR_OUT_OF_POOL_MEMORY;
6290         }
6291 
6292         // Perform simulated allocation and error out with
6293         // VK_ERROR_OUT_OF_POOL_MEMORY if it fails.
6294         std::vector<DescriptorPoolInfo::PoolState> poolCopy =
6295             poolInfo->pools;
6296 
6297         for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; ++i) {
6298             auto setLayoutInfo = android::base::find(mDescriptorSetLayoutInfo, pAllocateInfo->pSetLayouts[i]);
6299             if (!setLayoutInfo) return VK_ERROR_INITIALIZATION_FAILED;
6300 
6301             for (const auto& binding : setLayoutInfo->bindings) {
6302                 bool success = false;
6303                 for (auto& pool : poolCopy) {
6304                     if (!isBindingFeasibleForAlloc(pool, binding)) continue;
6305 
6306                     success = true;
6307                     allocBindingFeasible(binding, pool);
6308                     break;
6309                 }
6310 
6311                 if (!success) {
6312                     return VK_ERROR_OUT_OF_POOL_MEMORY;
6313                 }
6314             }
6315         }
6316         return VK_SUCCESS;
6317     }
6318 
applyDescriptorSetAllocationLocked(DescriptorPoolInfo & poolInfo,const std::vector<VkDescriptorSetLayoutBinding> & bindings)6319     void applyDescriptorSetAllocationLocked(DescriptorPoolInfo& poolInfo, const std::vector<VkDescriptorSetLayoutBinding>& bindings) {
6320         ++poolInfo.usedSets;
6321         for (const auto& binding : bindings) {
6322             for (auto& pool : poolInfo.pools) {
6323                 if (!isBindingFeasibleForAlloc(pool, binding)) continue;
6324                 allocBindingFeasible(binding, pool);
6325                 break;
6326             }
6327         }
6328     }
6329 
removeDescriptorSetAllocationLocked(DescriptorPoolInfo & poolInfo,const std::vector<VkDescriptorSetLayoutBinding> & bindings)6330     void removeDescriptorSetAllocationLocked(DescriptorPoolInfo& poolInfo, const std::vector<VkDescriptorSetLayoutBinding>& bindings) {
6331         --poolInfo.usedSets;
6332         for (const auto& binding : bindings) {
6333             for (auto& pool : poolInfo.pools) {
6334                 if (!isBindingFeasibleForFree(pool, binding)) continue;
6335                 freeBindingFeasible(binding, pool);
6336                 break;
6337             }
6338         }
6339     }
6340 
6341     template <class T>
6342     class NonDispatchableHandleInfo {
6343     public:
6344         T underlying;
6345     };
6346 
6347     std::unordered_map<VkInstance, InstanceInfo>
6348         mInstanceInfo;
6349     std::unordered_map<VkPhysicalDevice, PhysicalDeviceInfo>
6350         mPhysdevInfo;
6351     std::unordered_map<VkDevice, DeviceInfo>
6352         mDeviceInfo;
6353     std::unordered_map<VkImage, ImageInfo>
6354         mImageInfo;
6355     std::unordered_map<VkImageView, ImageViewInfo> mImageViewInfo;
6356     std::unordered_map<VkSampler, SamplerInfo> mSamplerInfo;
6357     std::unordered_map<VkCommandBuffer, CommandBufferInfo> mCmdBufferInfo;
6358     std::unordered_map<VkCommandPool, CommandPoolInfo> mCmdPoolInfo;
6359     // TODO: release CommandBufferInfo when a command pool is reset/released
6360 
6361     // Back-reference to the physical device associated with a particular
6362     // VkDevice, and the VkDevice corresponding to a VkQueue.
6363     std::unordered_map<VkDevice, VkPhysicalDevice> mDeviceToPhysicalDevice;
6364     std::unordered_map<VkPhysicalDevice, VkInstance> mPhysicalDeviceToInstance;
6365 
6366     std::unordered_map<VkQueue, QueueInfo> mQueueInfo;
6367     std::unordered_map<VkBuffer, BufferInfo> mBufferInfo;
6368 
6369     std::unordered_map<VkDeviceMemory, MappedMemoryInfo> mMapInfo;
6370 
6371     std::unordered_map<VkSemaphore, SemaphoreInfo> mSemaphoreInfo;
6372     std::unordered_map<VkFence, FenceInfo> mFenceInfo;
6373 
6374     std::unordered_map<VkDescriptorSetLayout, DescriptorSetLayoutInfo> mDescriptorSetLayoutInfo;
6375     std::unordered_map<VkDescriptorPool, DescriptorPoolInfo> mDescriptorPoolInfo;
6376     std::unordered_map<VkDescriptorSet, DescriptorSetInfo> mDescriptorSetInfo;
6377 
6378 #ifdef _WIN32
6379     int mSemaphoreId = 1;
genSemaphoreId()6380     int genSemaphoreId() {
6381         if (mSemaphoreId == -1) {
6382             mSemaphoreId = 1;
6383         }
6384         int res = mSemaphoreId;
6385         ++mSemaphoreId;
6386         return res;
6387     }
6388     std::unordered_map<int, VkSemaphore> mExternalSemaphoresById;
6389 #endif
6390     std::unordered_map<VkDescriptorUpdateTemplate, DescriptorUpdateTemplateInfo> mDescriptorUpdateTemplateInfo;
6391 
6392     VkDecoderSnapshot mSnapshot;
6393 
6394     std::vector<uint64_t> mCreatedHandlesForSnapshotLoad;
6395     size_t mCreatedHandlesForSnapshotLoadIndex = 0;
6396 
6397     Lock mOccupiedGpasLock;
6398     // Back-reference to the VkDeviceMemory that is occupying a particular
6399     // guest physical address
6400     struct OccupiedGpaInfo {
6401         VulkanDispatch* vk;
6402         VkDevice device;
6403         VkDeviceMemory memory;
6404         uint64_t gpa;
6405         size_t sizeToPage;
6406     };
6407     std::unordered_map<uint64_t, OccupiedGpaInfo> mOccupiedGpas;
6408 
6409     struct LinearImageProperties {
6410         VkDeviceSize offset;
6411         VkDeviceSize rowPitchAlignment;
6412     };
6413     android::base::Optional<LinearImageProperties> mLinearImageProperties;
6414 };
6415 
VkDecoderGlobalState()6416 VkDecoderGlobalState::VkDecoderGlobalState()
6417     : mImpl(new VkDecoderGlobalState::Impl()) {}
6418 
6419 VkDecoderGlobalState::~VkDecoderGlobalState() = default;
6420 
6421 static VkDecoderGlobalState* sGlobalDecoderState = nullptr;
6422 
6423 // static
get()6424 VkDecoderGlobalState* VkDecoderGlobalState::get() {
6425     if (sGlobalDecoderState) return sGlobalDecoderState;
6426     sGlobalDecoderState = new VkDecoderGlobalState;
6427     return sGlobalDecoderState;
6428 }
6429 
6430 // Snapshots
snapshotsEnabled() const6431 bool VkDecoderGlobalState::snapshotsEnabled() const {
6432     return mImpl->snapshotsEnabled();
6433 }
6434 
vkCleanupEnabled() const6435 bool VkDecoderGlobalState::vkCleanupEnabled() const {
6436     return mImpl->vkCleanupEnabled();
6437 }
6438 
save(android::base::Stream * stream)6439 void VkDecoderGlobalState::save(android::base::Stream* stream) {
6440     mImpl->save(stream);
6441 }
6442 
load(android::base::Stream * stream)6443 void VkDecoderGlobalState::load(android::base::Stream* stream) {
6444     mImpl->load(stream);
6445 }
6446 
lock()6447 void VkDecoderGlobalState::lock() {
6448     mImpl->lock();
6449 }
6450 
unlock()6451 void VkDecoderGlobalState::unlock() {
6452     mImpl->unlock();
6453 }
6454 
setCreatedHandlesForSnapshotLoad(const unsigned char * buffer)6455 size_t VkDecoderGlobalState::setCreatedHandlesForSnapshotLoad(const unsigned char* buffer) {
6456     return mImpl->setCreatedHandlesForSnapshotLoad(buffer);
6457 }
6458 
clearCreatedHandlesForSnapshotLoad()6459 void VkDecoderGlobalState::clearCreatedHandlesForSnapshotLoad() {
6460     mImpl->clearCreatedHandlesForSnapshotLoad();
6461 }
6462 
on_vkEnumerateInstanceVersion(android::base::BumpPool * pool,uint32_t * pApiVersion)6463 VkResult VkDecoderGlobalState::on_vkEnumerateInstanceVersion(
6464     android::base::BumpPool* pool,
6465     uint32_t* pApiVersion) {
6466     return mImpl->on_vkEnumerateInstanceVersion(pool, pApiVersion);
6467 }
6468 
on_vkCreateInstance(android::base::BumpPool * pool,const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)6469 VkResult VkDecoderGlobalState::on_vkCreateInstance(
6470     android::base::BumpPool* pool,
6471     const VkInstanceCreateInfo* pCreateInfo,
6472     const VkAllocationCallbacks* pAllocator,
6473     VkInstance* pInstance) {
6474     return mImpl->on_vkCreateInstance(pool, pCreateInfo, pAllocator, pInstance);
6475 }
6476 
on_vkDestroyInstance(android::base::BumpPool * pool,VkInstance instance,const VkAllocationCallbacks * pAllocator)6477 void VkDecoderGlobalState::on_vkDestroyInstance(
6478     android::base::BumpPool* pool,
6479     VkInstance instance,
6480     const VkAllocationCallbacks* pAllocator) {
6481     mImpl->on_vkDestroyInstance(pool, instance, pAllocator);
6482 }
6483 
on_vkEnumeratePhysicalDevices(android::base::BumpPool * pool,VkInstance instance,uint32_t * physicalDeviceCount,VkPhysicalDevice * physicalDevices)6484 VkResult VkDecoderGlobalState::on_vkEnumeratePhysicalDevices(
6485     android::base::BumpPool* pool,
6486     VkInstance instance,
6487     uint32_t* physicalDeviceCount,
6488     VkPhysicalDevice* physicalDevices) {
6489     return mImpl->on_vkEnumeratePhysicalDevices(pool, instance, physicalDeviceCount, physicalDevices);
6490 }
6491 
on_vkGetPhysicalDeviceFeatures(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures * pFeatures)6492 void VkDecoderGlobalState::on_vkGetPhysicalDeviceFeatures(
6493     android::base::BumpPool* pool,
6494     VkPhysicalDevice physicalDevice,
6495     VkPhysicalDeviceFeatures* pFeatures) {
6496     mImpl->on_vkGetPhysicalDeviceFeatures(pool, physicalDevice, pFeatures);
6497 }
6498 
on_vkGetPhysicalDeviceFeatures2(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures2 * pFeatures)6499 void VkDecoderGlobalState::on_vkGetPhysicalDeviceFeatures2(
6500     android::base::BumpPool* pool,
6501     VkPhysicalDevice physicalDevice,
6502     VkPhysicalDeviceFeatures2* pFeatures) {
6503     mImpl->on_vkGetPhysicalDeviceFeatures2(pool, physicalDevice, pFeatures);
6504 }
6505 
on_vkGetPhysicalDeviceFeatures2KHR(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures2KHR * pFeatures)6506 void VkDecoderGlobalState::on_vkGetPhysicalDeviceFeatures2KHR(
6507     android::base::BumpPool* pool,
6508     VkPhysicalDevice physicalDevice,
6509     VkPhysicalDeviceFeatures2KHR* pFeatures) {
6510     mImpl->on_vkGetPhysicalDeviceFeatures2(pool, physicalDevice, pFeatures);
6511 }
6512 
on_vkGetPhysicalDeviceImageFormatProperties(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags,VkImageFormatProperties * pImageFormatProperties)6513 VkResult VkDecoderGlobalState::on_vkGetPhysicalDeviceImageFormatProperties(
6514     android::base::BumpPool* pool,
6515     VkPhysicalDevice physicalDevice,
6516     VkFormat format,
6517     VkImageType type,
6518     VkImageTiling tiling,
6519     VkImageUsageFlags usage,
6520     VkImageCreateFlags flags,
6521     VkImageFormatProperties* pImageFormatProperties) {
6522     return mImpl->on_vkGetPhysicalDeviceImageFormatProperties(
6523             pool, physicalDevice, format, type, tiling, usage, flags,
6524             pImageFormatProperties);
6525 }
on_vkGetPhysicalDeviceImageFormatProperties2(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,VkImageFormatProperties2 * pImageFormatProperties)6526 VkResult VkDecoderGlobalState::on_vkGetPhysicalDeviceImageFormatProperties2(
6527     android::base::BumpPool* pool,
6528     VkPhysicalDevice physicalDevice,
6529     const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
6530     VkImageFormatProperties2* pImageFormatProperties) {
6531     return mImpl->on_vkGetPhysicalDeviceImageFormatProperties2(
6532             pool, physicalDevice, pImageFormatInfo, pImageFormatProperties);
6533 }
on_vkGetPhysicalDeviceImageFormatProperties2KHR(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,VkImageFormatProperties2 * pImageFormatProperties)6534 VkResult VkDecoderGlobalState::on_vkGetPhysicalDeviceImageFormatProperties2KHR(
6535     android::base::BumpPool* pool,
6536     VkPhysicalDevice physicalDevice,
6537     const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
6538     VkImageFormatProperties2* pImageFormatProperties) {
6539     return mImpl->on_vkGetPhysicalDeviceImageFormatProperties2(
6540             pool, physicalDevice, pImageFormatInfo, pImageFormatProperties);
6541 }
6542 
on_vkGetPhysicalDeviceFormatProperties(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties * pFormatProperties)6543 void VkDecoderGlobalState::on_vkGetPhysicalDeviceFormatProperties(
6544     android::base::BumpPool* pool,
6545     VkPhysicalDevice physicalDevice,
6546     VkFormat format,
6547     VkFormatProperties* pFormatProperties) {
6548     mImpl->on_vkGetPhysicalDeviceFormatProperties(pool, physicalDevice, format,
6549                                                   pFormatProperties);
6550 }
6551 
on_vkGetPhysicalDeviceFormatProperties2(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)6552 void VkDecoderGlobalState::on_vkGetPhysicalDeviceFormatProperties2(
6553     android::base::BumpPool* pool,
6554     VkPhysicalDevice physicalDevice,
6555     VkFormat format,
6556     VkFormatProperties2* pFormatProperties) {
6557     mImpl->on_vkGetPhysicalDeviceFormatProperties2(pool, physicalDevice, format,
6558                                                    pFormatProperties);
6559 }
6560 
on_vkGetPhysicalDeviceFormatProperties2KHR(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)6561 void VkDecoderGlobalState::on_vkGetPhysicalDeviceFormatProperties2KHR(
6562     android::base::BumpPool* pool,
6563     VkPhysicalDevice physicalDevice,
6564     VkFormat format,
6565     VkFormatProperties2* pFormatProperties) {
6566     mImpl->on_vkGetPhysicalDeviceFormatProperties2(pool, physicalDevice, format,
6567                                                    pFormatProperties);
6568 }
6569 
on_vkGetPhysicalDeviceProperties(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties * pProperties)6570 void VkDecoderGlobalState::on_vkGetPhysicalDeviceProperties(
6571     android::base::BumpPool* pool,
6572     VkPhysicalDevice physicalDevice,
6573     VkPhysicalDeviceProperties* pProperties) {
6574     mImpl->on_vkGetPhysicalDeviceProperties(pool, physicalDevice, pProperties);
6575 }
6576 
on_vkGetPhysicalDeviceProperties2(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties2 * pProperties)6577 void VkDecoderGlobalState::on_vkGetPhysicalDeviceProperties2(
6578     android::base::BumpPool* pool,
6579     VkPhysicalDevice physicalDevice,
6580     VkPhysicalDeviceProperties2* pProperties) {
6581     mImpl->on_vkGetPhysicalDeviceProperties2(pool, physicalDevice, pProperties);
6582 }
6583 
on_vkGetPhysicalDeviceProperties2KHR(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties2 * pProperties)6584 void VkDecoderGlobalState::on_vkGetPhysicalDeviceProperties2KHR(
6585     android::base::BumpPool* pool,
6586     VkPhysicalDevice physicalDevice,
6587     VkPhysicalDeviceProperties2* pProperties) {
6588     mImpl->on_vkGetPhysicalDeviceProperties2(pool, physicalDevice, pProperties);
6589 }
6590 
on_vkGetPhysicalDeviceMemoryProperties(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties * pMemoryProperties)6591 void VkDecoderGlobalState::on_vkGetPhysicalDeviceMemoryProperties(
6592     android::base::BumpPool* pool,
6593     VkPhysicalDevice physicalDevice,
6594     VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
6595     mImpl->on_vkGetPhysicalDeviceMemoryProperties(
6596         pool, physicalDevice, pMemoryProperties);
6597 }
6598 
on_vkGetPhysicalDeviceMemoryProperties2(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties2 * pMemoryProperties)6599 void VkDecoderGlobalState::on_vkGetPhysicalDeviceMemoryProperties2(
6600     android::base::BumpPool* pool,
6601     VkPhysicalDevice physicalDevice,
6602     VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
6603     mImpl->on_vkGetPhysicalDeviceMemoryProperties2(
6604         pool, physicalDevice, pMemoryProperties);
6605 }
6606 
on_vkGetPhysicalDeviceMemoryProperties2KHR(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties2 * pMemoryProperties)6607 void VkDecoderGlobalState::on_vkGetPhysicalDeviceMemoryProperties2KHR(
6608     android::base::BumpPool* pool,
6609     VkPhysicalDevice physicalDevice,
6610     VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
6611     mImpl->on_vkGetPhysicalDeviceMemoryProperties2(
6612         pool, physicalDevice, pMemoryProperties);
6613 }
6614 
on_vkEnumerateDeviceExtensionProperties(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)6615 VkResult VkDecoderGlobalState::on_vkEnumerateDeviceExtensionProperties(
6616     android::base::BumpPool* pool,
6617     VkPhysicalDevice physicalDevice,
6618     const char* pLayerName,
6619     uint32_t* pPropertyCount,
6620     VkExtensionProperties* pProperties) {
6621     return mImpl->on_vkEnumerateDeviceExtensionProperties(
6622         pool, physicalDevice, pLayerName, pPropertyCount, pProperties);
6623 }
6624 
on_vkCreateDevice(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)6625 VkResult VkDecoderGlobalState::on_vkCreateDevice(
6626     android::base::BumpPool* pool,
6627     VkPhysicalDevice physicalDevice,
6628     const VkDeviceCreateInfo* pCreateInfo,
6629     const VkAllocationCallbacks* pAllocator,
6630     VkDevice* pDevice) {
6631     return mImpl->on_vkCreateDevice(pool, physicalDevice, pCreateInfo, pAllocator, pDevice);
6632 }
6633 
on_vkGetDeviceQueue(android::base::BumpPool * pool,VkDevice device,uint32_t queueFamilyIndex,uint32_t queueIndex,VkQueue * pQueue)6634 void VkDecoderGlobalState::on_vkGetDeviceQueue(
6635     android::base::BumpPool* pool,
6636     VkDevice device,
6637     uint32_t queueFamilyIndex,
6638     uint32_t queueIndex,
6639     VkQueue* pQueue) {
6640     mImpl->on_vkGetDeviceQueue(pool, device, queueFamilyIndex, queueIndex, pQueue);
6641 }
6642 
on_vkDestroyDevice(android::base::BumpPool * pool,VkDevice device,const VkAllocationCallbacks * pAllocator)6643 void VkDecoderGlobalState::on_vkDestroyDevice(
6644     android::base::BumpPool* pool,
6645     VkDevice device,
6646     const VkAllocationCallbacks* pAllocator) {
6647     mImpl->on_vkDestroyDevice(pool, device, pAllocator);
6648 }
6649 
on_vkCreateBuffer(android::base::BumpPool * pool,VkDevice device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer)6650 VkResult VkDecoderGlobalState::on_vkCreateBuffer(
6651     android::base::BumpPool* pool,
6652     VkDevice device,
6653     const VkBufferCreateInfo* pCreateInfo,
6654     const VkAllocationCallbacks* pAllocator,
6655     VkBuffer* pBuffer) {
6656     return mImpl->on_vkCreateBuffer(pool, device, pCreateInfo, pAllocator, pBuffer);
6657 }
6658 
on_vkDestroyBuffer(android::base::BumpPool * pool,VkDevice device,VkBuffer buffer,const VkAllocationCallbacks * pAllocator)6659 void VkDecoderGlobalState::on_vkDestroyBuffer(
6660     android::base::BumpPool* pool,
6661     VkDevice device,
6662     VkBuffer buffer,
6663     const VkAllocationCallbacks* pAllocator) {
6664     mImpl->on_vkDestroyBuffer(pool, device, buffer, pAllocator);
6665 }
6666 
on_vkBindBufferMemory(android::base::BumpPool * pool,VkDevice device,VkBuffer buffer,VkDeviceMemory memory,VkDeviceSize memoryOffset)6667 VkResult VkDecoderGlobalState::on_vkBindBufferMemory(
6668     android::base::BumpPool* pool,
6669     VkDevice device,
6670     VkBuffer buffer,
6671     VkDeviceMemory memory,
6672     VkDeviceSize memoryOffset) {
6673     return mImpl->on_vkBindBufferMemory(pool, device, buffer, memory, memoryOffset);
6674 }
6675 
on_vkBindBufferMemory2(android::base::BumpPool * pool,VkDevice device,uint32_t bindInfoCount,const VkBindBufferMemoryInfo * pBindInfos)6676 VkResult VkDecoderGlobalState::on_vkBindBufferMemory2(
6677     android::base::BumpPool* pool,
6678     VkDevice device,
6679     uint32_t bindInfoCount,
6680     const VkBindBufferMemoryInfo* pBindInfos) {
6681     return mImpl->on_vkBindBufferMemory2(pool, device, bindInfoCount, pBindInfos);
6682 }
6683 
on_vkBindBufferMemory2KHR(android::base::BumpPool * pool,VkDevice device,uint32_t bindInfoCount,const VkBindBufferMemoryInfo * pBindInfos)6684 VkResult VkDecoderGlobalState::on_vkBindBufferMemory2KHR(
6685     android::base::BumpPool* pool,
6686     VkDevice device,
6687     uint32_t bindInfoCount,
6688     const VkBindBufferMemoryInfo* pBindInfos) {
6689     return mImpl->on_vkBindBufferMemory2KHR(pool, device, bindInfoCount, pBindInfos);
6690 }
6691 
on_vkCreateImage(android::base::BumpPool * pool,VkDevice device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage)6692 VkResult VkDecoderGlobalState::on_vkCreateImage(
6693     android::base::BumpPool* pool,
6694     VkDevice device,
6695     const VkImageCreateInfo* pCreateInfo,
6696     const VkAllocationCallbacks* pAllocator,
6697     VkImage* pImage) {
6698     return mImpl->on_vkCreateImage(pool, device, pCreateInfo, pAllocator, pImage);
6699 }
6700 
on_vkDestroyImage(android::base::BumpPool * pool,VkDevice device,VkImage image,const VkAllocationCallbacks * pAllocator)6701 void VkDecoderGlobalState::on_vkDestroyImage(
6702     android::base::BumpPool* pool,
6703     VkDevice device,
6704     VkImage image,
6705     const VkAllocationCallbacks* pAllocator) {
6706     mImpl->on_vkDestroyImage(pool, device, image, pAllocator);
6707 }
6708 
on_vkBindImageMemory(android::base::BumpPool * pool,VkDevice device,VkImage image,VkDeviceMemory memory,VkDeviceSize memoryOffset)6709 VkResult VkDecoderGlobalState::on_vkBindImageMemory(android::base::BumpPool* pool,
6710                                                     VkDevice device,
6711                                                     VkImage image,
6712                                                     VkDeviceMemory memory,
6713                                                     VkDeviceSize memoryOffset) {
6714     return mImpl->on_vkBindImageMemory(pool, device, image, memory,
6715                                        memoryOffset);
6716 }
6717 
on_vkCreateImageView(android::base::BumpPool * pool,VkDevice device,const VkImageViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImageView * pView)6718 VkResult VkDecoderGlobalState::on_vkCreateImageView(
6719     android::base::BumpPool* pool,
6720     VkDevice device,
6721     const VkImageViewCreateInfo* pCreateInfo,
6722     const VkAllocationCallbacks* pAllocator,
6723     VkImageView* pView) {
6724     return mImpl->on_vkCreateImageView(pool, device, pCreateInfo, pAllocator, pView);
6725 }
6726 
on_vkDestroyImageView(android::base::BumpPool * pool,VkDevice device,VkImageView imageView,const VkAllocationCallbacks * pAllocator)6727 void VkDecoderGlobalState::on_vkDestroyImageView(
6728     android::base::BumpPool* pool,
6729     VkDevice device,
6730     VkImageView imageView,
6731     const VkAllocationCallbacks* pAllocator) {
6732     mImpl->on_vkDestroyImageView(pool, device, imageView, pAllocator);
6733 }
6734 
on_vkCreateSampler(android::base::BumpPool * pool,VkDevice device,const VkSamplerCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)6735 VkResult VkDecoderGlobalState::on_vkCreateSampler(
6736     android::base::BumpPool* pool,
6737     VkDevice device,
6738     const VkSamplerCreateInfo* pCreateInfo,
6739     const VkAllocationCallbacks* pAllocator,
6740     VkSampler* pSampler) {
6741     return mImpl->on_vkCreateSampler(pool, device, pCreateInfo, pAllocator, pSampler);
6742 }
6743 
on_vkDestroySampler(android::base::BumpPool * pool,VkDevice device,VkSampler sampler,const VkAllocationCallbacks * pAllocator)6744 void VkDecoderGlobalState::on_vkDestroySampler(
6745     android::base::BumpPool* pool,
6746     VkDevice device,
6747     VkSampler sampler,
6748     const VkAllocationCallbacks* pAllocator) {
6749     mImpl->on_vkDestroySampler(pool, device, sampler, pAllocator);
6750 }
6751 
on_vkCreateSemaphore(android::base::BumpPool * pool,VkDevice device,const VkSemaphoreCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSemaphore * pSemaphore)6752 VkResult VkDecoderGlobalState::on_vkCreateSemaphore(
6753     android::base::BumpPool* pool,
6754     VkDevice device,
6755     const VkSemaphoreCreateInfo* pCreateInfo,
6756     const VkAllocationCallbacks* pAllocator,
6757     VkSemaphore* pSemaphore) {
6758     return mImpl->on_vkCreateSemaphore(pool, device, pCreateInfo, pAllocator, pSemaphore);
6759 }
6760 
on_vkImportSemaphoreFdKHR(android::base::BumpPool * pool,VkDevice device,const VkImportSemaphoreFdInfoKHR * pImportSemaphoreFdInfo)6761 VkResult VkDecoderGlobalState::on_vkImportSemaphoreFdKHR(
6762     android::base::BumpPool* pool,
6763     VkDevice device,
6764     const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo) {
6765     return mImpl->on_vkImportSemaphoreFdKHR(pool, device, pImportSemaphoreFdInfo);
6766 }
6767 
on_vkGetSemaphoreFdKHR(android::base::BumpPool * pool,VkDevice device,const VkSemaphoreGetFdInfoKHR * pGetFdInfo,int * pFd)6768 VkResult VkDecoderGlobalState::on_vkGetSemaphoreFdKHR(
6769     android::base::BumpPool* pool,
6770     VkDevice device,
6771     const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
6772     int* pFd) {
6773     return mImpl->on_vkGetSemaphoreFdKHR(pool, device, pGetFdInfo, pFd);
6774 }
6775 
on_vkDestroySemaphore(android::base::BumpPool * pool,VkDevice device,VkSemaphore semaphore,const VkAllocationCallbacks * pAllocator)6776 void VkDecoderGlobalState::on_vkDestroySemaphore(
6777     android::base::BumpPool* pool,
6778     VkDevice device,
6779     VkSemaphore semaphore,
6780     const VkAllocationCallbacks* pAllocator) {
6781     mImpl->on_vkDestroySemaphore(pool, device, semaphore, pAllocator);
6782 }
6783 
on_vkCreateFence(android::base::BumpPool * pool,VkDevice device,const VkFenceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkFence * pFence)6784 VkResult VkDecoderGlobalState::on_vkCreateFence(
6785         android::base::BumpPool* pool,
6786         VkDevice device,
6787         const VkFenceCreateInfo* pCreateInfo,
6788         const VkAllocationCallbacks* pAllocator,
6789         VkFence* pFence) {
6790     return mImpl->on_vkCreateFence(pool, device, pCreateInfo, pAllocator,
6791                                    pFence);
6792 }
6793 
on_vkDestroyFence(android::base::BumpPool * pool,VkDevice device,VkFence fence,const VkAllocationCallbacks * pAllocator)6794 void VkDecoderGlobalState::on_vkDestroyFence(
6795         android::base::BumpPool* pool,
6796         VkDevice device,
6797         VkFence fence,
6798         const VkAllocationCallbacks* pAllocator) {
6799     return mImpl->on_vkDestroyFence(pool, device, fence, pAllocator);
6800 }
6801 
on_vkCreateDescriptorSetLayout(android::base::BumpPool * pool,VkDevice device,const VkDescriptorSetLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorSetLayout * pSetLayout)6802 VkResult VkDecoderGlobalState::on_vkCreateDescriptorSetLayout(
6803     android::base::BumpPool* pool,
6804     VkDevice device,
6805     const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
6806     const VkAllocationCallbacks* pAllocator,
6807     VkDescriptorSetLayout* pSetLayout) {
6808     return mImpl->on_vkCreateDescriptorSetLayout(pool, device, pCreateInfo, pAllocator, pSetLayout);
6809 }
6810 
on_vkDestroyDescriptorSetLayout(android::base::BumpPool * pool,VkDevice device,VkDescriptorSetLayout descriptorSetLayout,const VkAllocationCallbacks * pAllocator)6811 void VkDecoderGlobalState::on_vkDestroyDescriptorSetLayout(
6812     android::base::BumpPool* pool,
6813     VkDevice device,
6814     VkDescriptorSetLayout descriptorSetLayout,
6815     const VkAllocationCallbacks* pAllocator) {
6816     mImpl->on_vkDestroyDescriptorSetLayout(pool, device, descriptorSetLayout, pAllocator);
6817 }
6818 
on_vkCreateDescriptorPool(android::base::BumpPool * pool,VkDevice device,const VkDescriptorPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorPool * pDescriptorPool)6819 VkResult VkDecoderGlobalState::on_vkCreateDescriptorPool(
6820     android::base::BumpPool* pool,
6821     VkDevice device,
6822     const VkDescriptorPoolCreateInfo* pCreateInfo,
6823     const VkAllocationCallbacks* pAllocator,
6824     VkDescriptorPool* pDescriptorPool) {
6825     return mImpl->on_vkCreateDescriptorPool(pool, device, pCreateInfo, pAllocator, pDescriptorPool);
6826 }
6827 
on_vkDestroyDescriptorPool(android::base::BumpPool * pool,VkDevice device,VkDescriptorPool descriptorPool,const VkAllocationCallbacks * pAllocator)6828 void VkDecoderGlobalState::on_vkDestroyDescriptorPool(
6829     android::base::BumpPool* pool,
6830     VkDevice device,
6831     VkDescriptorPool descriptorPool,
6832     const VkAllocationCallbacks* pAllocator) {
6833     mImpl->on_vkDestroyDescriptorPool(
6834         pool, device, descriptorPool, pAllocator);
6835 }
6836 
on_vkResetDescriptorPool(android::base::BumpPool * pool,VkDevice device,VkDescriptorPool descriptorPool,VkDescriptorPoolResetFlags flags)6837 VkResult VkDecoderGlobalState::on_vkResetDescriptorPool(
6838     android::base::BumpPool* pool,
6839     VkDevice device,
6840     VkDescriptorPool descriptorPool,
6841     VkDescriptorPoolResetFlags flags) {
6842     return mImpl->on_vkResetDescriptorPool(
6843         pool, device, descriptorPool, flags);
6844 }
6845 
on_vkAllocateDescriptorSets(android::base::BumpPool * pool,VkDevice device,const VkDescriptorSetAllocateInfo * pAllocateInfo,VkDescriptorSet * pDescriptorSets)6846 VkResult VkDecoderGlobalState::on_vkAllocateDescriptorSets(
6847     android::base::BumpPool* pool,
6848     VkDevice device,
6849     const VkDescriptorSetAllocateInfo* pAllocateInfo,
6850     VkDescriptorSet* pDescriptorSets) {
6851     return mImpl->on_vkAllocateDescriptorSets(
6852         pool, device, pAllocateInfo, pDescriptorSets);
6853 }
6854 
on_vkFreeDescriptorSets(android::base::BumpPool * pool,VkDevice device,VkDescriptorPool descriptorPool,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets)6855 VkResult VkDecoderGlobalState::on_vkFreeDescriptorSets(
6856     android::base::BumpPool* pool,
6857     VkDevice device,
6858     VkDescriptorPool descriptorPool,
6859     uint32_t descriptorSetCount,
6860     const VkDescriptorSet* pDescriptorSets) {
6861     return mImpl->on_vkFreeDescriptorSets(
6862         pool, device, descriptorPool, descriptorSetCount, pDescriptorSets);
6863 }
6864 
on_vkUpdateDescriptorSets(android::base::BumpPool * pool,VkDevice device,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites,uint32_t descriptorCopyCount,const VkCopyDescriptorSet * pDescriptorCopies)6865 void VkDecoderGlobalState::on_vkUpdateDescriptorSets(
6866     android::base::BumpPool* pool,
6867     VkDevice device,
6868     uint32_t descriptorWriteCount,
6869     const VkWriteDescriptorSet* pDescriptorWrites,
6870     uint32_t descriptorCopyCount,
6871     const VkCopyDescriptorSet* pDescriptorCopies) {
6872     mImpl->on_vkUpdateDescriptorSets(pool, device, descriptorWriteCount,
6873                                      pDescriptorWrites, descriptorCopyCount,
6874                                      pDescriptorCopies);
6875 }
6876 
on_vkCmdCopyBufferToImage(android::base::BumpPool * pool,VkCommandBuffer commandBuffer,VkBuffer srcBuffer,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkBufferImageCopy * pRegions)6877 void VkDecoderGlobalState::on_vkCmdCopyBufferToImage(
6878     android::base::BumpPool* pool,
6879     VkCommandBuffer commandBuffer,
6880     VkBuffer srcBuffer,
6881     VkImage dstImage,
6882     VkImageLayout dstImageLayout,
6883     uint32_t regionCount,
6884     const VkBufferImageCopy* pRegions) {
6885     mImpl->on_vkCmdCopyBufferToImage(pool, commandBuffer, srcBuffer, dstImage,
6886             dstImageLayout, regionCount, pRegions);
6887 }
6888 
on_vkCmdCopyImage(android::base::BumpPool * pool,VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageCopy * pRegions)6889 void VkDecoderGlobalState::on_vkCmdCopyImage(android::base::BumpPool* pool,
6890                                              VkCommandBuffer commandBuffer,
6891                                              VkImage srcImage,
6892                                              VkImageLayout srcImageLayout,
6893                                              VkImage dstImage,
6894                                              VkImageLayout dstImageLayout,
6895                                              uint32_t regionCount,
6896                                              const VkImageCopy* pRegions) {
6897     mImpl->on_vkCmdCopyImage(pool, commandBuffer, srcImage, srcImageLayout,
6898                              dstImage, dstImageLayout, regionCount, pRegions);
6899 }
on_vkCmdCopyImageToBuffer(android::base::BumpPool * pool,VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferImageCopy * pRegions)6900 void VkDecoderGlobalState::on_vkCmdCopyImageToBuffer(
6901         android::base::BumpPool* pool,
6902         VkCommandBuffer commandBuffer,
6903         VkImage srcImage,
6904         VkImageLayout srcImageLayout,
6905         VkBuffer dstBuffer,
6906         uint32_t regionCount,
6907         const VkBufferImageCopy* pRegions) {
6908     mImpl->on_vkCmdCopyImageToBuffer(pool, commandBuffer, srcImage,
6909                                      srcImageLayout, dstBuffer, regionCount,
6910                                      pRegions);
6911 }
6912 
on_vkGetImageMemoryRequirements(android::base::BumpPool * pool,VkDevice device,VkImage image,VkMemoryRequirements * pMemoryRequirements)6913 void VkDecoderGlobalState::on_vkGetImageMemoryRequirements(
6914         android::base::BumpPool* pool,
6915         VkDevice device,
6916         VkImage image,
6917         VkMemoryRequirements* pMemoryRequirements) {
6918     mImpl->on_vkGetImageMemoryRequirements(pool, device, image,
6919                                            pMemoryRequirements);
6920 }
6921 
on_vkGetImageMemoryRequirements2(android::base::BumpPool * pool,VkDevice device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)6922 void VkDecoderGlobalState::on_vkGetImageMemoryRequirements2(
6923         android::base::BumpPool* pool,
6924         VkDevice device,
6925         const VkImageMemoryRequirementsInfo2* pInfo,
6926         VkMemoryRequirements2* pMemoryRequirements) {
6927     mImpl->on_vkGetImageMemoryRequirements2(pool, device, pInfo,
6928                                             pMemoryRequirements);
6929 }
6930 
on_vkGetImageMemoryRequirements2KHR(android::base::BumpPool * pool,VkDevice device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)6931 void VkDecoderGlobalState::on_vkGetImageMemoryRequirements2KHR(
6932         android::base::BumpPool* pool,
6933         VkDevice device,
6934         const VkImageMemoryRequirementsInfo2* pInfo,
6935         VkMemoryRequirements2* pMemoryRequirements) {
6936     mImpl->on_vkGetImageMemoryRequirements2(pool, device, pInfo,
6937                                             pMemoryRequirements);
6938 }
6939 
on_vkCmdPipelineBarrier(android::base::BumpPool * pool,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)6940 void VkDecoderGlobalState::on_vkCmdPipelineBarrier(
6941         android::base::BumpPool* pool,
6942         VkCommandBuffer commandBuffer,
6943         VkPipelineStageFlags srcStageMask,
6944         VkPipelineStageFlags dstStageMask,
6945         VkDependencyFlags dependencyFlags,
6946         uint32_t memoryBarrierCount,
6947         const VkMemoryBarrier* pMemoryBarriers,
6948         uint32_t bufferMemoryBarrierCount,
6949         const VkBufferMemoryBarrier* pBufferMemoryBarriers,
6950         uint32_t imageMemoryBarrierCount,
6951         const VkImageMemoryBarrier* pImageMemoryBarriers) {
6952     mImpl->on_vkCmdPipelineBarrier(
6953             pool, commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
6954             memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
6955             pBufferMemoryBarriers, imageMemoryBarrierCount,
6956             pImageMemoryBarriers);
6957 }
6958 
on_vkAllocateMemory(android::base::BumpPool * pool,VkDevice device,const VkMemoryAllocateInfo * pAllocateInfo,const VkAllocationCallbacks * pAllocator,VkDeviceMemory * pMemory)6959 VkResult VkDecoderGlobalState::on_vkAllocateMemory(
6960     android::base::BumpPool* pool,
6961     VkDevice device,
6962     const VkMemoryAllocateInfo* pAllocateInfo,
6963     const VkAllocationCallbacks* pAllocator,
6964     VkDeviceMemory* pMemory) {
6965     return mImpl->on_vkAllocateMemory(pool, device, pAllocateInfo, pAllocator, pMemory);
6966 }
6967 
on_vkFreeMemory(android::base::BumpPool * pool,VkDevice device,VkDeviceMemory memory,const VkAllocationCallbacks * pAllocator)6968 void VkDecoderGlobalState::on_vkFreeMemory(
6969     android::base::BumpPool* pool,
6970     VkDevice device,
6971     VkDeviceMemory memory,
6972     const VkAllocationCallbacks* pAllocator) {
6973     mImpl->on_vkFreeMemory(pool, device, memory, pAllocator);
6974 }
6975 
on_vkMapMemory(android::base::BumpPool * pool,VkDevice device,VkDeviceMemory memory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)6976 VkResult VkDecoderGlobalState::on_vkMapMemory(
6977     android::base::BumpPool* pool,
6978     VkDevice device,
6979     VkDeviceMemory memory,
6980     VkDeviceSize offset,
6981     VkDeviceSize size,
6982     VkMemoryMapFlags flags,
6983     void** ppData) {
6984     return mImpl->on_vkMapMemory(pool, device, memory, offset, size, flags, ppData);
6985 }
6986 
on_vkUnmapMemory(android::base::BumpPool * pool,VkDevice device,VkDeviceMemory memory)6987 void VkDecoderGlobalState::on_vkUnmapMemory(
6988     android::base::BumpPool* pool,
6989     VkDevice device,
6990     VkDeviceMemory memory) {
6991     mImpl->on_vkUnmapMemory(pool, device, memory);
6992 }
6993 
getMappedHostPointer(VkDeviceMemory memory)6994 uint8_t* VkDecoderGlobalState::getMappedHostPointer(VkDeviceMemory memory) {
6995     return mImpl->getMappedHostPointer(memory);
6996 }
6997 
getDeviceMemorySize(VkDeviceMemory memory)6998 VkDeviceSize VkDecoderGlobalState::getDeviceMemorySize(VkDeviceMemory memory) {
6999     return mImpl->getDeviceMemorySize(memory);
7000 }
7001 
usingDirectMapping() const7002 bool VkDecoderGlobalState::usingDirectMapping() const {
7003     return mImpl->usingDirectMapping();
7004 }
7005 
7006 VkDecoderGlobalState::HostFeatureSupport
getHostFeatureSupport() const7007 VkDecoderGlobalState::getHostFeatureSupport() const {
7008     return mImpl->getHostFeatureSupport();
7009 }
7010 
7011 // VK_ANDROID_native_buffer
on_vkGetSwapchainGrallocUsageANDROID(android::base::BumpPool * pool,VkDevice device,VkFormat format,VkImageUsageFlags imageUsage,int * grallocUsage)7012 VkResult VkDecoderGlobalState::on_vkGetSwapchainGrallocUsageANDROID(
7013     android::base::BumpPool* pool,
7014     VkDevice device,
7015     VkFormat format,
7016     VkImageUsageFlags imageUsage,
7017     int* grallocUsage) {
7018     return mImpl->on_vkGetSwapchainGrallocUsageANDROID(
7019         pool, device, format, imageUsage, grallocUsage);
7020 }
7021 
on_vkGetSwapchainGrallocUsage2ANDROID(android::base::BumpPool * pool,VkDevice device,VkFormat format,VkImageUsageFlags imageUsage,VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,uint64_t * grallocConsumerUsage,uint64_t * grallocProducerUsage)7022 VkResult VkDecoderGlobalState::on_vkGetSwapchainGrallocUsage2ANDROID(
7023     android::base::BumpPool* pool,
7024     VkDevice device,
7025     VkFormat format,
7026     VkImageUsageFlags imageUsage,
7027     VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
7028     uint64_t* grallocConsumerUsage,
7029     uint64_t* grallocProducerUsage) {
7030     return mImpl->on_vkGetSwapchainGrallocUsage2ANDROID(
7031         pool, device, format, imageUsage,
7032         swapchainImageUsage,
7033         grallocConsumerUsage,
7034         grallocProducerUsage);
7035 }
7036 
on_vkAcquireImageANDROID(android::base::BumpPool * pool,VkDevice device,VkImage image,int nativeFenceFd,VkSemaphore semaphore,VkFence fence)7037 VkResult VkDecoderGlobalState::on_vkAcquireImageANDROID(
7038     android::base::BumpPool* pool,
7039     VkDevice device,
7040     VkImage image,
7041     int nativeFenceFd,
7042     VkSemaphore semaphore,
7043     VkFence fence) {
7044     return mImpl->on_vkAcquireImageANDROID(
7045         pool, device, image, nativeFenceFd, semaphore, fence);
7046 }
7047 
on_vkQueueSignalReleaseImageANDROID(android::base::BumpPool * pool,VkQueue queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image,int * pNativeFenceFd)7048 VkResult VkDecoderGlobalState::on_vkQueueSignalReleaseImageANDROID(
7049     android::base::BumpPool* pool,
7050     VkQueue queue,
7051     uint32_t waitSemaphoreCount,
7052     const VkSemaphore* pWaitSemaphores,
7053     VkImage image,
7054     int* pNativeFenceFd) {
7055     return mImpl->on_vkQueueSignalReleaseImageANDROID(
7056         pool, queue, waitSemaphoreCount, pWaitSemaphores,
7057         image, pNativeFenceFd);
7058 }
7059 
7060 // VK_GOOGLE_gfxstream
on_vkMapMemoryIntoAddressSpaceGOOGLE(android::base::BumpPool * pool,VkDevice device,VkDeviceMemory memory,uint64_t * pAddress)7061 VkResult VkDecoderGlobalState::on_vkMapMemoryIntoAddressSpaceGOOGLE(
7062     android::base::BumpPool* pool,
7063     VkDevice device, VkDeviceMemory memory, uint64_t* pAddress) {
7064     return mImpl->on_vkMapMemoryIntoAddressSpaceGOOGLE(
7065         pool, device, memory, pAddress);
7066 }
on_vkGetMemoryHostAddressInfoGOOGLE(android::base::BumpPool * pool,VkDevice device,VkDeviceMemory memory,uint64_t * pAddress,uint64_t * pSize,uint64_t * pHostmemId)7067 VkResult VkDecoderGlobalState::on_vkGetMemoryHostAddressInfoGOOGLE(
7068     android::base::BumpPool* pool,
7069     VkDevice device, VkDeviceMemory memory,
7070     uint64_t* pAddress, uint64_t* pSize, uint64_t* pHostmemId) {
7071     return mImpl->on_vkGetMemoryHostAddressInfoGOOGLE(
7072         pool, device, memory, pAddress, pSize, pHostmemId);
7073 }
7074 
7075 // VK_GOOGLE_gfxstream
on_vkFreeMemorySyncGOOGLE(android::base::BumpPool * pool,VkDevice device,VkDeviceMemory memory,const VkAllocationCallbacks * pAllocator)7076 VkResult VkDecoderGlobalState::on_vkFreeMemorySyncGOOGLE(
7077     android::base::BumpPool* pool,
7078     VkDevice device,
7079     VkDeviceMemory memory,
7080     const VkAllocationCallbacks* pAllocator) {
7081     return mImpl->on_vkFreeMemorySyncGOOGLE(pool, device, memory, pAllocator);
7082 }
7083 
7084 
7085 // VK_GOOGLE_color_buffer
on_vkRegisterImageColorBufferGOOGLE(android::base::BumpPool * pool,VkDevice device,VkImage image,uint32_t colorBuffer)7086 VkResult VkDecoderGlobalState::on_vkRegisterImageColorBufferGOOGLE(
7087     android::base::BumpPool* pool,
7088     VkDevice device, VkImage image, uint32_t colorBuffer) {
7089     return mImpl->on_vkRegisterImageColorBufferGOOGLE(
7090         pool, device, image, colorBuffer);
7091 }
7092 
on_vkRegisterBufferColorBufferGOOGLE(android::base::BumpPool * pool,VkDevice device,VkBuffer buffer,uint32_t colorBuffer)7093 VkResult VkDecoderGlobalState::on_vkRegisterBufferColorBufferGOOGLE(
7094     android::base::BumpPool* pool,
7095     VkDevice device, VkBuffer buffer, uint32_t colorBuffer) {
7096     return mImpl->on_vkRegisterBufferColorBufferGOOGLE(
7097         pool, device, buffer, colorBuffer);
7098 }
7099 
on_vkAllocateCommandBuffers(android::base::BumpPool * pool,VkDevice device,const VkCommandBufferAllocateInfo * pAllocateInfo,VkCommandBuffer * pCommandBuffers)7100 VkResult VkDecoderGlobalState::on_vkAllocateCommandBuffers(
7101     android::base::BumpPool* pool,
7102     VkDevice device,
7103     const VkCommandBufferAllocateInfo* pAllocateInfo,
7104     VkCommandBuffer* pCommandBuffers) {
7105     return mImpl->on_vkAllocateCommandBuffers(pool, device, pAllocateInfo,
7106                                               pCommandBuffers);
7107 }
7108 
on_vkCreateCommandPool(android::base::BumpPool * pool,VkDevice device,const VkCommandPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkCommandPool * pCommandPool)7109 VkResult VkDecoderGlobalState::on_vkCreateCommandPool(
7110     android::base::BumpPool* pool,
7111     VkDevice device,
7112     const VkCommandPoolCreateInfo* pCreateInfo,
7113     const VkAllocationCallbacks* pAllocator,
7114     VkCommandPool* pCommandPool) {
7115     return mImpl->on_vkCreateCommandPool(pool, device, pCreateInfo, pAllocator,
7116                                          pCommandPool);
7117 }
7118 
on_vkDestroyCommandPool(android::base::BumpPool * pool,VkDevice device,VkCommandPool commandPool,const VkAllocationCallbacks * pAllocator)7119 void VkDecoderGlobalState::on_vkDestroyCommandPool(
7120     android::base::BumpPool* pool,
7121     VkDevice device,
7122     VkCommandPool commandPool,
7123     const VkAllocationCallbacks* pAllocator) {
7124     mImpl->on_vkDestroyCommandPool(pool, device, commandPool, pAllocator);
7125 }
7126 
on_vkResetCommandPool(android::base::BumpPool * pool,VkDevice device,VkCommandPool commandPool,VkCommandPoolResetFlags flags)7127 VkResult VkDecoderGlobalState::on_vkResetCommandPool(
7128     android::base::BumpPool* pool,
7129     VkDevice device,
7130     VkCommandPool commandPool,
7131     VkCommandPoolResetFlags flags) {
7132     return mImpl->on_vkResetCommandPool(pool, device, commandPool, flags);
7133 }
7134 
on_vkCmdExecuteCommands(android::base::BumpPool * pool,VkCommandBuffer commandBuffer,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)7135 void VkDecoderGlobalState::on_vkCmdExecuteCommands(
7136     android::base::BumpPool* pool,
7137     VkCommandBuffer commandBuffer,
7138     uint32_t commandBufferCount,
7139     const VkCommandBuffer* pCommandBuffers) {
7140     return mImpl->on_vkCmdExecuteCommands(pool, commandBuffer, commandBufferCount,
7141                                           pCommandBuffers);
7142 }
7143 
on_vkQueueSubmit(android::base::BumpPool * pool,VkQueue queue,uint32_t submitCount,const VkSubmitInfo * pSubmits,VkFence fence)7144 VkResult VkDecoderGlobalState::on_vkQueueSubmit(
7145     android::base::BumpPool* pool,
7146     VkQueue queue,
7147     uint32_t submitCount,
7148     const VkSubmitInfo* pSubmits,
7149     VkFence fence) {
7150     return mImpl->on_vkQueueSubmit(pool, queue, submitCount, pSubmits, fence);
7151 }
7152 
on_vkQueueWaitIdle(android::base::BumpPool * pool,VkQueue queue)7153 VkResult VkDecoderGlobalState::on_vkQueueWaitIdle(
7154         android::base::BumpPool* pool,
7155         VkQueue queue) {
7156     return mImpl->on_vkQueueWaitIdle(pool, queue);
7157 }
7158 
on_vkResetCommandBuffer(android::base::BumpPool * pool,VkCommandBuffer commandBuffer,VkCommandBufferResetFlags flags)7159 VkResult VkDecoderGlobalState::on_vkResetCommandBuffer(
7160     android::base::BumpPool* pool,
7161     VkCommandBuffer commandBuffer,
7162     VkCommandBufferResetFlags flags) {
7163     return mImpl->on_vkResetCommandBuffer(pool, commandBuffer, flags);
7164 }
7165 
on_vkFreeCommandBuffers(android::base::BumpPool * pool,VkDevice device,VkCommandPool commandPool,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)7166 void VkDecoderGlobalState::on_vkFreeCommandBuffers(
7167     android::base::BumpPool* pool,
7168     VkDevice device,
7169     VkCommandPool commandPool,
7170     uint32_t commandBufferCount,
7171     const VkCommandBuffer* pCommandBuffers) {
7172     return mImpl->on_vkFreeCommandBuffers(pool, device, commandPool,
7173                                           commandBufferCount, pCommandBuffers);
7174 }
7175 
on_vkGetPhysicalDeviceExternalSemaphoreProperties(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,VkExternalSemaphoreProperties * pExternalSemaphoreProperties)7176 void VkDecoderGlobalState::on_vkGetPhysicalDeviceExternalSemaphoreProperties(
7177     android::base::BumpPool* pool,
7178     VkPhysicalDevice physicalDevice,
7179     const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
7180     VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
7181     return mImpl->on_vkGetPhysicalDeviceExternalSemaphoreProperties(
7182             pool, physicalDevice, pExternalSemaphoreInfo,
7183             pExternalSemaphoreProperties);
7184 }
7185 
on_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(android::base::BumpPool * pool,VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,VkExternalSemaphoreProperties * pExternalSemaphoreProperties)7186 void VkDecoderGlobalState::on_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(
7187     android::base::BumpPool* pool,
7188     VkPhysicalDevice physicalDevice,
7189     const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
7190     VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
7191     return mImpl->on_vkGetPhysicalDeviceExternalSemaphoreProperties(
7192             pool, physicalDevice, pExternalSemaphoreInfo,
7193             pExternalSemaphoreProperties);
7194 }
7195 
7196 // Descriptor update templates
on_vkCreateDescriptorUpdateTemplate(android::base::BumpPool * pool,VkDevice boxed_device,const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate)7197 VkResult VkDecoderGlobalState::on_vkCreateDescriptorUpdateTemplate(
7198         android::base::BumpPool* pool,
7199     VkDevice boxed_device,
7200     const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
7201     const VkAllocationCallbacks* pAllocator,
7202     VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
7203     return mImpl->on_vkCreateDescriptorUpdateTemplate(
7204         pool, boxed_device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
7205 }
7206 
on_vkCreateDescriptorUpdateTemplateKHR(android::base::BumpPool * pool,VkDevice boxed_device,const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate)7207 VkResult VkDecoderGlobalState::on_vkCreateDescriptorUpdateTemplateKHR(
7208         android::base::BumpPool* pool,
7209     VkDevice boxed_device,
7210     const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
7211     const VkAllocationCallbacks* pAllocator,
7212     VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
7213     return mImpl->on_vkCreateDescriptorUpdateTemplateKHR(
7214         pool, boxed_device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
7215 }
7216 
on_vkDestroyDescriptorUpdateTemplate(android::base::BumpPool * pool,VkDevice boxed_device,VkDescriptorUpdateTemplate descriptorUpdateTemplate,const VkAllocationCallbacks * pAllocator)7217 void VkDecoderGlobalState::on_vkDestroyDescriptorUpdateTemplate(
7218         android::base::BumpPool* pool,
7219     VkDevice boxed_device,
7220     VkDescriptorUpdateTemplate descriptorUpdateTemplate,
7221     const VkAllocationCallbacks* pAllocator) {
7222     mImpl->on_vkDestroyDescriptorUpdateTemplate(
7223         pool, boxed_device, descriptorUpdateTemplate, pAllocator);
7224 }
7225 
on_vkDestroyDescriptorUpdateTemplateKHR(android::base::BumpPool * pool,VkDevice boxed_device,VkDescriptorUpdateTemplate descriptorUpdateTemplate,const VkAllocationCallbacks * pAllocator)7226 void VkDecoderGlobalState::on_vkDestroyDescriptorUpdateTemplateKHR(
7227         android::base::BumpPool* pool,
7228     VkDevice boxed_device,
7229     VkDescriptorUpdateTemplate descriptorUpdateTemplate,
7230     const VkAllocationCallbacks* pAllocator) {
7231     mImpl->on_vkDestroyDescriptorUpdateTemplateKHR(
7232         pool, boxed_device, descriptorUpdateTemplate, pAllocator);
7233 }
7234 
on_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(android::base::BumpPool * pool,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)7235 void VkDecoderGlobalState::on_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(
7236         android::base::BumpPool* pool,
7237     VkDevice boxed_device,
7238     VkDescriptorSet descriptorSet,
7239     VkDescriptorUpdateTemplate descriptorUpdateTemplate,
7240     uint32_t imageInfoCount,
7241     uint32_t bufferInfoCount,
7242     uint32_t bufferViewCount,
7243     const uint32_t* pImageInfoEntryIndices,
7244     const uint32_t* pBufferInfoEntryIndices,
7245     const uint32_t* pBufferViewEntryIndices,
7246     const VkDescriptorImageInfo* pImageInfos,
7247     const VkDescriptorBufferInfo* pBufferInfos,
7248     const VkBufferView* pBufferViews) {
7249     mImpl->on_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(
7250         pool, boxed_device,
7251         descriptorSet,
7252         descriptorUpdateTemplate,
7253         imageInfoCount,
7254         bufferInfoCount,
7255         bufferViewCount,
7256         pImageInfoEntryIndices,
7257         pBufferInfoEntryIndices,
7258         pBufferViewEntryIndices,
7259         pImageInfos,
7260         pBufferInfos,
7261         pBufferViews);
7262 }
7263 
on_vkBeginCommandBuffer(android::base::BumpPool * pool,VkCommandBuffer commandBuffer,const VkCommandBufferBeginInfo * pBeginInfo)7264 VkResult VkDecoderGlobalState::on_vkBeginCommandBuffer(
7265         android::base::BumpPool* pool,
7266         VkCommandBuffer commandBuffer,
7267         const VkCommandBufferBeginInfo* pBeginInfo) {
7268     return mImpl->on_vkBeginCommandBuffer(pool, commandBuffer, pBeginInfo);
7269 }
7270 
on_vkBeginCommandBufferAsyncGOOGLE(android::base::BumpPool * pool,VkCommandBuffer commandBuffer,const VkCommandBufferBeginInfo * pBeginInfo)7271 void VkDecoderGlobalState::on_vkBeginCommandBufferAsyncGOOGLE(
7272     android::base::BumpPool* pool,
7273     VkCommandBuffer commandBuffer,
7274     const VkCommandBufferBeginInfo* pBeginInfo) {
7275     mImpl->on_vkBeginCommandBuffer(pool, commandBuffer, pBeginInfo);
7276 }
7277 
on_vkEndCommandBufferAsyncGOOGLE(android::base::BumpPool * pool,VkCommandBuffer commandBuffer)7278 void VkDecoderGlobalState::on_vkEndCommandBufferAsyncGOOGLE(
7279     android::base::BumpPool* pool,
7280     VkCommandBuffer commandBuffer) {
7281     mImpl->on_vkEndCommandBufferAsyncGOOGLE(
7282         pool, commandBuffer);
7283 }
7284 
on_vkResetCommandBufferAsyncGOOGLE(android::base::BumpPool * pool,VkCommandBuffer commandBuffer,VkCommandBufferResetFlags flags)7285 void VkDecoderGlobalState::on_vkResetCommandBufferAsyncGOOGLE(
7286     android::base::BumpPool* pool,
7287     VkCommandBuffer commandBuffer,
7288     VkCommandBufferResetFlags flags) {
7289     mImpl->on_vkResetCommandBufferAsyncGOOGLE(
7290         pool, commandBuffer, flags);
7291 }
7292 
on_vkCommandBufferHostSyncGOOGLE(android::base::BumpPool * pool,VkCommandBuffer commandBuffer,uint32_t needHostSync,uint32_t sequenceNumber)7293 void VkDecoderGlobalState::on_vkCommandBufferHostSyncGOOGLE(
7294     android::base::BumpPool* pool,
7295     VkCommandBuffer commandBuffer,
7296     uint32_t needHostSync,
7297     uint32_t sequenceNumber) {
7298     mImpl->hostSyncCommandBuffer("hostSync", commandBuffer, needHostSync, sequenceNumber);
7299 }
7300 
on_vkCreateImageWithRequirementsGOOGLE(android::base::BumpPool * pool,VkDevice device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage,VkMemoryRequirements * pMemoryRequirements)7301 VkResult VkDecoderGlobalState::on_vkCreateImageWithRequirementsGOOGLE(
7302     android::base::BumpPool* pool,
7303     VkDevice device,
7304     const VkImageCreateInfo* pCreateInfo,
7305     const VkAllocationCallbacks* pAllocator,
7306     VkImage* pImage,
7307     VkMemoryRequirements* pMemoryRequirements) {
7308     return mImpl->on_vkCreateImageWithRequirementsGOOGLE(
7309             pool, device, pCreateInfo, pAllocator, pImage, pMemoryRequirements);
7310 }
7311 
on_vkCreateBufferWithRequirementsGOOGLE(android::base::BumpPool * pool,VkDevice device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer,VkMemoryRequirements * pMemoryRequirements)7312 VkResult VkDecoderGlobalState::on_vkCreateBufferWithRequirementsGOOGLE(
7313     android::base::BumpPool* pool,
7314     VkDevice device,
7315     const VkBufferCreateInfo* pCreateInfo,
7316     const VkAllocationCallbacks* pAllocator,
7317     VkBuffer* pBuffer,
7318     VkMemoryRequirements* pMemoryRequirements) {
7319     return mImpl->on_vkCreateBufferWithRequirementsGOOGLE(
7320             pool, device, pCreateInfo, pAllocator, pBuffer, pMemoryRequirements);
7321 }
7322 
on_vkCmdBindPipeline(android::base::BumpPool * pool,VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipeline pipeline)7323 void VkDecoderGlobalState::on_vkCmdBindPipeline(
7324         android::base::BumpPool* pool,
7325         VkCommandBuffer commandBuffer,
7326         VkPipelineBindPoint pipelineBindPoint,
7327         VkPipeline pipeline) {
7328     mImpl->on_vkCmdBindPipeline(pool, commandBuffer, pipelineBindPoint,
7329                                 pipeline);
7330 }
7331 
on_vkCmdBindDescriptorSets(android::base::BumpPool * pool,VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipelineLayout layout,uint32_t firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets,uint32_t dynamicOffsetCount,const uint32_t * pDynamicOffsets)7332 void VkDecoderGlobalState::on_vkCmdBindDescriptorSets(
7333         android::base::BumpPool* pool,
7334         VkCommandBuffer commandBuffer,
7335         VkPipelineBindPoint pipelineBindPoint,
7336         VkPipelineLayout layout,
7337         uint32_t firstSet,
7338         uint32_t descriptorSetCount,
7339         const VkDescriptorSet* pDescriptorSets,
7340         uint32_t dynamicOffsetCount,
7341         const uint32_t* pDynamicOffsets) {
7342     mImpl->on_vkCmdBindDescriptorSets(pool, commandBuffer, pipelineBindPoint,
7343                                       layout, firstSet, descriptorSetCount,
7344                                       pDescriptorSets, dynamicOffsetCount,
7345                                       pDynamicOffsets);
7346 }
7347 
on_vkCreateRenderPass(android::base::BumpPool * pool,VkDevice boxed_device,const VkRenderPassCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)7348 VkResult VkDecoderGlobalState::on_vkCreateRenderPass(
7349         android::base::BumpPool* pool,
7350         VkDevice boxed_device,
7351         const VkRenderPassCreateInfo* pCreateInfo,
7352         const VkAllocationCallbacks* pAllocator,
7353         VkRenderPass* pRenderPass) {
7354     return mImpl->on_vkCreateRenderPass(pool, boxed_device, pCreateInfo,
7355                                         pAllocator, pRenderPass);
7356 }
7357 
on_vkQueueHostSyncGOOGLE(android::base::BumpPool * pool,VkQueue queue,uint32_t needHostSync,uint32_t sequenceNumber)7358 void VkDecoderGlobalState::on_vkQueueHostSyncGOOGLE(
7359     android::base::BumpPool* pool,
7360     VkQueue queue,
7361     uint32_t needHostSync,
7362     uint32_t sequenceNumber) {
7363     mImpl->hostSyncQueue("hostSyncQueue", queue, needHostSync, sequenceNumber);
7364 }
7365 
on_vkQueueSubmitAsyncGOOGLE(android::base::BumpPool * pool,VkQueue queue,uint32_t submitCount,const VkSubmitInfo * pSubmits,VkFence fence)7366 void VkDecoderGlobalState::on_vkQueueSubmitAsyncGOOGLE(
7367     android::base::BumpPool* pool,
7368     VkQueue queue,
7369     uint32_t submitCount,
7370     const VkSubmitInfo* pSubmits,
7371     VkFence fence) {
7372     mImpl->on_vkQueueSubmit(pool, queue, submitCount, pSubmits, fence);
7373 }
7374 
on_vkQueueWaitIdleAsyncGOOGLE(android::base::BumpPool * pool,VkQueue queue)7375 void VkDecoderGlobalState::on_vkQueueWaitIdleAsyncGOOGLE(
7376     android::base::BumpPool* pool,
7377     VkQueue queue) {
7378     mImpl->on_vkQueueWaitIdle(pool, queue);
7379 }
7380 
on_vkQueueBindSparseAsyncGOOGLE(android::base::BumpPool * pool,VkQueue queue,uint32_t bindInfoCount,const VkBindSparseInfo * pBindInfo,VkFence fence)7381 void VkDecoderGlobalState::on_vkQueueBindSparseAsyncGOOGLE(
7382     android::base::BumpPool* pool,
7383     VkQueue queue,
7384     uint32_t bindInfoCount,
7385     const VkBindSparseInfo* pBindInfo, VkFence fence) {
7386     mImpl->on_vkQueueBindSparseAsyncGOOGLE(pool, queue, bindInfoCount, pBindInfo, fence);
7387 }
7388 
on_vkGetLinearImageLayoutGOOGLE(android::base::BumpPool * pool,VkDevice device,VkFormat format,VkDeviceSize * pOffset,VkDeviceSize * pRowPitchAlignment)7389 void VkDecoderGlobalState::on_vkGetLinearImageLayoutGOOGLE(
7390     android::base::BumpPool* pool,
7391     VkDevice device,
7392     VkFormat format,
7393     VkDeviceSize* pOffset,
7394     VkDeviceSize* pRowPitchAlignment) {
7395     mImpl->on_vkGetLinearImageLayoutGOOGLE(pool, device, format, pOffset, pRowPitchAlignment);
7396 }
7397 
on_vkQueueFlushCommandsGOOGLE(android::base::BumpPool * pool,VkQueue queue,VkCommandBuffer commandBuffer,VkDeviceSize dataSize,const void * pData)7398 void VkDecoderGlobalState::on_vkQueueFlushCommandsGOOGLE(
7399     android::base::BumpPool* pool,
7400     VkQueue queue,
7401     VkCommandBuffer commandBuffer,
7402     VkDeviceSize dataSize,
7403     const void* pData) {
7404     mImpl->on_vkQueueFlushCommandsGOOGLE(pool, queue, commandBuffer, dataSize, pData);
7405 }
7406 
on_vkQueueCommitDescriptorSetUpdatesGOOGLE(android::base::BumpPool * pool,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)7407 void VkDecoderGlobalState::on_vkQueueCommitDescriptorSetUpdatesGOOGLE(
7408     android::base::BumpPool* pool,
7409     VkQueue queue,
7410     uint32_t descriptorPoolCount,
7411     const VkDescriptorPool* pDescriptorPools,
7412     uint32_t descriptorSetCount,
7413     const VkDescriptorSetLayout* pDescriptorSetLayouts,
7414     const uint64_t* pDescriptorSetPoolIds,
7415     const uint32_t* pDescriptorSetWhichPool,
7416     const uint32_t* pDescriptorSetPendingAllocation,
7417     const uint32_t* pDescriptorWriteStartingIndices,
7418     uint32_t pendingDescriptorWriteCount,
7419     const VkWriteDescriptorSet* pPendingDescriptorWrites) {
7420     mImpl->on_vkQueueCommitDescriptorSetUpdatesGOOGLE(pool, queue, descriptorPoolCount, pDescriptorPools, descriptorSetCount, pDescriptorSetLayouts, pDescriptorSetPoolIds, pDescriptorSetWhichPool, pDescriptorSetPendingAllocation, pDescriptorWriteStartingIndices, pendingDescriptorWriteCount, pPendingDescriptorWrites);
7421 }
7422 
on_vkCollectDescriptorPoolIdsGOOGLE(android::base::BumpPool * pool,VkDevice device,VkDescriptorPool descriptorPool,uint32_t * pPoolIdCount,uint64_t * pPoolIds)7423 void VkDecoderGlobalState::on_vkCollectDescriptorPoolIdsGOOGLE(
7424     android::base::BumpPool* pool,
7425     VkDevice device,
7426     VkDescriptorPool descriptorPool,
7427     uint32_t* pPoolIdCount,
7428     uint64_t* pPoolIds) {
7429     mImpl->on_vkCollectDescriptorPoolIdsGOOGLE(pool, device, descriptorPool, pPoolIdCount, pPoolIds);
7430 }
7431 
waitForFence(VkFence boxed_fence,uint64_t timeout)7432 VkResult VkDecoderGlobalState::waitForFence(VkFence boxed_fence,
7433                                             uint64_t timeout) {
7434     return mImpl->waitForFence(boxed_fence, timeout);
7435 }
7436 
getFenceStatus(VkFence boxed_fence)7437 VkResult VkDecoderGlobalState::getFenceStatus(VkFence boxed_fence) {
7438     return mImpl->getFenceStatus(boxed_fence);
7439 }
7440 
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)7441 void VkDecoderGlobalState::deviceMemoryTransform_tohost(
7442     VkDeviceMemory* memory, uint32_t memoryCount,
7443     VkDeviceSize* offset, uint32_t offsetCount,
7444     VkDeviceSize* size, uint32_t sizeCount,
7445     uint32_t* typeIndex, uint32_t typeIndexCount,
7446     uint32_t* typeBits, uint32_t typeBitsCount) {
7447     // Not used currently
7448     (void)memory; (void)memoryCount;
7449     (void)offset; (void)offsetCount;
7450     (void)size; (void)sizeCount;
7451     (void)typeIndex; (void)typeIndexCount;
7452     (void)typeBits; (void)typeBitsCount;
7453 }
7454 
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)7455 void VkDecoderGlobalState::deviceMemoryTransform_fromhost(
7456     VkDeviceMemory* memory, uint32_t memoryCount,
7457     VkDeviceSize* offset, uint32_t offsetCount,
7458     VkDeviceSize* size, uint32_t sizeCount,
7459     uint32_t* typeIndex, uint32_t typeIndexCount,
7460     uint32_t* typeBits, uint32_t typeBitsCount) {
7461     // Not used currently
7462     (void)memory; (void)memoryCount;
7463     (void)offset; (void)offsetCount;
7464     (void)size; (void)sizeCount;
7465     (void)typeIndex; (void)typeIndexCount;
7466     (void)typeBits; (void)typeBitsCount;
7467 }
7468 
snapshot()7469 VkDecoderSnapshot* VkDecoderGlobalState::snapshot() {
7470     return mImpl->snapshot();
7471 }
7472 
7473 #define DEFINE_TRANSFORMED_TYPE_IMPL(type) \
7474     void VkDecoderGlobalState::transformImpl_##type##_tohost(const type* val, uint32_t count) { \
7475         mImpl->transformImpl_##type##_tohost(val, count); \
7476     } \
7477     void VkDecoderGlobalState::transformImpl_##type##_fromhost(const type* val, uint32_t count) { \
7478         mImpl->transformImpl_##type##_fromhost(val, count); \
7479     } \
7480 
7481 LIST_TRANSFORMED_TYPES(DEFINE_TRANSFORMED_TYPE_IMPL)
7482 
7483 #define DEFINE_BOXED_DISPATCHABLE_HANDLE_API_DEF(type) \
7484     type VkDecoderGlobalState::new_boxed_##type(type underlying, VulkanDispatch* dispatch, bool ownDispatch) { \
7485         return mImpl->new_boxed_##type(underlying, dispatch, ownDispatch); \
7486     } \
7487     void VkDecoderGlobalState::delete_##type(type boxed) { \
7488         mImpl->delete_##type(boxed); \
7489     } \
7490     type VkDecoderGlobalState::unbox_##type(type boxed) { \
7491         return mImpl->unbox_##type(boxed); \
7492     } \
7493     type VkDecoderGlobalState::unboxed_to_boxed_##type(type unboxed) { \
7494         return mImpl->unboxed_to_boxed_##type(unboxed); \
7495     } \
7496     VulkanDispatch* VkDecoderGlobalState::dispatch_##type(type boxed) { \
7497         return mImpl->dispatch_##type(boxed); \
7498     } \
7499 
7500 #define DEFINE_BOXED_NON_DISPATCHABLE_HANDLE_API_DEF(type) \
7501     type VkDecoderGlobalState::new_boxed_non_dispatchable_##type(type underlying) { \
7502         return mImpl->new_boxed_non_dispatchable_##type(underlying); \
7503     } \
7504     void VkDecoderGlobalState::delete_##type(type boxed) { \
7505         mImpl->delete_##type(boxed); \
7506     } \
7507     type VkDecoderGlobalState::unbox_##type(type boxed) { \
7508         return mImpl->unbox_##type(boxed); \
7509     } \
7510     type VkDecoderGlobalState::unboxed_to_boxed_non_dispatchable_##type(type unboxed) { \
7511         return mImpl->unboxed_to_boxed_non_dispatchable_##type(unboxed); \
7512     } \
7513 
GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(DEFINE_BOXED_DISPATCHABLE_HANDLE_API_DEF)7514 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(DEFINE_BOXED_DISPATCHABLE_HANDLE_API_DEF)
7515 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(DEFINE_BOXED_NON_DISPATCHABLE_HANDLE_API_DEF)
7516 
7517 #define DEFINE_BOXED_DISPATCHABLE_HANDLE_GLOBAL_API_DEF(type) \
7518     type unbox_##type(type boxed) { \
7519         auto elt = sBoxedHandleManager.get( \
7520                 (uint64_t)(uintptr_t)boxed); \
7521         if (!elt) return VK_NULL_HANDLE; \
7522         return (type)elt->underlying; \
7523     } \
7524     VulkanDispatch* dispatch_##type(type boxed) { \
7525         auto elt = sBoxedHandleManager.get( \
7526                 (uint64_t)(uintptr_t)boxed); \
7527         if (!elt) { fprintf(stderr, "%s: err not found boxed %p\n", __func__, boxed); return nullptr; } \
7528         return elt->dispatch; \
7529     } \
7530     void delete_##type(type boxed) { \
7531         if (!boxed) return; \
7532         auto elt = sBoxedHandleManager.get( \
7533             (uint64_t)(uintptr_t)boxed); \
7534         if (!elt) return; \
7535         releaseOrderMaintInfo(elt->ordMaintInfo); \
7536         if (elt->readStream) { \
7537             sReadStreamRegistry.push(elt->readStream); \
7538             elt->readStream = nullptr; \
7539         } \
7540         sBoxedHandleManager.remove((uint64_t)boxed); \
7541     } \
7542     type unboxed_to_boxed_##type(type unboxed) { \
7543         AutoLock lock(sBoxedHandleManager.lock); \
7544         return (type)sBoxedHandleManager.getBoxedFromUnboxedLocked( \
7545                 (uint64_t)(uintptr_t)unboxed); \
7546     } \
7547 
7548 #define DEFINE_BOXED_NON_DISPATCHABLE_HANDLE_GLOBAL_API_DEF(type) \
7549     type new_boxed_non_dispatchable_##type(type underlying) { \
7550         return VkDecoderGlobalState::get()->new_boxed_non_dispatchable_##type(underlying); \
7551     } \
7552     void delete_##type(type boxed) { \
7553         if (!boxed) return; \
7554         sBoxedHandleManager.remove((uint64_t)boxed); \
7555     } \
7556     void delayed_delete_##type(type boxed, VkDevice device, std::function<void()> callback) { \
7557         sBoxedHandleManager.removeDelayed((uint64_t)boxed, device, callback); \
7558     } \
7559     type unbox_##type(type boxed) { \
7560         if (!boxed) return boxed; \
7561         auto elt = sBoxedHandleManager.get( \
7562                 (uint64_t)(uintptr_t)boxed); \
7563         if (!elt) { fprintf(stderr, "%s: unbox %p failed, not found\n", __func__, boxed); abort(); return VK_NULL_HANDLE; } \
7564         return (type)elt->underlying; \
7565     } \
7566     type unboxed_to_boxed_non_dispatchable_##type(type unboxed) { \
7567         AutoLock lock(sBoxedHandleManager.lock); \
7568         return (type)sBoxedHandleManager.getBoxedFromUnboxedLocked( \
7569                 (uint64_t)(uintptr_t)unboxed); \
7570     } \
7571 
7572 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(DEFINE_BOXED_DISPATCHABLE_HANDLE_GLOBAL_API_DEF)
7573 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(DEFINE_BOXED_NON_DISPATCHABLE_HANDLE_GLOBAL_API_DEF)
7574 
7575 void BoxedHandleUnwrapAndDeletePreserveBoxedMapping::setup(android::base::BumpPool* pool, uint64_t** bufPtr) {
7576     mPool = pool;
7577     mPreserveBufPtr = bufPtr;
7578 }
7579 
allocPreserve(size_t count)7580 void BoxedHandleUnwrapAndDeletePreserveBoxedMapping::allocPreserve(size_t count) {
7581     *mPreserveBufPtr = (uint64_t*)mPool->alloc(count * sizeof(uint64_t));
7582 }
7583 
7584 #define BOXED_DISPATCHABLE_HANDLE_UNWRAP_AND_DELETE_PRESERVE_BOXED_IMPL(type_name) \
7585     void BoxedHandleUnwrapAndDeletePreserveBoxedMapping::mapHandles_##type_name(type_name* handles, size_t count) { \
7586         allocPreserve(count); \
7587         for (size_t i = 0; i < count; ++i) { \
7588             (*mPreserveBufPtr)[i] = (uint64_t)(handles[i]); \
7589             if (handles[i]) { handles[i] = VkDecoderGlobalState::get()->unbox_##type_name(handles[i]); } else { handles[i] = (type_name)nullptr; } ; \
7590         } \
7591     } \
7592     void BoxedHandleUnwrapAndDeletePreserveBoxedMapping::mapHandles_##type_name##_u64(const type_name* handles, uint64_t* handle_u64s, size_t count) { \
7593         allocPreserve(count); \
7594         for (size_t i = 0; i < count; ++i) { \
7595             (*mPreserveBufPtr)[i] = (uint64_t)(handle_u64s[i]); \
7596             if (handles[i]) { handle_u64s[i] = (uint64_t)VkDecoderGlobalState::get()->unbox_##type_name(handles[i]); } else { handle_u64s[i] = 0; } \
7597         } \
7598     } \
7599     void BoxedHandleUnwrapAndDeletePreserveBoxedMapping::mapHandles_u64_##type_name(const uint64_t* handle_u64s, type_name* handles, size_t count) { \
7600         allocPreserve(count); \
7601         for (size_t i = 0; i < count; ++i) { \
7602             (*mPreserveBufPtr)[i] = (uint64_t)(handle_u64s[i]); \
7603             if (handle_u64s[i]) { handles[i] = VkDecoderGlobalState::get()->unbox_##type_name((type_name)(uintptr_t)handle_u64s[i]); } else { handles[i] = (type_name)nullptr; } \
7604         } \
7605     } \
7606 
7607 #define BOXED_NON_DISPATCHABLE_HANDLE_UNWRAP_AND_DELETE_PRESERVE_BOXED_IMPL(type_name) \
7608     void BoxedHandleUnwrapAndDeletePreserveBoxedMapping::mapHandles_##type_name(type_name* handles, size_t count) { \
7609         allocPreserve(count); \
7610         for (size_t i = 0; i < count; ++i) { \
7611             (*mPreserveBufPtr)[i] = (uint64_t)(handles[i]); \
7612             if (handles[i]) { auto boxed = handles[i]; handles[i] = VkDecoderGlobalState::get()->unbox_##type_name(handles[i]); delete_##type_name(boxed); } else { handles[i] = (type_name)nullptr; }; \
7613         } \
7614     } \
7615     void BoxedHandleUnwrapAndDeletePreserveBoxedMapping::mapHandles_##type_name##_u64(const type_name* handles, uint64_t* handle_u64s, size_t count) { \
7616         allocPreserve(count); \
7617         for (size_t i = 0; i < count; ++i) { \
7618             (*mPreserveBufPtr)[i] = (uint64_t)(handle_u64s[i]); \
7619             if (handles[i]) { auto boxed = handles[i]; handle_u64s[i] = (uint64_t)VkDecoderGlobalState::get()->unbox_##type_name(handles[i]); delete_##type_name(boxed); } else { handle_u64s[i] = 0; } \
7620         } \
7621     } \
7622     void BoxedHandleUnwrapAndDeletePreserveBoxedMapping::mapHandles_u64_##type_name(const uint64_t* handle_u64s, type_name* handles, size_t count) { \
7623         allocPreserve(count); \
7624         for (size_t i = 0; i < count; ++i) { \
7625             (*mPreserveBufPtr)[i] = (uint64_t)(handle_u64s[i]); \
7626             if (handle_u64s[i]) { auto boxed = (type_name)(uintptr_t)handle_u64s[i]; handles[i] = VkDecoderGlobalState::get()->unbox_##type_name((type_name)(uintptr_t)handle_u64s[i]); delete_##type_name(boxed); } else { handles[i] = (type_name)nullptr; } \
7627         } \
7628     } \
7629 
7630 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(BOXED_DISPATCHABLE_HANDLE_UNWRAP_AND_DELETE_PRESERVE_BOXED_IMPL)
7631 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(BOXED_NON_DISPATCHABLE_HANDLE_UNWRAP_AND_DELETE_PRESERVE_BOXED_IMPL)
7632 
7633 }  // namespace goldfish_vk
7634