Flutter Engine
 
Loading...
Searching...
No Matches
vulkan::VulkanDevice Class Reference

#include <vulkan_device.h>

Public Member Functions

 VulkanDevice (VulkanProcTable &vk, VulkanHandle< VkPhysicalDevice > physical_device, bool enable_validation_layers)
 Create a new VkDevice with a resolved VkQueue suitable for rendering with Skia.
 
 VulkanDevice (VulkanProcTable &vk, VulkanHandle< VkPhysicalDevice > physical_device, VulkanHandle< VkDevice > device, uint32_t queue_family_index, VulkanHandle< VkQueue > queue)
 Wrap an existing VkDevice and VkQueue.
 
 ~VulkanDevice ()
 
bool IsValid () const
 
const VulkanHandle< VkDevice > & GetHandle () const
 
const VulkanHandle< VkPhysicalDevice > & GetPhysicalDeviceHandle () const
 
const VulkanHandle< VkQueue > & GetQueueHandle () const
 
const VulkanHandle< VkCommandPool > & GetCommandPool () const
 
uint32_t GetGraphicsQueueIndex () const
 
void ReleaseDeviceOwnership ()
 
bool GetSurfaceCapabilities (const VulkanSurface &surface, VkSurfaceCapabilitiesKHR *capabilities) const
 
bool GetPhysicalDeviceFeatures (VkPhysicalDeviceFeatures *features) const
 
int ChooseSurfaceFormat (const VulkanSurface &surface, const std::vector< VkFormat > &desired_formats, VkSurfaceFormatKHR *format) const
 
bool ChoosePresentMode (const VulkanSurface &surface, VkPresentModeKHR *present_mode) const
 
bool QueueSubmit (std::vector< VkPipelineStageFlags > wait_dest_pipeline_stages, const std::vector< VkSemaphore > &wait_semaphores, const std::vector< VkSemaphore > &signal_semaphores, const std::vector< VkCommandBuffer > &command_buffers, const VulkanHandle< VkFence > &fence) const
 
bool WaitIdle () const
 

Detailed Description

Definition at line 18 of file vulkan_device.h.

Constructor & Destructor Documentation

◆ VulkanDevice() [1/2]

vulkan::VulkanDevice::VulkanDevice ( VulkanProcTable vk,
VulkanHandle< VkPhysicalDevice >  physical_device,
bool  enable_validation_layers 
)

Create a new VkDevice with a resolved VkQueue suitable for rendering with Skia.

Definition at line 31 of file vulkan_device.cc.

