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