18 std::numeric_limits<uint32_t>::max();
21 const std::vector<VkQueueFamilyProperties>& properties) {
22 for (uint32_t
i = 0, count =
static_cast<uint32_t
>(properties.size());
24 if (properties[
i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
36 graphics_queue_index_(
std::numeric_limits<uint32_t>::max()),
45 FML_DLOG(INFO) <<
"Could not find the graphics queue index.";
49 const float priorities[1] = {1.0f};
51 const VkDeviceQueueCreateInfo queue_create = {
52 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
55 .queueFamilyIndex = graphics_queue_index_,
57 .pQueuePriorities = priorities,
60 const char* extensions[] = {
62 VK_KHR_SWAPCHAIN_EXTENSION_NAME,
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,
77 std::vector<const char*>
layers;
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());
84 const VkDeviceCreateInfo create_info = {
85 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
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,
97 VkDevice
device = VK_NULL_HANDLE;
100 nullptr, &
device)) != VK_SUCCESS) {
101 FML_DLOG(INFO) <<
"Could not create device.";
109 FML_DLOG(INFO) <<
"Could not set up device proc addresses.";
113 VkQueue
queue = VK_NULL_HANDLE;
115 vk_.GetDeviceQueue(device_, graphics_queue_index_, 0, &
queue);
117 if (
queue == VK_NULL_HANDLE) {
118 FML_DLOG(INFO) <<
"Could not get the device queue handle.";
124 if (!InitializeCommandPool()) {
146 if (!InitializeCommandPool()) {
153bool VulkanDevice::InitializeCommandPool() {
154 const VkCommandPoolCreateInfo command_pool_create_info = {
155 .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
157 .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
158 .queueFamilyIndex = 0,
161 VkCommandPool command_pool = VK_NULL_HANDLE;
163 device_, &command_pool_create_info,
nullptr, &command_pool)) !=
165 FML_DLOG(INFO) <<
"Could not create the command pool.";
169 command_pool_ = VulkanHandle<VkCommandPool>{
170 command_pool, [
this](VkCommandPool pool) {
171 vk_.DestroyCommandPool(device_, pool,
nullptr);
178 [[maybe_unused]]
auto result =
WaitIdle();
199 return physical_device_;
207 return command_pool_;
211 return graphics_queue_index_;
216 VkSurfaceCapabilitiesKHR* capabilities)
const {
218 if (!
surface.IsValid() || capabilities ==
nullptr) {
224 physical_device_,
surface.Handle(), capabilities)) == VK_SUCCESS;
232 if (capabilities->currentExtent.width != 0xFFFFFFFF &&
233 capabilities->currentExtent.height != 0xFFFFFFFF) {
238 SkISize size =
surface.GetSize();
240 if (size.width() == 0 || size.height() == 0) {
244 capabilities->currentExtent.width = size.width();
245 capabilities->currentExtent.height = size.height();
253 VkPhysicalDeviceFeatures* features)
const {
254 if (features ==
nullptr || !physical_device_) {
257 vk_.GetPhysicalDeviceFeatures(physical_device_, features);
261std::vector<VkQueueFamilyProperties> VulkanDevice::GetQueueFamilyProperties()
265 vk_.GetPhysicalDeviceQueueFamilyProperties(physical_device_, &count,
nullptr);
267 std::vector<VkQueueFamilyProperties> properties;
268 properties.resize(count, {});
270 vk_.GetPhysicalDeviceQueueFamilyProperties(physical_device_, &count,
278 const std::vector<VkFormat>& desired_formats,
279 VkSurfaceFormatKHR* format)
const {
285 uint32_t format_count = 0;
287 physical_device_,
surface.Handle(), &format_count,
nullptr)) !=
292 if (format_count == 0) {
296 std::vector<VkSurfaceFormatKHR> formats;
297 formats.resize(format_count);
300 physical_device_,
surface.Handle(), &format_count, formats.data())) !=
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];
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()) {
315 return static_cast<int>(
i);
323 VkPresentModeKHR* present_mode)
const {
324 if (!
surface.IsValid() || present_mode ==
nullptr) {
338 *present_mode = VK_PRESENT_MODE_FIFO_KHR;
343 std::vector<VkPipelineStageFlags> wait_dest_pipeline_stages,
344 const std::vector<VkSemaphore>& wait_semaphores,
345 const std::vector<VkSemaphore>& signal_semaphores,
346 const std::vector<VkCommandBuffer>& command_buffers,
348 if (wait_semaphores.size() != wait_dest_pipeline_stages.size()) {
352 const VkSubmitInfo submit_info = {
353 .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
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(),
VulkanDevice(VulkanProcTable &vk, VulkanHandle< VkPhysicalDevice > physical_device, bool enable_validation_layers)
Create a new VkDevice with a resolved VkQueue suitable for rendering with Skia.
const VulkanHandle< VkQueue > & GetQueueHandle() const
const VulkanHandle< VkPhysicalDevice > & GetPhysicalDeviceHandle() 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 GetSurfaceCapabilities(const VulkanSurface &surface, VkSurfaceCapabilitiesKHR *capabilities) const
const VulkanHandle< VkDevice > & GetHandle() const
void ReleaseDeviceOwnership()
int ChooseSurfaceFormat(const VulkanSurface &surface, const std::vector< VkFormat > &desired_formats, VkSurfaceFormatKHR *format) const
bool GetPhysicalDeviceFeatures(VkPhysicalDeviceFeatures *features) const
const VulkanHandle< VkCommandPool > & GetCommandPool() const
uint32_t GetGraphicsQueueIndex() const
bool AreInstanceProcsSetup() const
bool SetupDeviceProcAddresses(const VulkanHandle< VkDevice > &device)
VkPhysicalDevice physical_device
bool enable_validation_layers
uint32_t queue_family_index
const FlutterLayer ** layers
uint32_t uint32_t * format
#define FML_DLOG(severity)
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).
#define VK_CALL_LOG_ERROR(expression)