34 : vk_(p_vk),
35 physical_device_(std::move(physical_device)),
36 graphics_queue_index_(std::numeric_limits<uint32_t>::max()),
37 valid_(false) {
38 if (!physical_device_ || !vk_.AreInstanceProcsSetup()) {
39 return;
40 }
41
42 graphics_queue_index_ = FindGraphicsQueueIndex(GetQueueFamilyProperties());
43
44 if (graphics_queue_index_ == kVulkanInvalidGraphicsQueueIndex) {
45 FML_DLOG(INFO) << "Could not find the graphics queue index.";
46 return;
47 }
48
49 const float priorities[1] = {1.0f};
50
51 const VkDeviceQueueCreateInfo queue_create = {
52 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
53 .pNext = nullptr,
54 .flags = 0,
55 .queueFamilyIndex = graphics_queue_index_,
56 .queueCount = 1,
57 .pQueuePriorities = priorities,
58 };
59
60 const char* extensions[] = {
61#if FML_OS_ANDROID
62 VK_KHR_SWAPCHAIN_EXTENSION_NAME,
63#endif
64#if OS_FUCHSIA
65 VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
66 VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
67 VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
68 VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME,
69 VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
70 VK_FUCHSIA_BUFFER_COLLECTION_EXTENSION_NAME,
71#endif
72 };
73
74 auto enabled_layers =
75 DeviceLayersToEnable(vk_, physical_device_, enable_validation_layers);
76
77 std::vector<const char*> layers;
78
79 layers.reserve(enabled_layers.size());
80 for (size_t i = 0; i < enabled_layers.size(); i++) {
81 layers.push_back(enabled_layers[i].c_str());
82 }
83
84 const VkDeviceCreateInfo create_info = {
85 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
86 .pNext = nullptr,
87 .flags = 0,
88 .queueCreateInfoCount = 1,
89 .pQueueCreateInfos = &queue_create,
90 .enabledLayerCount = static_cast<uint32_t>(layers.size()),
91 .ppEnabledLayerNames = layers.data(),
92 .enabledExtensionCount = sizeof(extensions) / sizeof(const char*),
93 .ppEnabledExtensionNames = extensions,
94 .pEnabledFeatures = nullptr,
95 };
96
97 VkDevice device = VK_NULL_HANDLE;
98
99 if (VK_CALL_LOG_ERROR(vk_.CreateDevice(physical_device_, &create_info,
100 nullptr, &device)) != VK_SUCCESS) {
101 FML_DLOG(INFO) << "Could not create device.";
102 return;
103 }
104
105 device_ = VulkanHandle<VkDevice>{
106 device, [this](VkDevice device) { vk_.DestroyDevice(device, nullptr); }};
107
108 if (!vk_.SetupDeviceProcAddresses(device_)) {
109 FML_DLOG(INFO) << "Could not set up device proc addresses.";
110 return;
111 }
112
113 VkQueue queue = VK_NULL_HANDLE;
114
115 vk_.GetDeviceQueue(device_, graphics_queue_index_, 0, &queue);
116
117 if (queue == VK_NULL_HANDLE) {
118 FML_DLOG(INFO) << "Could not get the device queue handle.";
119 return;
120 }
121
122 queue_ = VulkanHandle<VkQueue>(queue);
123
124 if (!InitializeCommandPool()) {
125 return;
126 }
127
128 valid_ = true;
129}
bool SetupDeviceProcAddresses(const VulkanHandle< VkDevice > &device)
VkPhysicalDevice physical_device
Definition main.cc:67
VkDevice device
Definition main.cc:69
bool enable_validation_layers
Definition main.cc:36
VkQueue queue
Definition main.cc:71
const FlutterLayer ** layers
#define FML_DLOG(severity)
Definition logging.h:121
static uint32_t FindGraphicsQueueIndex(const std::vector< VkQueueFamilyProperties > &properties)
constexpr auto kVulkanInvalidGraphicsQueueIndex
std::vector< std::string > DeviceLayersToEnable(const VulkanProcTable &vk, const VulkanHandle< VkPhysicalDevice > &physical_device, bool enable_validation_layers)
FlutterSize size
The size of the layer (in physical pixels).
Definition embedder.h:2147
#define VK_CALL_LOG_ERROR(expression)

References vulkan::VulkanProcTable::AreInstanceProcsSetup(), device, vulkan::DeviceLayersToEnable(), enable_validation_layers, vulkan::FindGraphicsQueueIndex(), FML_DLOG, i, vulkan::kVulkanInvalidGraphicsQueueIndex, layers, queue, vulkan::VulkanProcTable::SetupDeviceProcAddresses(), FlutterLayer::size, and VK_CALL_LOG_ERROR.

◆ VulkanDevice() [2/2]

vulkan::VulkanDevice::VulkanDevice ( VulkanProcTable vk,
VulkanHandle< VkPhysicalDevice >  physical_device,
VulkanHandle< VkDevice >  device,
uint32_t  queue_family_index,
VulkanHandle< VkQueue >  queue 
)

Wrap an existing VkDevice and VkQueue.

Definition at line 131 of file vulkan_device.cc.

136 : vk_(p_vk),
137 physical_device_(std::move(physical_device)),
138 device_(std::move(device)),
139 queue_(std::move(queue)),
140 graphics_queue_index_(queue_family_index),
141 valid_(false) {
142 if (!physical_device_ || !vk_.AreInstanceProcsSetup()) {
143 return;
144 }
145
146 if (!InitializeCommandPool()) {
147 return;
148 }
149
150 valid_ = true;
151}
uint32_t queue_family_index
Definition main.cc:70

References vulkan::VulkanProcTable::AreInstanceProcsSetup().

◆ ~VulkanDevice()

vulkan::VulkanDevice::~VulkanDevice ( )

Definition at line 177 of file vulkan_device.cc.

177 {
178 [[maybe_unused]] auto result = WaitIdle();
179}

References WaitIdle().

