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, ®ion);
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, ®ion);
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