Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
mock_vulkan.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <cstdint>
8#include <cstring>
9#include <utility>
10#include <vector>
11
12#include "flutter/fml/logging.h"
14#include "impeller/renderer/backend/vulkan/vk.h" // IWYU pragma: keep.
15#include "third_party/swiftshader/include/vulkan/vulkan_core.h"
16#include "vulkan/vulkan.hpp"
17
18namespace impeller {
19namespace testing {
20
21namespace {
22
23struct MockCommandBuffer {
24 explicit MockCommandBuffer(
25 std::shared_ptr<std::vector<std::string>> called_functions)
26 : called_functions_(std::move(called_functions)) {}
27 std::shared_ptr<std::vector<std::string>> called_functions_;
28 std::vector<VkImageMemoryBarrier> image_memory_barriers_;
29 std::vector<VkViewport> recorded_viewports_;
30};
31
32struct MockQueryPool {};
33
34struct MockCommandPool {};
35
36struct MockDescriptorPool {};
37
38struct MockSurfaceKHR {};
39
40struct MockImage {};
41
42struct MockSwapchainKHR {
43 std::array<MockImage, 3> images;
44 size_t current_image = 0;
45};
46
47struct MockSemaphore {};
48
49struct MockFramebuffer {};
50
51static ISize currentImageSize = ISize{1, 1};
52
53class MockDevice final {
54 public:
55 explicit MockDevice() : called_functions_(new std::vector<std::string>()) {}
56
57 MockCommandBuffer* NewCommandBuffer() {
58 auto buffer = std::make_unique<MockCommandBuffer>(called_functions_);
59 MockCommandBuffer* result = buffer.get();
60 Lock lock(command_buffers_mutex_);
61 command_buffers_.emplace_back(std::move(buffer));
62 return result;
63 }
64
65 MockCommandPool* NewCommandPool() {
66 auto pool = std::make_unique<MockCommandPool>();
67 MockCommandPool* result = pool.get();
68 Lock lock(commmand_pools_mutex_);
69 command_pools_.emplace_back(std::move(pool));
70 return result;
71 }
72
73 void DeleteCommandPool(MockCommandPool* pool) {
74 Lock lock(commmand_pools_mutex_);
75 auto it = std::find_if(command_pools_.begin(), command_pools_.end(),
76 [pool](const std::unique_ptr<MockCommandPool>& p) {
77 return p.get() == pool;
78 });
79 if (it != command_pools_.end()) {
80 command_pools_.erase(it);
81 }
82 }
83
84 const std::shared_ptr<std::vector<std::string>>& GetCalledFunctions() {
85 return called_functions_;
86 }
87
88 void AddCalledFunction(const std::string& function) {
89 Lock lock(called_functions_mutex_);
90 called_functions_->push_back(function);
91 }
92
93 private:
94 MockDevice(const MockDevice&) = delete;
95
96 MockDevice& operator=(const MockDevice&) = delete;
97
98 Mutex called_functions_mutex_;
99 std::shared_ptr<std::vector<std::string>> called_functions_
100 IPLR_GUARDED_BY(called_functions_mutex_);
101
102 Mutex command_buffers_mutex_;
103 std::vector<std::unique_ptr<MockCommandBuffer>> command_buffers_
104 IPLR_GUARDED_BY(command_buffers_mutex_);
105
106 Mutex commmand_pools_mutex_;
107 std::vector<std::unique_ptr<MockCommandPool>> command_pools_
108 IPLR_GUARDED_BY(commmand_pools_mutex_);
109};
110
111struct MockVulkanState {
112 std::vector<std::string> instance_extensions;
113 std::vector<std::string> instance_layers;
114 std::vector<std::string> device_extensions;
115 std::function<void(VkPhysicalDevice physicalDevice,
116 VkFormat format,
117 VkFormatProperties* pFormatProperties)>
119 std::function<void(VkPhysicalDevice physicalDevice,
120 VkPhysicalDeviceProperties* pProperties)>
122 std::function<std::remove_pointer_t<PFN_vkWaitForFences>>
124 std::function<std::remove_pointer_t<PFN_vkAcquireNextImageKHR>>
126 // When > 0, the next vkCreateImage for a fixed-rate-compressed image returns
127 // VK_ERROR_COMPRESSION_EXHAUSTED_EXT and decrements (models PowerVR).
129};
130
131class MockVulkanStatePtr {
132 public:
133 MockVulkanStatePtr() = default;
134
135 ~MockVulkanStatePtr() {
136 FML_CHECK(ptr_ == nullptr)
137 << "MockVulkanState was not null upon thread exit. Leak detected!";
138 }
139
140 void reset(MockVulkanState* ptr = nullptr) {
141 if (ptr_) {
142 delete ptr_;
143 }
144 ptr_ = ptr;
145 }
146
147 MockVulkanStatePtr(const MockVulkanStatePtr&) = delete;
148 MockVulkanStatePtr& operator=(const MockVulkanStatePtr&) = delete;
149 MockVulkanState* get() const { return ptr_; }
150 MockVulkanState& operator*() const { return *ptr_; }
151 MockVulkanState* operator->() const { return ptr_; }
152 explicit operator bool() const { return ptr_ != nullptr; }
153
154 private:
155 MockVulkanState* ptr_ = nullptr;
156};
157
158static thread_local MockVulkanStatePtr g_mock_vulkan_state;
159
160static MockVulkanState& GetMockVulkanState() {
161 FML_CHECK(g_mock_vulkan_state) << "MockVulkanState must be initialized.";
162 return *g_mock_vulkan_state;
163}
164
165void noop() {}
166
167VkResult vkEnumerateInstanceExtensionProperties(
168 const char* pLayerName,
169 uint32_t* pPropertyCount,
170 VkExtensionProperties* pProperties) {
171 if (!pProperties) {
172 *pPropertyCount = GetMockVulkanState().instance_extensions.size();
173 return VK_SUCCESS;
174 } else {
175 uint32_t count = 0;
176 VkResult result = VK_SUCCESS;
177 for (const std::string& ext : GetMockVulkanState().instance_extensions) {
178 if (count >= *pPropertyCount) {
179 result = VK_INCOMPLETE;
180 break;
181 }
182 snprintf(pProperties[count].extensionName,
183 sizeof(pProperties[count].extensionName), "%s", ext.c_str());
184 pProperties[count].specVersion = 0;
185 count++;
186 }
187 *pPropertyCount = count;
188 return result;
189 }
190}
191
192VkResult vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount,
193 VkLayerProperties* pProperties) {
194 if (!pProperties) {
195 *pPropertyCount = GetMockVulkanState().instance_layers.size();
196 return VK_SUCCESS;
197 } else {
198 uint32_t count = 0;
199 VkResult result = VK_SUCCESS;
200 for (const std::string& ext : GetMockVulkanState().instance_layers) {
201 if (count >= *pPropertyCount) {
202 result = VK_INCOMPLETE;
203 break;
204 }
205 snprintf(pProperties[count].layerName,
206 sizeof(pProperties[count].layerName), "%s", ext.c_str());
207 pProperties[count].specVersion = 0;
208 count++;
209 }
210 *pPropertyCount = count;
211 return result;
212 }
213}
214
215VkResult vkEnumeratePhysicalDevices(VkInstance instance,
216 uint32_t* pPhysicalDeviceCount,
217 VkPhysicalDevice* pPhysicalDevices) {
218 if (!pPhysicalDevices) {
219 *pPhysicalDeviceCount = 1;
220 } else {
221 pPhysicalDevices[0] = reinterpret_cast<VkPhysicalDevice>(0xfeedface);
222 }
223 return VK_SUCCESS;
224}
225
226void vkGetPhysicalDeviceFormatProperties(
227 VkPhysicalDevice physicalDevice,
228 VkFormat format,
229 VkFormatProperties* pFormatProperties) {
230 if (GetMockVulkanState().format_properties_callback) {
231 GetMockVulkanState().format_properties_callback(physicalDevice, format,
232 pFormatProperties);
233 }
234}
235
236void vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
237 VkPhysicalDeviceProperties* pProperties) {
238 pProperties->limits.framebufferColorSampleCounts =
239 static_cast<VkSampleCountFlags>(VK_SAMPLE_COUNT_1_BIT |
240 VK_SAMPLE_COUNT_4_BIT);
241 pProperties->limits.maxImageDimension2D = 4096;
242 pProperties->limits.timestampPeriod = 1;
243 if (GetMockVulkanState().physical_device_properties_callback) {
244 GetMockVulkanState().physical_device_properties_callback(physicalDevice,
245 pProperties);
246 }
247}
248
249void vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
250 VkPhysicalDeviceFeatures2* pFeatures) {
251 // Advertise the features the mock supports by walking the pNext chain.
252 auto* next = reinterpret_cast<VkBaseOutStructure*>(pFeatures->pNext);
253 while (next != nullptr) {
254 if (next->sType ==
255 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT) {
256 reinterpret_cast<VkPhysicalDeviceImageCompressionControlFeaturesEXT*>(
257 next)
258 ->imageCompressionControl = VK_TRUE;
259 }
260 next = next->pNext;
261 }
262}
263
264VkResult vkGetPhysicalDeviceImageFormatProperties2(
265 VkPhysicalDevice physicalDevice,
266 const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
267 VkImageFormatProperties2* pImageFormatProperties) {
268 // Report fixed-rate compression support when it is queried (i.e. the input
269 // carries a VkImageCompressionControlEXT and the output a
270 // VkImageCompressionPropertiesEXT).
271 bool compression_requested = false;
272 const auto* in =
273 reinterpret_cast<const VkBaseInStructure*>(pImageFormatInfo->pNext);
274 while (in != nullptr) {
275 if (in->sType == VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT) {
276 compression_requested = true;
277 }
278 in = in->pNext;
279 }
280 auto* out =
281 reinterpret_cast<VkBaseOutStructure*>(pImageFormatProperties->pNext);
282 while (compression_requested && out != nullptr) {
283 if (out->sType == VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT) {
284 auto* props = reinterpret_cast<VkImageCompressionPropertiesEXT*>(out);
285 props->imageCompressionFlags =
286 VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT;
287 props->imageCompressionFixedRateFlags =
288 VK_IMAGE_COMPRESSION_FIXED_RATE_4BPC_BIT_EXT;
289 }
290 out = out->pNext;
291 }
292 return VK_SUCCESS;
293}
294
295void vkGetPhysicalDeviceQueueFamilyProperties(
296 VkPhysicalDevice physicalDevice,
297 uint32_t* pQueueFamilyPropertyCount,
298 VkQueueFamilyProperties* pQueueFamilyProperties) {
299 if (!pQueueFamilyProperties) {
300 *pQueueFamilyPropertyCount = 1;
301 } else {
302 pQueueFamilyProperties[0].queueCount = 3;
303 pQueueFamilyProperties[0].queueFlags = static_cast<VkQueueFlags>(
304 VK_QUEUE_TRANSFER_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT);
305 }
306}
307
308VkResult vkEnumerateDeviceExtensionProperties(
309 VkPhysicalDevice physicalDevice,
310 const char* pLayerName,
311 uint32_t* pPropertyCount,
312 VkExtensionProperties* pProperties) {
313 if (!pProperties) {
314 *pPropertyCount = GetMockVulkanState().device_extensions.size();
315 return VK_SUCCESS;
316 } else {
317 uint32_t count = 0;
318 VkResult result = VK_SUCCESS;
319 for (const std::string& ext : GetMockVulkanState().device_extensions) {
320 if (count >= *pPropertyCount) {
321 result = VK_INCOMPLETE;
322 break;
323 }
324 snprintf(pProperties[count].extensionName,
325 sizeof(pProperties[count].extensionName), "%s", ext.c_str());
326 pProperties[count].specVersion = 0;
327 count++;
328 }
329 *pPropertyCount = count;
330 return result;
331 }
332}
333
334VkResult vkCreateDevice(VkPhysicalDevice physicalDevice,
335 const VkDeviceCreateInfo* pCreateInfo,
336 const VkAllocationCallbacks* pAllocator,
337 VkDevice* pDevice) {
338 *pDevice = reinterpret_cast<VkDevice>(new MockDevice());
339 return VK_SUCCESS;
340}
341
342VkResult vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
343 const VkAllocationCallbacks* pAllocator,
344 VkInstance* pInstance) {
345 *pInstance = reinterpret_cast<VkInstance>(0xbaadf00d);
346 return VK_SUCCESS;
347}
348
349void vkGetPhysicalDeviceMemoryProperties(
350 VkPhysicalDevice physicalDevice,
351 VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
352 pMemoryProperties->memoryTypeCount = 2;
353 pMemoryProperties->memoryHeapCount = 2;
354 pMemoryProperties->memoryTypes[0].heapIndex = 0;
355 pMemoryProperties->memoryTypes[0].propertyFlags =
356 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
357 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
358 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
359 pMemoryProperties->memoryTypes[1].heapIndex = 1;
360 pMemoryProperties->memoryTypes[1].propertyFlags =
361 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
362 pMemoryProperties->memoryHeaps[0].size = 1024 * 1024 * 1024;
363 pMemoryProperties->memoryHeaps[0].flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT;
364 pMemoryProperties->memoryHeaps[1].size = 1024 * 1024 * 1024;
365 pMemoryProperties->memoryHeaps[1].flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT;
366}
367
368VkResult vkCreatePipelineCache(VkDevice device,
369 const VkPipelineCacheCreateInfo* pCreateInfo,
370 const VkAllocationCallbacks* pAllocator,
371 VkPipelineCache* pPipelineCache) {
372 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
373 mock_device->AddCalledFunction("vkCreatePipelineCache");
374 *pPipelineCache = reinterpret_cast<VkPipelineCache>(0xb000dead);
375 return VK_SUCCESS;
376}
377
378VkResult vkCreateCommandPool(VkDevice device,
379 const VkCommandPoolCreateInfo* pCreateInfo,
380 const VkAllocationCallbacks* pAllocator,
381 VkCommandPool* pCommandPool) {
382 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
383 mock_device->AddCalledFunction("vkCreateCommandPool");
384 *pCommandPool =
385 reinterpret_cast<VkCommandPool>(mock_device->NewCommandPool());
386 return VK_SUCCESS;
387}
388
389VkResult vkResetCommandPool(VkDevice device,
390 VkCommandPool commandPool,
391 VkCommandPoolResetFlags flags) {
392 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
393 if (flags & VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT) {
394 mock_device->AddCalledFunction("vkResetCommandPoolReleaseResources");
395 } else {
396 mock_device->AddCalledFunction("vkResetCommandPool");
397 }
398 return VK_SUCCESS;
399}
400
401VkResult vkAllocateCommandBuffers(
402 VkDevice device,
403 const VkCommandBufferAllocateInfo* pAllocateInfo,
404 VkCommandBuffer* pCommandBuffers) {
405 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
406 mock_device->AddCalledFunction("vkAllocateCommandBuffers");
407 *pCommandBuffers =
408 reinterpret_cast<VkCommandBuffer>(mock_device->NewCommandBuffer());
409 return VK_SUCCESS;
410}
411
412VkResult vkBeginCommandBuffer(VkCommandBuffer commandBuffer,
413 const VkCommandBufferBeginInfo* pBeginInfo) {
414 return VK_SUCCESS;
415}
416
417VkResult vkCreateImage(VkDevice device,
418 const VkImageCreateInfo* pCreateInfo,
419 const VkAllocationCallbacks* pAllocator,
420 VkImage* pImage) {
421 reinterpret_cast<MockDevice*>(device)->AddCalledFunction("vkCreateImage");
422 // Simulate VK_ERROR_COMPRESSION_EXHAUSTED_EXT for fixed-rate-compressed image
423 // creates (the spec only returns this error for compression requests).
424 if (g_mock_vulkan_state &&
425 g_mock_vulkan_state->compression_exhausted_create_image_failures > 0) {
426 const auto* next =
427 reinterpret_cast<const VkBaseInStructure*>(pCreateInfo->pNext);
428 while (next != nullptr) {
429 if (next->sType == VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT) {
430 g_mock_vulkan_state->compression_exhausted_create_image_failures--;
431 return VK_ERROR_COMPRESSION_EXHAUSTED_EXT;
432 }
433 next = next->pNext;
434 }
435 }
436 *pImage = reinterpret_cast<VkImage>(0xD0D0CACA);
437 return VK_SUCCESS;
438}
439
440void vkGetImageMemoryRequirements2KHR(
441 VkDevice device,
442 const VkImageMemoryRequirementsInfo2* pInfo,
443 VkMemoryRequirements2* pMemoryRequirements) {
444 pMemoryRequirements->memoryRequirements.size = 1024;
445 pMemoryRequirements->memoryRequirements.memoryTypeBits = 1;
446}
447
448VkResult vkAllocateMemory(VkDevice device,
449 const VkMemoryAllocateInfo* pAllocateInfo,
450 const VkAllocationCallbacks* pAllocator,
451 VkDeviceMemory* pMemory) {
452 *pMemory = reinterpret_cast<VkDeviceMemory>(0xCAFEB0BA);
453 return VK_SUCCESS;
454}
455
456VkResult vkBindImageMemory(VkDevice device,
457 VkImage image,
458 VkDeviceMemory memory,
459 VkDeviceSize memoryOffset) {
460 return VK_SUCCESS;
461}
462
463VkResult vkCreateImageView(VkDevice device,
464 const VkImageViewCreateInfo* pCreateInfo,
465 const VkAllocationCallbacks* pAllocator,
466 VkImageView* pView) {
467 *pView = reinterpret_cast<VkImageView>(0xFEE1DEAD);
468 return VK_SUCCESS;
469}
470
471VkResult vkCreateBuffer(VkDevice device,
472 const VkBufferCreateInfo* pCreateInfo,
473 const VkAllocationCallbacks* pAllocator,
474 VkBuffer* pBuffer) {
475 *pBuffer = reinterpret_cast<VkBuffer>(0xDEADDEAD);
476 return VK_SUCCESS;
477}
478
479void vkGetBufferMemoryRequirements2KHR(
480 VkDevice device,
481 const VkBufferMemoryRequirementsInfo2* pInfo,
482 VkMemoryRequirements2* pMemoryRequirements) {
483 pMemoryRequirements->memoryRequirements.size = 1024;
484 pMemoryRequirements->memoryRequirements.memoryTypeBits = 1;
485}
486
487VkResult vkBindBufferMemory(VkDevice device,
488 VkBuffer buffer,
489 VkDeviceMemory memory,
490 VkDeviceSize memoryOffset) {
491 return VK_SUCCESS;
492}
493
494VkResult vkCreateRenderPass(VkDevice device,
495 const VkRenderPassCreateInfo* pCreateInfo,
496 const VkAllocationCallbacks* pAllocator,
497 VkRenderPass* pRenderPass) {
498 *pRenderPass = reinterpret_cast<VkRenderPass>(0x12341234);
499 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
500 mock_device->AddCalledFunction("vkCreateRenderPass");
501 return VK_SUCCESS;
502}
503
504VkResult vkCreateDescriptorSetLayout(
505 VkDevice device,
506 const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
507 const VkAllocationCallbacks* pAllocator,
508 VkDescriptorSetLayout* pSetLayout) {
509 *pSetLayout = reinterpret_cast<VkDescriptorSetLayout>(0x77777777);
510 return VK_SUCCESS;
511}
512
513VkResult vkCreatePipelineLayout(VkDevice device,
514 const VkPipelineLayoutCreateInfo* pCreateInfo,
515 const VkAllocationCallbacks* pAllocator,
516 VkPipelineLayout* pPipelineLayout) {
517 *pPipelineLayout = reinterpret_cast<VkPipelineLayout>(0x88888888);
518 return VK_SUCCESS;
519}
520
521VkResult vkCreateGraphicsPipelines(
522 VkDevice device,
523 VkPipelineCache pipelineCache,
524 uint32_t createInfoCount,
525 const VkGraphicsPipelineCreateInfo* pCreateInfos,
526 const VkAllocationCallbacks* pAllocator,
527 VkPipeline* pPipelines) {
528 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
529 mock_device->AddCalledFunction("vkCreateGraphicsPipelines");
530 *pPipelines = reinterpret_cast<VkPipeline>(0x99999999);
531 return VK_SUCCESS;
532}
533
534VkResult vkDeviceWaitIdle(VkDevice device) {
535 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
536 mock_device->AddCalledFunction("vkDeviceWaitIdle");
537 return VK_SUCCESS;
538}
539
540void vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
541 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
542 mock_device->AddCalledFunction("vkDestroyDevice");
543 delete reinterpret_cast<MockDevice*>(device);
544}
545
546void vkDestroyInstance(VkInstance instance,
547 const VkAllocationCallbacks* pAllocator) {
548 if (g_mock_vulkan_state) {
549 g_mock_vulkan_state.reset();
550 }
551}
552
553void vkDestroyPipeline(VkDevice device,
554 VkPipeline pipeline,
555 const VkAllocationCallbacks* pAllocator) {
556 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
557 mock_device->AddCalledFunction("vkDestroyPipeline");
558}
559
560VkResult vkCreateShaderModule(VkDevice device,
561 const VkShaderModuleCreateInfo* pCreateInfo,
562 const VkAllocationCallbacks* pAllocator,
563 VkShaderModule* pShaderModule) {
564 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
565 mock_device->AddCalledFunction("vkCreateShaderModule");
566 *pShaderModule = reinterpret_cast<VkShaderModule>(0x11111111);
567 return VK_SUCCESS;
568}
569
570void vkDestroyShaderModule(VkDevice device,
571 VkShaderModule shaderModule,
572 const VkAllocationCallbacks* pAllocator) {
573 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
574 mock_device->AddCalledFunction("vkDestroyShaderModule");
575}
576
577void vkDestroyPipelineCache(VkDevice device,
578 VkPipelineCache pipelineCache,
579 const VkAllocationCallbacks* pAllocator) {
580 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
581 mock_device->AddCalledFunction("vkDestroyPipelineCache");
582}
583
584void vkDestroySurfaceKHR(VkInstance instance,
585 VkSurfaceKHR surface,
586 const VkAllocationCallbacks* pAllocator) {
587 return;
588}
589
590void vkCmdBindPipeline(VkCommandBuffer commandBuffer,
591 VkPipelineBindPoint pipelineBindPoint,
592 VkPipeline pipeline) {
593 MockCommandBuffer* mock_command_buffer =
594 reinterpret_cast<MockCommandBuffer*>(commandBuffer);
595 mock_command_buffer->called_functions_->push_back("vkCmdBindPipeline");
596}
597
598void vkCmdPipelineBarrier(VkCommandBuffer commandBuffer,
599 VkPipelineStageFlags srcStageMask,
600 VkPipelineStageFlags dstStageMask,
601 VkDependencyFlags dependencyFlags,
602 uint32_t memoryBarrierCount,
603 const VkMemoryBarrier* pMemoryBarriers,
604 uint32_t bufferMemoryBarrierCount,
605 const VkBufferMemoryBarrier* pBufferMemoryBarriers,
606 uint32_t imageMemoryBarrierCount,
607 const VkImageMemoryBarrier* pImageMemoryBarriers) {
608 MockCommandBuffer* mock_command_buffer =
609 reinterpret_cast<MockCommandBuffer*>(commandBuffer);
610 mock_command_buffer->called_functions_->push_back("vkCmdPipelineBarrier");
611 if (pImageMemoryBarriers) {
612 for (uint32_t i = 0; i < imageMemoryBarrierCount; ++i) {
613 mock_command_buffer->image_memory_barriers_.push_back(
614 pImageMemoryBarriers[i]);
615 }
616 }
617}
618
619void vkCmdSetStencilReference(VkCommandBuffer commandBuffer,
620 VkStencilFaceFlags faceMask,
621 uint32_t reference) {
622 MockCommandBuffer* mock_command_buffer =
623 reinterpret_cast<MockCommandBuffer*>(commandBuffer);
624 mock_command_buffer->called_functions_->push_back("vkCmdSetStencilReference");
625}
626
627void vkCmdSetScissor(VkCommandBuffer commandBuffer,
628 uint32_t firstScissor,
629 uint32_t scissorCount,
630 const VkRect2D* pScissors) {
631 MockCommandBuffer* mock_command_buffer =
632 reinterpret_cast<MockCommandBuffer*>(commandBuffer);
633 mock_command_buffer->called_functions_->push_back("vkCmdSetScissor");
634}
635
636void vkCmdSetViewport(VkCommandBuffer commandBuffer,
637 uint32_t firstViewport,
638 uint32_t viewportCount,
639 const VkViewport* pViewports) {
640 MockCommandBuffer* mock_command_buffer =
641 reinterpret_cast<MockCommandBuffer*>(commandBuffer);
642 mock_command_buffer->called_functions_->push_back("vkCmdSetViewport");
643 for (uint32_t i = 0; i < viewportCount; ++i) {
644 mock_command_buffer->recorded_viewports_.push_back(pViewports[i]);
645 }
646}
647
648void vkFreeCommandBuffers(VkDevice device,
649 VkCommandPool commandPool,
650 uint32_t commandBufferCount,
651 const VkCommandBuffer* pCommandBuffers) {
652 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
653 mock_device->AddCalledFunction("vkFreeCommandBuffers");
654}
655
656void vkDestroyCommandPool(VkDevice device,
657 VkCommandPool commandPool,
658 const VkAllocationCallbacks* pAllocator) {
659 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
660 mock_device->DeleteCommandPool(
661 reinterpret_cast<MockCommandPool*>(commandPool));
662 mock_device->AddCalledFunction("vkDestroyCommandPool");
663}
664
665VkResult vkEndCommandBuffer(VkCommandBuffer commandBuffer) {
666 return VK_SUCCESS;
667}
668
669VkResult vkCreateFence(VkDevice device,
670 const VkFenceCreateInfo* pCreateInfo,
671 const VkAllocationCallbacks* pAllocator,
672 VkFence* pFence) {
673 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
674 mock_device->AddCalledFunction("vkCreateFence");
675 *pFence = reinterpret_cast<VkFence>(new MockFence());
676 return VK_SUCCESS;
677}
678
679VkResult vkDestroyFence(VkDevice device,
680 VkFence fence,
681 const VkAllocationCallbacks* pAllocator) {
682 delete reinterpret_cast<MockFence*>(fence);
683 return VK_SUCCESS;
684}
685
686VkResult vkQueueSubmit(VkQueue queue,
687 uint32_t submitCount,
688 const VkSubmitInfo* pSubmits,
689 VkFence fence) {
690 return VK_SUCCESS;
691}
692
693VkResult vkWaitForFences(VkDevice device,
694 uint32_t fenceCount,
695 const VkFence* pFences,
696 VkBool32 waitAll,
697 uint64_t timeout) {
698 if (g_mock_vulkan_state && GetMockVulkanState().wait_for_fences_callback) {
699 return GetMockVulkanState().wait_for_fences_callback(
700 device, fenceCount, pFences, waitAll, timeout);
701 }
702 return VK_SUCCESS;
703}
704
705VkResult vkGetFenceStatus(VkDevice device, VkFence fence) {
706 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
707 MockFence* mock_fence = reinterpret_cast<MockFence*>(fence);
708 return mock_fence->GetStatus();
709}
710
711VkResult vkResetFences(VkDevice device,
712 uint32_t fenceCount,
713 const VkFence* fences) {
714 return VK_SUCCESS;
715}
716
717VkResult vkCreateDebugUtilsMessengerEXT(
718 VkInstance instance,
719 const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
720 const VkAllocationCallbacks* pAllocator,
721 VkDebugUtilsMessengerEXT* pMessenger) {
722 return VK_SUCCESS;
723}
724
725VkResult vkSetDebugUtilsObjectNameEXT(
726 VkDevice device,
727 const VkDebugUtilsObjectNameInfoEXT* pNameInfo) {
728 return VK_SUCCESS;
729}
730
731VkResult vkCreateQueryPool(VkDevice device,
732 const VkQueryPoolCreateInfo* pCreateInfo,
733 const VkAllocationCallbacks* pAllocator,
734 VkQueryPool* pQueryPool) {
735 *pQueryPool = reinterpret_cast<VkQueryPool>(new MockQueryPool());
736 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
737 mock_device->AddCalledFunction("vkCreateQueryPool");
738 return VK_SUCCESS;
739}
740
741void vkDestroyQueryPool(VkDevice device,
742 VkQueryPool queryPool,
743 const VkAllocationCallbacks* pAllocator) {
744 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
745 mock_device->AddCalledFunction("vkDestroyQueryPool");
746 delete reinterpret_cast<MockQueryPool*>(queryPool);
747}
748
749VkResult vkGetQueryPoolResults(VkDevice device,
750 VkQueryPool queryPool,
751 uint32_t firstQuery,
752 uint32_t queryCount,
753 size_t dataSize,
754 void* pData,
755 VkDeviceSize stride,
756 VkQueryResultFlags flags) {
757 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
758 if (dataSize == sizeof(uint32_t)) {
759 uint32_t* data = static_cast<uint32_t*>(pData);
760 for (auto i = firstQuery; i < queryCount; i++) {
761 data[0] = i;
762 }
763 } else if (dataSize == sizeof(int64_t)) {
764 uint64_t* data = static_cast<uint64_t*>(pData);
765 for (auto i = firstQuery; i < queryCount; i++) {
766 data[0] = i;
767 }
768 }
769 mock_device->AddCalledFunction("vkGetQueryPoolResults");
770 return VK_SUCCESS;
771}
772
773VkResult vkCreateDescriptorPool(VkDevice device,
774 const VkDescriptorPoolCreateInfo* pCreateInfo,
775 const VkAllocationCallbacks* pAllocator,
776 VkDescriptorPool* pDescriptorPool) {
777 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
778 *pDescriptorPool =
779 reinterpret_cast<VkDescriptorPool>(new MockDescriptorPool());
780 mock_device->AddCalledFunction("vkCreateDescriptorPool");
781 return VK_SUCCESS;
782}
783
784void vkDestroyDescriptorPool(VkDevice device,
785 VkDescriptorPool descriptorPool,
786 const VkAllocationCallbacks* pAllocator) {
787 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
788 mock_device->AddCalledFunction("vkDestroyDescriptorPool");
789 delete reinterpret_cast<MockDescriptorPool*>(descriptorPool);
790}
791
792VkResult vkResetDescriptorPool(VkDevice device,
793 VkDescriptorPool descriptorPool,
794 VkDescriptorPoolResetFlags flags) {
795 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
796 mock_device->AddCalledFunction("vkResetDescriptorPool");
797 return VK_SUCCESS;
798}
799
800VkResult vkAllocateDescriptorSets(
801 VkDevice device,
802 const VkDescriptorSetAllocateInfo* pAllocateInfo,
803 VkDescriptorSet* pDescriptorSets) {
804 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
805 mock_device->AddCalledFunction("vkAllocateDescriptorSets");
806 return VK_SUCCESS;
807}
808
809VkResult vkGetPhysicalDeviceSurfaceFormatsKHR(
810 VkPhysicalDevice physicalDevice,
811 VkSurfaceKHR surface,
812 uint32_t* pSurfaceFormatCount,
813 VkSurfaceFormatKHR* pSurfaceFormats) {
814 *pSurfaceFormatCount = 1u;
815 if (pSurfaceFormats != nullptr) {
816 pSurfaceFormats[0] =
817 VkSurfaceFormatKHR{.format = VK_FORMAT_R8G8B8A8_UNORM,
818 .colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
819 }
820 return VK_SUCCESS;
821}
822
823VkResult vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
824 VkPhysicalDevice physicalDevice,
825 VkSurfaceKHR surface,
826 VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) {
827 *pSurfaceCapabilities = VkSurfaceCapabilitiesKHR{
828 .minImageCount = 3,
829 .maxImageCount = 6,
830 .currentExtent =
831 VkExtent2D{
832 .width = static_cast<uint32_t>(currentImageSize.width),
833 .height = static_cast<uint32_t>(currentImageSize.height),
834 },
835 .minImageExtent =
836 VkExtent2D{
837 .width = 0,
838 .height = 0,
839 },
840 .maxImageExtent =
841 VkExtent2D{
842 .width = static_cast<uint32_t>(currentImageSize.width),
843 .height = static_cast<uint32_t>(currentImageSize.height),
844 },
845 .maxImageArrayLayers = 1,
846 .supportedTransforms =
847 VkSurfaceTransformFlagBitsKHR::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
848 .currentTransform =
849 VkSurfaceTransformFlagBitsKHR::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
850 .supportedCompositeAlpha = VkCompositeAlphaFlagBitsKHR::
851 VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR,
852 .supportedUsageFlags =
853 VkImageUsageFlagBits::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT};
854 return VK_SUCCESS;
855}
856
857VkResult vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
858 uint32_t queueFamilyIndex,
859 VkSurfaceKHR surface,
860 VkBool32* pSupported) {
861 *pSupported = VK_TRUE;
862 return VK_SUCCESS;
863}
864
865VkResult vkCreateSwapchainKHR(VkDevice device,
866 const VkSwapchainCreateInfoKHR* pCreateInfo,
867 const VkAllocationCallbacks* pAllocator,
868 VkSwapchainKHR* pSwapchain) {
869 *pSwapchain = reinterpret_cast<VkSwapchainKHR>(new MockSwapchainKHR());
870 return VK_SUCCESS;
871}
872
873void vkDestroySwapchainKHR(VkDevice device,
874 VkSwapchainKHR swapchain,
875 const VkAllocationCallbacks* pAllocator) {
876 delete reinterpret_cast<MockSwapchainKHR*>(swapchain);
877}
878
879VkResult vkGetSwapchainImagesKHR(VkDevice device,
880 VkSwapchainKHR swapchain,
881 uint32_t* pSwapchainImageCount,
882 VkImage* pSwapchainImages) {
883 MockSwapchainKHR* mock_swapchain =
884 reinterpret_cast<MockSwapchainKHR*>(swapchain);
885 auto& images = mock_swapchain->images;
886 *pSwapchainImageCount = images.size();
887 if (pSwapchainImages != nullptr) {
888 for (size_t i = 0; i < images.size(); i++) {
889 pSwapchainImages[i] = reinterpret_cast<VkImage>(&images[i]);
890 }
891 }
892 return VK_SUCCESS;
893}
894
895VkResult vkCreateSemaphore(VkDevice device,
896 const VkSemaphoreCreateInfo* pCreateInfo,
897 const VkAllocationCallbacks* pAllocator,
898 VkSemaphore* pSemaphore) {
899 *pSemaphore = reinterpret_cast<VkSemaphore>(new MockSemaphore());
900 return VK_SUCCESS;
901}
902
903void vkDestroySemaphore(VkDevice device,
904 VkSemaphore semaphore,
905 const VkAllocationCallbacks* pAllocator) {
906 delete reinterpret_cast<MockSemaphore*>(semaphore);
907}
908
909VkResult vkAcquireNextImageKHR(VkDevice device,
910 VkSwapchainKHR swapchain,
911 uint64_t timeout,
912 VkSemaphore semaphore,
913 VkFence fence,
914 uint32_t* pImageIndex) {
915 if (g_mock_vulkan_state && GetMockVulkanState().acquire_next_image_callback) {
916 return GetMockVulkanState().acquire_next_image_callback(
917 device, swapchain, timeout, semaphore, fence, pImageIndex);
918 }
919 auto current_index =
920 reinterpret_cast<MockSwapchainKHR*>(swapchain)->current_image++;
921 *pImageIndex = (current_index + 1) % 3u;
922 return VK_SUCCESS;
923}
924
925VkResult vkCreateFramebuffer(VkDevice device,
926 const VkFramebufferCreateInfo* pCreateInfo,
927 const VkAllocationCallbacks* pAllocator,
928 VkFramebuffer* pFramebuffer) {
929 *pFramebuffer = reinterpret_cast<VkFramebuffer>(new MockFramebuffer());
930 return VK_SUCCESS;
931}
932
933void vkDestroyFramebuffer(VkDevice device,
934 VkFramebuffer framebuffer,
935 const VkAllocationCallbacks* pAllocator) {
936 delete reinterpret_cast<MockFramebuffer*>(framebuffer);
937}
938
939void vkTrimCommandPool(VkDevice device,
940 VkCommandPool commandPool,
941 VkCommandPoolTrimFlags flags) {
942 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
943 mock_device->AddCalledFunction("vkTrimCommandPool");
944}
945
946VkResult vkGetPipelineCacheData(VkDevice device,
947 VkPipelineCache pipelineCache,
948 size_t* pDataSize,
949 void* pData) {
950 if (pData) {
951 const std::array<uint8_t, 5> cache_data{1, 2, 3, 4, 5};
952 size_t dst_buffer_size = *pDataSize;
953 size_t length = std::min(dst_buffer_size, cache_data.size());
954 std::memcpy(pData, cache_data.data(), length);
955 *pDataSize = length;
956 return (dst_buffer_size >= length) ? VK_SUCCESS : VK_INCOMPLETE;
957 } else {
958 *pDataSize = 10;
959 return VK_SUCCESS;
960 }
961}
962
963PFN_vkVoidFunction GetMockVulkanProcAddress(VkInstance instance,
964 const char* pName) {
965 if (strcmp("vkEnumerateInstanceExtensionProperties", pName) == 0) {
966 return reinterpret_cast<PFN_vkVoidFunction>(
967 vkEnumerateInstanceExtensionProperties);
968 } else if (strcmp("vkEnumerateInstanceLayerProperties", pName) == 0) {
969 return reinterpret_cast<PFN_vkVoidFunction>(
970 vkEnumerateInstanceLayerProperties);
971 } else if (strcmp("vkEnumeratePhysicalDevices", pName) == 0) {
972 return reinterpret_cast<PFN_vkVoidFunction>(vkEnumeratePhysicalDevices);
973 } else if (strcmp("vkGetPhysicalDeviceFormatProperties", pName) == 0) {
974 return reinterpret_cast<PFN_vkVoidFunction>(
975 vkGetPhysicalDeviceFormatProperties);
976 } else if (strcmp("vkGetPhysicalDeviceProperties", pName) == 0) {
977 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceProperties);
978 } else if (strcmp("vkGetPhysicalDeviceFeatures2", pName) == 0 ||
979 strcmp("vkGetPhysicalDeviceFeatures2KHR", pName) == 0) {
980 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceFeatures2);
981 } else if (strcmp("vkGetPhysicalDeviceImageFormatProperties2", pName) == 0 ||
982 strcmp("vkGetPhysicalDeviceImageFormatProperties2KHR", pName) ==
983 0) {
984 return reinterpret_cast<PFN_vkVoidFunction>(
985 vkGetPhysicalDeviceImageFormatProperties2);
986 } else if (strcmp("vkGetPhysicalDeviceQueueFamilyProperties", pName) == 0) {
987 return reinterpret_cast<PFN_vkVoidFunction>(
988 vkGetPhysicalDeviceQueueFamilyProperties);
989 } else if (strcmp("vkEnumerateDeviceExtensionProperties", pName) == 0) {
990 return reinterpret_cast<PFN_vkVoidFunction>(
991 vkEnumerateDeviceExtensionProperties);
992 } else if (strcmp("vkCreateDevice", pName) == 0) {
993 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateDevice);
994 } else if (strcmp("vkCreateInstance", pName) == 0) {
995 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateInstance);
996 } else if (strcmp("vkGetPhysicalDeviceMemoryProperties", pName) == 0) {
997 return reinterpret_cast<PFN_vkVoidFunction>(
998 vkGetPhysicalDeviceMemoryProperties);
999 } else if (strcmp("vkCreatePipelineCache", pName) == 0) {
1000 return reinterpret_cast<PFN_vkVoidFunction>(vkCreatePipelineCache);
1001 } else if (strcmp("vkCreateCommandPool", pName) == 0) {
1002 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateCommandPool);
1003 } else if (strcmp("vkResetCommandPool", pName) == 0) {
1004 return reinterpret_cast<PFN_vkVoidFunction>(vkResetCommandPool);
1005 } else if (strcmp("vkAllocateCommandBuffers", pName) == 0) {
1006 return reinterpret_cast<PFN_vkVoidFunction>(vkAllocateCommandBuffers);
1007 } else if (strcmp("vkBeginCommandBuffer", pName) == 0) {
1008 return reinterpret_cast<PFN_vkVoidFunction>(vkBeginCommandBuffer);
1009 } else if (strcmp("vkCreateImage", pName) == 0) {
1010 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateImage);
1011 } else if (strcmp("vkGetInstanceProcAddr", pName) == 0) {
1012 return reinterpret_cast<PFN_vkVoidFunction>(GetMockVulkanProcAddress);
1013 } else if (strcmp("vkGetDeviceProcAddr", pName) == 0) {
1014 return reinterpret_cast<PFN_vkVoidFunction>(GetMockVulkanProcAddress);
1015 } else if (strcmp("vkGetImageMemoryRequirements2KHR", pName) == 0 ||
1016 strcmp("vkGetImageMemoryRequirements2", pName) == 0) {
1017 return reinterpret_cast<PFN_vkVoidFunction>(
1018 vkGetImageMemoryRequirements2KHR);
1019 } else if (strcmp("vkAllocateMemory", pName) == 0) {
1020 return reinterpret_cast<PFN_vkVoidFunction>(vkAllocateMemory);
1021 } else if (strcmp("vkBindImageMemory", pName) == 0) {
1022 return reinterpret_cast<PFN_vkVoidFunction>(vkBindImageMemory);
1023 } else if (strcmp("vkCreateImageView", pName) == 0) {
1024 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateImageView);
1025 } else if (strcmp("vkCreateBuffer", pName) == 0) {
1026 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateBuffer);
1027 } else if (strcmp("vkGetBufferMemoryRequirements2KHR", pName) == 0 ||
1028 strcmp("vkGetBufferMemoryRequirements2", pName) == 0) {
1029 return reinterpret_cast<PFN_vkVoidFunction>(
1030 vkGetBufferMemoryRequirements2KHR);
1031 } else if (strcmp("vkBindBufferMemory", pName) == 0) {
1032 return reinterpret_cast<PFN_vkVoidFunction>(vkBindBufferMemory);
1033 } else if (strcmp("vkCreateRenderPass", pName) == 0) {
1034 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateRenderPass);
1035 } else if (strcmp("vkCreateDescriptorSetLayout", pName) == 0) {
1036 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateDescriptorSetLayout);
1037 } else if (strcmp("vkCreatePipelineLayout", pName) == 0) {
1038 return reinterpret_cast<PFN_vkVoidFunction>(vkCreatePipelineLayout);
1039 } else if (strcmp("vkCreateGraphicsPipelines", pName) == 0) {
1040 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateGraphicsPipelines);
1041 } else if (strcmp("vkDeviceWaitIdle", pName) == 0) {
1042 return reinterpret_cast<PFN_vkVoidFunction>(vkDeviceWaitIdle);
1043 } else if (strcmp("vkDestroyDevice", pName) == 0) {
1044 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroyDevice);
1045 } else if (strcmp("vkDestroyInstance", pName) == 0) {
1046 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroyInstance);
1047 } else if (strcmp("vkDestroyPipeline", pName) == 0) {
1048 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroyPipeline);
1049 } else if (strcmp("vkCreateShaderModule", pName) == 0) {
1050 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateShaderModule);
1051 } else if (strcmp("vkDestroyShaderModule", pName) == 0) {
1052 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroyShaderModule);
1053 } else if (strcmp("vkDestroyPipelineCache", pName) == 0) {
1054 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroyPipelineCache);
1055 } else if (strcmp("vkCmdBindPipeline", pName) == 0) {
1056 return reinterpret_cast<PFN_vkVoidFunction>(vkCmdBindPipeline);
1057 } else if (strcmp("vkCmdPipelineBarrier", pName) == 0) {
1058 return reinterpret_cast<PFN_vkVoidFunction>(vkCmdPipelineBarrier);
1059 } else if (strcmp("vkCmdSetStencilReference", pName) == 0) {
1060 return reinterpret_cast<PFN_vkVoidFunction>(vkCmdSetStencilReference);
1061 } else if (strcmp("vkCmdSetScissor", pName) == 0) {
1062 return reinterpret_cast<PFN_vkVoidFunction>(vkCmdSetScissor);
1063 } else if (strcmp("vkCmdSetViewport", pName) == 0) {
1064 return reinterpret_cast<PFN_vkVoidFunction>(vkCmdSetViewport);
1065 } else if (strcmp("vkDestroyCommandPool", pName) == 0) {
1066 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroyCommandPool);
1067 } else if (strcmp("vkFreeCommandBuffers", pName) == 0) {
1068 return reinterpret_cast<PFN_vkVoidFunction>(vkFreeCommandBuffers);
1069 } else if (strcmp("vkEndCommandBuffer", pName) == 0) {
1070 return reinterpret_cast<PFN_vkVoidFunction>(vkEndCommandBuffer);
1071 } else if (strcmp("vkCreateFence", pName) == 0) {
1072 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateFence);
1073 } else if (strcmp("vkDestroyFence", pName) == 0) {
1074 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroyFence);
1075 } else if (strcmp("vkQueueSubmit", pName) == 0) {
1076 return reinterpret_cast<PFN_vkVoidFunction>(vkQueueSubmit);
1077 } else if (strcmp("vkWaitForFences", pName) == 0) {
1078 return reinterpret_cast<PFN_vkVoidFunction>(vkWaitForFences);
1079 } else if (strcmp("vkGetFenceStatus", pName) == 0) {
1080 return reinterpret_cast<PFN_vkVoidFunction>(vkGetFenceStatus);
1081 } else if (strcmp("vkResetFences", pName) == 0) {
1082 return reinterpret_cast<PFN_vkVoidFunction>(vkResetFences);
1083 } else if (strcmp("vkCreateDebugUtilsMessengerEXT", pName) == 0) {
1084 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateDebugUtilsMessengerEXT);
1085 } else if (strcmp("vkSetDebugUtilsObjectNameEXT", pName) == 0) {
1086 return reinterpret_cast<PFN_vkVoidFunction>(vkSetDebugUtilsObjectNameEXT);
1087 } else if (strcmp("vkCreateQueryPool", pName) == 0) {
1088 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateQueryPool);
1089 } else if (strcmp("vkDestroyQueryPool", pName) == 0) {
1090 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroyQueryPool);
1091 } else if (strcmp("vkGetQueryPoolResults", pName) == 0) {
1092 return reinterpret_cast<PFN_vkVoidFunction>(vkGetQueryPoolResults);
1093 } else if (strcmp("vkCreateDescriptorPool", pName) == 0) {
1094 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateDescriptorPool);
1095 } else if (strcmp("vkDestroyDescriptorPool", pName) == 0) {
1096 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroyDescriptorPool);
1097 } else if (strcmp("vkResetDescriptorPool", pName) == 0) {
1098 return reinterpret_cast<PFN_vkVoidFunction>(vkResetDescriptorPool);
1099 } else if (strcmp("vkAllocateDescriptorSets", pName) == 0) {
1100 return reinterpret_cast<PFN_vkVoidFunction>(vkAllocateDescriptorSets);
1101 } else if (strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", pName) == 0) {
1102 return reinterpret_cast<PFN_vkVoidFunction>(
1103 vkGetPhysicalDeviceSurfaceFormatsKHR);
1104 } else if (strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", pName) == 0) {
1105 return reinterpret_cast<PFN_vkVoidFunction>(
1106 vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
1107 } else if (strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", pName) == 0) {
1108 return reinterpret_cast<PFN_vkVoidFunction>(
1109 vkGetPhysicalDeviceSurfaceSupportKHR);
1110 } else if (strcmp("vkCreateSwapchainKHR", pName) == 0) {
1111 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateSwapchainKHR);
1112 } else if (strcmp("vkDestroySwapchainKHR", pName) == 0) {
1113 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroySwapchainKHR);
1114 } else if (strcmp("vkGetSwapchainImagesKHR", pName) == 0) {
1115 return reinterpret_cast<PFN_vkVoidFunction>(vkGetSwapchainImagesKHR);
1116 } else if (strcmp("vkCreateSemaphore", pName) == 0) {
1117 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateSemaphore);
1118 } else if (strcmp("vkDestroySemaphore", pName) == 0) {
1119 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroySemaphore);
1120 } else if (strcmp("vkDestroySurfaceKHR", pName) == 0) {
1121 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroySurfaceKHR);
1122 } else if (strcmp("vkAcquireNextImageKHR", pName) == 0) {
1123 return reinterpret_cast<PFN_vkVoidFunction>(vkAcquireNextImageKHR);
1124 } else if (strcmp("vkCreateFramebuffer", pName) == 0) {
1125 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateFramebuffer);
1126 } else if (strcmp("vkDestroyFramebuffer", pName) == 0) {
1127 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroyFramebuffer);
1128 } else if (strcmp("vkTrimCommandPool", pName) == 0) {
1129 return reinterpret_cast<PFN_vkVoidFunction>(vkTrimCommandPool);
1130 } else if (strcmp("vkGetPipelineCacheData", pName) == 0) {
1131 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPipelineCacheData);
1132 }
1133 return noop;
1134}
1135
1136} // namespace
1137
1139 : instance_extensions_({"VK_KHR_surface", "VK_MVK_macos_surface"}),
1140 device_extensions_({"VK_KHR_swapchain"}),
1141 format_properties_callback_([](VkPhysicalDevice physicalDevice,
1142 VkFormat format,
1143 VkFormatProperties* pFormatProperties) {
1144 if (format == VK_FORMAT_R8G8B8A8_UNORM) {
1145 pFormatProperties->optimalTilingFeatures =
1146 static_cast<VkFormatFeatureFlags>(
1147 vk::FormatFeatureFlagBits::eColorAttachment);
1148 } else if (format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
1149 pFormatProperties->optimalTilingFeatures =
1150 static_cast<VkFormatFeatureFlags>(
1151 vk::FormatFeatureFlagBits::eDepthStencilAttachment);
1152 } else if (format == VK_FORMAT_S8_UINT) {
1153 pFormatProperties->optimalTilingFeatures =
1154 static_cast<VkFormatFeatureFlags>(
1155 vk::FormatFeatureFlagBits::eDepthStencilAttachment);
1156 }
1157 }) {}
1158
1159std::shared_ptr<ContextVK> MockVulkanContextBuilder::Build() {
1160 auto message_loop = fml::ConcurrentMessageLoop::Create();
1161 ContextVK::Settings settings;
1162 settings.proc_address_callback = GetMockVulkanProcAddress;
1163 if (settings_callback_) {
1164 settings_callback_(settings);
1165 }
1166 g_mock_vulkan_state.reset(new MockVulkanState());
1167 g_mock_vulkan_state->instance_extensions = instance_extensions_;
1168 g_mock_vulkan_state->instance_layers = instance_layers_;
1169 g_mock_vulkan_state->device_extensions = device_extensions_;
1170 g_mock_vulkan_state->format_properties_callback = format_properties_callback_;
1171 g_mock_vulkan_state->physical_device_properties_callback =
1172 physical_properties_callback_;
1173 g_mock_vulkan_state->acquire_next_image_callback =
1174 acquire_next_image_callback_;
1175 g_mock_vulkan_state->wait_for_fences_callback = wait_for_fences_callback_;
1176 g_mock_vulkan_state->compression_exhausted_create_image_failures =
1177 compression_exhausted_create_image_failures_;
1178 settings.embedder_data = embedder_data_;
1179 std::shared_ptr<ContextVK> result = ContextVK::Create(std::move(settings));
1180 return result;
1181}
1182
1183std::shared_ptr<std::vector<std::string>> GetMockVulkanFunctions(
1184 VkDevice device) {
1185 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
1186 return mock_device->GetCalledFunctions();
1187}
1188
1190 currentImageSize = size;
1191}
1192
1193std::vector<VkImageMemoryBarrier>& GetImageMemoryBarriers(
1194 VkCommandBuffer buffer) {
1195 MockCommandBuffer* mock_command_buffer =
1196 reinterpret_cast<MockCommandBuffer*>(buffer);
1197 return mock_command_buffer->image_memory_barriers_;
1198}
1199
1200const std::vector<VkViewport>& GetRecordedViewports(VkCommandBuffer buffer) {
1201 MockCommandBuffer* mock_command_buffer =
1202 reinterpret_cast<MockCommandBuffer*>(buffer);
1203 return mock_command_buffer->recorded_viewports_;
1204}
1205
1206} // namespace testing
1207} // namespace impeller
static std::shared_ptr< ConcurrentMessageLoop > Create(size_t worker_count=std::thread::hardware_concurrency())
static std::shared_ptr< ContextVK > Create(Settings settings)
MockCommandBuffer(std::weak_ptr< const Context > context)
Definition mocks.h:143
std::shared_ptr< ContextVK > Build()
Create a Vulkan context with Vulkan functions mocked. The caller is given a chance to tinker on the s...
FlutterVulkanImage * image
VkSwapchainKHR swapchain
Definition main.cc:80
VkDevice device
Definition main.cc:69
VkInstance instance
Definition main.cc:64
VkQueue queue
Definition main.cc:71
#define FML_CHECK(condition)
Definition logging.h:104
size_t length
size_t current_image
std::vector< std::string > instance_layers
std::vector< std::string > device_extensions
std::function< void(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties)> format_properties_callback
std::function< void(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties)> physical_device_properties_callback
std::function< std::remove_pointer_t< PFN_vkWaitForFences > > wait_for_fences_callback
int compression_exhausted_create_image_failures
std::shared_ptr< std::vector< std::string > > called_functions_
std::array< MockImage, 3 > images
std::vector< std::string > instance_extensions
std::function< std::remove_pointer_t< PFN_vkAcquireNextImageKHR > > acquire_next_image_callback
std::vector< VkImageMemoryBarrier > image_memory_barriers_
std::vector< VkViewport > recorded_viewports_
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switch_defs.h:36
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set profile Make the profiler discard new samples once the profiler sample buffer is full When this flag is not the profiler sample buffer is used as a ring buffer
Definition switch_defs.h:98
std::shared_ptr< std::vector< std::string > > GetMockVulkanFunctions(VkDevice device)
const std::vector< VkViewport > & GetRecordedViewports(VkCommandBuffer buffer)
Returns the viewports passed to vkCmdSetViewport calls on the given command buffer,...
std::vector< VkImageMemoryBarrier > & GetImageMemoryBarriers(VkCommandBuffer buffer)
void SetSwapchainImageSize(ISize size)
Override the image size returned by all swapchain images.
constexpr Color operator*(T value, const Color &c)
Definition color.h:914
ISize64 ISize
Definition size.h:162
Definition ref_ptr.h:261
std::shared_ptr< PipelineGLES > pipeline
int32_t height
PFN_vkGetInstanceProcAddr proc_address_callback
Definition context_vk.h:80
std::optional< EmbedderData > embedder_data
Definition context_vk.h:90
#define IPLR_GUARDED_BY(x)