Member Function Documentation

◆ ChoosePresentMode()

bool vulkan::VulkanDevice::ChoosePresentMode ( const VulkanSurface surface,
VkPresentModeKHR *  present_mode 
) const

Definition at line 322 of file vulkan_device.cc.

323 {
324 if (!surface.IsValid() || present_mode == nullptr) {
325 return false;
326 }
327
328 // https://github.com/LunarG/VulkanSamples/issues/98 indicates that
329 // VK_PRESENT_MODE_FIFO_KHR is preferable on mobile platforms. The problems
330 // mentioned in the ticket w.r.t the application being faster that the refresh
331 // rate of the screen should not be faced by any Flutter platforms as they are
332 // powered by Vsync pulses instead of depending the submit to block.
333 // However, for platforms that don't have VSync providers set up, it is better
334 // to fall back to FIFO. For platforms that do have VSync providers, there
335 // should be little difference. In case there is a need for a mode other than
336 // FIFO, availability checks must be performed here before returning the
337 // result. FIFO is always present.
338 *present_mode = VK_PRESENT_MODE_FIFO_KHR;
339 return true;
340}
VkSurfaceKHR surface
Definition main.cc:65

References surface.

◆ ChooseSurfaceFormat()

int vulkan::VulkanDevice::ChooseSurfaceFormat ( const VulkanSurface surface,
const std::vector< VkFormat > &  desired_formats,
VkSurfaceFormatKHR *  format 
) const

Definition at line 276 of file vulkan_device.cc.

279 {
280#if FML_OS_ANDROID
281 if (!surface.IsValid() || format == nullptr) {
282 return -1;
283 }
284
285 uint32_t format_count = 0;
286 if (VK_CALL_LOG_ERROR(vk_.GetPhysicalDeviceSurfaceFormatsKHR(
287 physical_device_, surface.Handle(), &format_count, nullptr)) !=
288 VK_SUCCESS) {
289 return -1;
290 }
291
292 if (format_count == 0) {
293 return -1;
294 }
295
296 std::vector<VkSurfaceFormatKHR> formats;
297 formats.resize(format_count);
298
299 if (VK_CALL_LOG_ERROR(vk_.GetPhysicalDeviceSurfaceFormatsKHR(
300 physical_device_, surface.Handle(), &format_count, formats.data())) !=
301 VK_SUCCESS) {
302 return -1;
303 }
304
305 std::map<VkFormat, VkSurfaceFormatKHR> supported_formats;
306 for (uint32_t i = 0; i < format_count; i++) {
307 supported_formats[formats[i].format] = formats[i];
308 }
309
310 // Try to find the first supported format in the list of desired formats.
311 for (size_t i = 0; i < desired_formats.size(); ++i) {
312 auto found = supported_formats.find(desired_formats[i]);
313 if (found != supported_formats.end()) {
314 *format = found->second;
315 return static_cast<int>(i);
316 }
317 }
318#endif
319 return -1;
320}
uint32_t uint32_t * format

References format, i, surface, and VK_CALL_LOG_ERROR.

◆ GetCommandPool()

const VulkanHandle< VkCommandPool > & vulkan::VulkanDevice::GetCommandPool ( ) const

Definition at line 206 of file vulkan_device.cc.

206 {
207 return command_pool_;
208}

◆ GetGraphicsQueueIndex()

uint32_t vulkan::VulkanDevice::GetGraphicsQueueIndex ( ) const

Definition at line 210 of file vulkan_device.cc.

210 {
211 return graphics_queue_index_;
212}

◆ GetHandle()

const VulkanHandle< VkDevice > & vulkan::VulkanDevice::GetHandle ( ) const

Definition at line 189 of file vulkan_device.cc.

189 {
190 return device_;
191}

◆ GetPhysicalDeviceFeatures()

bool vulkan::VulkanDevice::GetPhysicalDeviceFeatures ( VkPhysicalDeviceFeatures *  features) const

Definition at line 252 of file vulkan_device.cc.

253 {
254 if (features == nullptr || !physical_device_) {
255 return false;
256 }
257 vk_.GetPhysicalDeviceFeatures(physical_device_, features);
258 return true;
259}

◆ GetPhysicalDeviceHandle()

