blob: bf9a3edb0a60ce8100a593c7cb0347d22238965a [file] [log] [blame]
dyen8a145fb72016-03-31 00:37:511// Copyright (c) 2016 The Chromium 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
5#include "gpu/vulkan/vulkan_device_queue.h"
6
dyen5bd6d4f2016-03-31 15:25:457#include <unordered_set>
dyen8a145fb72016-03-31 00:37:518#include <vector>
9
10#include "gpu/vulkan/vulkan_command_pool.h"
Chris Blumeb9adeda82018-06-08 00:23:5311#include "gpu/vulkan/vulkan_function_pointers.h"
dyen8a145fb72016-03-31 00:37:5112
dyen8a145fb72016-03-31 00:37:5113namespace gpu {
14
Michael Spang7509e6d2018-05-16 17:08:2815VulkanDeviceQueue::VulkanDeviceQueue(VkInstance vk_instance)
16 : vk_instance_(vk_instance) {}
dyen8a145fb72016-03-31 00:37:5117
18VulkanDeviceQueue::~VulkanDeviceQueue() {
19 DCHECK_EQ(static_cast<VkPhysicalDevice>(VK_NULL_HANDLE), vk_physical_device_);
20 DCHECK_EQ(static_cast<VkDevice>(VK_NULL_HANDLE), vk_device_);
21 DCHECK_EQ(static_cast<VkQueue>(VK_NULL_HANDLE), vk_queue_);
22}
23
Michael Spang7509e6d2018-05-16 17:08:2824bool VulkanDeviceQueue::Initialize(
25 uint32_t options,
Michael Spang4e46bc22018-06-21 23:07:5126 const std::vector<const char*>& required_extensions,
Michael Spang7509e6d2018-05-16 17:08:2827 const GetPresentationSupportCallback& get_presentation_support) {
suyambu.rmf2fbf532017-12-04 08:38:1528 if (VK_NULL_HANDLE == vk_instance_)
dyen8a145fb72016-03-31 00:37:5129 return false;
30
dyen5bd6d4f2016-03-31 15:25:4531 VkResult result = VK_SUCCESS;
dyen8a145fb72016-03-31 00:37:5132
33 uint32_t device_count = 0;
Chris Blumef0fb42f2018-06-28 19:35:2534 result = vkEnumeratePhysicalDevices(vk_instance_, &device_count, nullptr);
dyen5bd6d4f2016-03-31 15:25:4535 if (VK_SUCCESS != result || device_count == 0)
dyen8a145fb72016-03-31 00:37:5136 return false;
37
38 std::vector<VkPhysicalDevice> devices(device_count);
Chris Blumef0fb42f2018-06-28 19:35:2539 result =
40 vkEnumeratePhysicalDevices(vk_instance_, &device_count, devices.data());
dyen5bd6d4f2016-03-31 15:25:4541 if (VK_SUCCESS != result) {
42 DLOG(ERROR) << "vkEnumeratePhysicalDevices() failed: " << result;
dyen8a145fb72016-03-31 00:37:5143 return false;
44 }
45
dyen8a145fb72016-03-31 00:37:5146 VkQueueFlags queue_flags = 0;
47 if (options & DeviceQueueOption::GRAPHICS_QUEUE_FLAG)
48 queue_flags |= VK_QUEUE_GRAPHICS_BIT;
49
50 int device_index = -1;
51 int queue_index = -1;
52 for (size_t i = 0; i < devices.size(); ++i) {
53 const VkPhysicalDevice& device = devices[i];
54 uint32_t queue_count = 0;
Chris Blumef0fb42f2018-06-28 19:35:2555 vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count, nullptr);
dyen8a145fb72016-03-31 00:37:5156 if (queue_count) {
57 std::vector<VkQueueFamilyProperties> queue_properties(queue_count);
Chris Blumef0fb42f2018-06-28 19:35:2558 vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count,
59 queue_properties.data());
dyen8a145fb72016-03-31 00:37:5160 for (size_t n = 0; n < queue_properties.size(); ++n) {
61 if ((queue_properties[n].queueFlags & queue_flags) != queue_flags)
62 continue;
63
dyen8a145fb72016-03-31 00:37:5164 if (options & DeviceQueueOption::PRESENTATION_SUPPORT_QUEUE_FLAG &&
Michael Spang7509e6d2018-05-16 17:08:2865 !get_presentation_support.Run(device, queue_properties, n)) {
dyen8a145fb72016-03-31 00:37:5166 continue;
67 }
dyen8a145fb72016-03-31 00:37:5168
69 queue_index = static_cast<int>(n);
70 break;
71 }
72
73 if (-1 != queue_index) {
74 device_index = static_cast<int>(i);
75 break;
76 }
77 }
78 }
79
80 if (queue_index == -1)
81 return false;
82
83 vk_physical_device_ = devices[device_index];
84 vk_queue_index_ = queue_index;
85
86 float queue_priority = 0.0f;
87 VkDeviceQueueCreateInfo queue_create_info = {};
88 queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
89 queue_create_info.queueFamilyIndex = queue_index;
90 queue_create_info.queueCount = 1;
91 queue_create_info.pQueuePriorities = &queue_priority;
92
dyen5bd6d4f2016-03-31 15:25:4593 std::vector<const char*> enabled_layer_names;
94#if DCHECK_IS_ON()
95 uint32_t num_device_layers = 0;
Chris Blumef0fb42f2018-06-28 19:35:2596 result = vkEnumerateDeviceLayerProperties(vk_physical_device_,
97 &num_device_layers, nullptr);
dyen5bd6d4f2016-03-31 15:25:4598 if (VK_SUCCESS != result) {
tzikddef02182018-08-14 07:08:3399 DLOG(ERROR) << "vkEnumerateDeviceLayerProperties(NULL) failed: " << result;
dyen5bd6d4f2016-03-31 15:25:45100 return false;
101 }
102
103 std::vector<VkLayerProperties> device_layers(num_device_layers);
Chris Blumef0fb42f2018-06-28 19:35:25104 result = vkEnumerateDeviceLayerProperties(
Chris Blumeb9adeda82018-06-08 00:23:53105 vk_physical_device_, &num_device_layers, device_layers.data());
dyen5bd6d4f2016-03-31 15:25:45106 if (VK_SUCCESS != result) {
107 DLOG(ERROR) << "vkEnumerateDeviceLayerProperties() failed: " << result;
108 return false;
109 }
110
111 std::unordered_set<std::string> desired_layers({
112 "VK_LAYER_LUNARG_standard_validation",
113 });
114
115 for (const VkLayerProperties& layer_property : device_layers) {
116 if (desired_layers.find(layer_property.layerName) != desired_layers.end())
117 enabled_layer_names.push_back(layer_property.layerName);
118 }
119#endif
120
Michael Spang4e46bc22018-06-21 23:07:51121 std::vector<const char*> enabled_extensions;
122 enabled_extensions.insert(std::end(enabled_extensions),
123 std::begin(required_extensions),
124 std::end(required_extensions));
125
dyen8a145fb72016-03-31 00:37:51126 VkDeviceCreateInfo device_create_info = {};
127 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
128 device_create_info.queueCreateInfoCount = 1;
129 device_create_info.pQueueCreateInfos = &queue_create_info;
dyen5bd6d4f2016-03-31 15:25:45130 device_create_info.enabledLayerCount = enabled_layer_names.size();
131 device_create_info.ppEnabledLayerNames = enabled_layer_names.data();
Michael Spang4e46bc22018-06-21 23:07:51132 device_create_info.enabledExtensionCount = enabled_extensions.size();
133 device_create_info.ppEnabledExtensionNames = enabled_extensions.data();
dyen8a145fb72016-03-31 00:37:51134
Chris Blumef0fb42f2018-06-28 19:35:25135 result = vkCreateDevice(vk_physical_device_, &device_create_info, nullptr,
136 &vk_device_);
dyen5bd6d4f2016-03-31 15:25:45137 if (VK_SUCCESS != result)
dyen8a145fb72016-03-31 00:37:51138 return false;
139
Michael Spang4e46bc22018-06-21 23:07:51140 enabled_extensions_ = gfx::ExtensionSet(std::begin(enabled_extensions),
141 std::end(enabled_extensions));
142
Chris Blumef0fb42f2018-06-28 19:35:25143 gpu::GetVulkanFunctionPointers()->BindDeviceFunctionPointers(vk_device_);
Chris Blumeb9adeda82018-06-08 00:23:53144
Michael Spang4e46bc22018-06-21 23:07:51145 if (gfx::HasExtension(enabled_extensions_, VK_KHR_SWAPCHAIN_EXTENSION_NAME))
Chris Blumef0fb42f2018-06-28 19:35:25146 gpu::GetVulkanFunctionPointers()->BindSwapchainFunctionPointers(vk_device_);
Michael Spang4e46bc22018-06-21 23:07:51147
Chris Blumef0fb42f2018-06-28 19:35:25148 vkGetDeviceQueue(vk_device_, queue_index, 0, &vk_queue_);
dyen8a145fb72016-03-31 00:37:51149
150 return true;
151}
152
153void VulkanDeviceQueue::Destroy() {
154 if (VK_NULL_HANDLE != vk_device_) {
Chris Blumef0fb42f2018-06-28 19:35:25155 vkDestroyDevice(vk_device_, nullptr);
dyen8a145fb72016-03-31 00:37:51156 vk_device_ = VK_NULL_HANDLE;
157 }
158
159 vk_queue_ = VK_NULL_HANDLE;
160 vk_queue_index_ = 0;
161
162 vk_physical_device_ = VK_NULL_HANDLE;
163}
164
mostynb6682b1c42016-04-19 10:17:30165std::unique_ptr<VulkanCommandPool> VulkanDeviceQueue::CreateCommandPool() {
166 std::unique_ptr<VulkanCommandPool> command_pool(new VulkanCommandPool(this));
dyen8a145fb72016-03-31 00:37:51167 if (!command_pool->Initialize())
168 return nullptr;
169
170 return command_pool;
171}
172
173} // namespace gpu