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