const VulkanHandle< VkPhysicalDevice > & vulkan::VulkanDevice::GetPhysicalDeviceHandle ( ) const

Definition at line 197 of file vulkan_device.cc.

198 {
199 return physical_device_;
200}

◆ GetQueueHandle()

const VulkanHandle< VkQueue > & vulkan::VulkanDevice::GetQueueHandle ( ) const

Definition at line 202 of file vulkan_device.cc.

202 {
203 return queue_;
204}

◆ GetSurfaceCapabilities()

bool vulkan::VulkanDevice::GetSurfaceCapabilities ( const VulkanSurface surface,
VkSurfaceCapabilitiesKHR *  capabilities 
) const

Definition at line 214 of file vulkan_device.cc.

216 {
217#if FML_OS_ANDROID
218 if (!surface.IsValid() || capabilities == nullptr) {
219 return false;
220 }
221
222 bool success =
223 VK_CALL_LOG_ERROR(vk_.GetPhysicalDeviceSurfaceCapabilitiesKHR(
224 physical_device_, surface.Handle(), capabilities)) == VK_SUCCESS;
225
226 if (!success) {
227 return false;
228 }
229
230 // Check if the physical device surface capabilities are valid. If so, there
231 // is nothing more to do.
232 if (capabilities->currentExtent.width != 0xFFFFFFFF &&
233 capabilities->currentExtent.height != 0xFFFFFFFF) {
234 return true;
235 }
236
237 // Ask the native surface for its size as a fallback.
238 SkISize size = surface.GetSize();
239
240 if (size.width() == 0 || size.height() == 0) {
241 return false;
242 }
243
244 capabilities->currentExtent.width = size.width();
245 capabilities->currentExtent.height = size.height();
246 return true;
247#else
248 return false;
249#endif
250}
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

References surface, and VK_CALL_LOG_ERROR.

◆ IsValid()

bool vulkan::VulkanDevice::IsValid ( ) const

Definition at line 181 of file vulkan_device.cc.

181 {
182 return valid_;
183}

◆ QueueSubmit()

bool vulkan::VulkanDevice::QueueSubmit ( std::vector< VkPipelineStageFlags >  wait_dest_pipeline_stages,
const std::vector< VkSemaphore > &  wait_semaphores,
const std::vector< VkSemaphore > &  signal_semaphores,
const std::vector< VkCommandBuffer > &  command_buffers,
const VulkanHandle< VkFence > &  fence 
) const

Definition at line 342 of file vulkan_device.cc.

347 {
348 if (wait_semaphores.size() != wait_dest_pipeline_stages.size()) {
349 return false;
350 }
351
352 const VkSubmitInfo submit_info = {
353 .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
354 .pNext = nullptr,
355 .waitSemaphoreCount = static_cast<uint32_t>(wait_semaphores.size()),
356 .pWaitSemaphores = wait_semaphores.data(),
357 .pWaitDstStageMask = wait_dest_pipeline_stages.data(),
358 .commandBufferCount = static_cast<uint32_t>(command_buffers.size()),
359 .pCommandBuffers = command_buffers.data(),
360 .signalSemaphoreCount = static_cast<uint32_t>(signal_semaphores.size()),
361 .pSignalSemaphores = signal_semaphores.data(),
362 };
363
364 if (VK_CALL_LOG_ERROR(vk_.QueueSubmit(queue_, 1, &submit_info, fence)) !=
365 VK_SUCCESS) {
366 return false;
367 }
368
369 return true;
370}

References VK_CALL_LOG_ERROR.

◆ ReleaseDeviceOwnership()

void vulkan::VulkanDevice::ReleaseDeviceOwnership ( )

Definition at line 193 of file vulkan_device.cc.

193 {
194 device_.ReleaseOwnership();
195}

References vulkan::VulkanHandle< T >::ReleaseOwnership().

◆ WaitIdle()

bool vulkan::VulkanDevice::WaitIdle ( ) const

Definition at line 185 of file vulkan_device.cc.

185 {
186 return VK_CALL_LOG_ERROR(vk_.DeviceWaitIdle(device_)) == VK_SUCCESS;
187}

References VK_CALL_LOG_ERROR.

Referenced by ~VulkanDevice().


The documentation for this class was generated from the following files: