OLD | NEW |
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/vulkan/vulkan_implementation.h" | 5 #include "gpu/vulkan/vulkan_implementation.h" |
6 | 6 |
| 7 #include <unordered_set> |
| 8 #include <vector> |
7 #include <vulkan/vulkan.h> | 9 #include <vulkan/vulkan.h> |
8 | 10 |
9 #include "base/logging.h" | 11 #include "base/logging.h" |
10 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "gpu/vulkan/vulkan_platform.h" |
11 | 14 |
12 #if defined(VK_USE_PLATFORM_XLIB_KHR) | 15 #if defined(VK_USE_PLATFORM_XLIB_KHR) |
13 #include "ui/gfx/x/x11_types.h" | 16 #include "ui/gfx/x/x11_types.h" |
14 #endif // defined(VK_USE_PLATFORM_XLIB_KHR) | 17 #endif // defined(VK_USE_PLATFORM_XLIB_KHR) |
15 | 18 |
| 19 VKAPI_ATTR VkBool32 VKAPI_CALL VulkanErrorCallback( |
| 20 VkDebugReportFlagsEXT flags, |
| 21 VkDebugReportObjectTypeEXT objectType, |
| 22 uint64_t object, |
| 23 size_t location, |
| 24 int32_t messageCode, |
| 25 const char* pLayerPrefix, |
| 26 const char* pMessage, |
| 27 void* pUserData) { |
| 28 LOG(ERROR) << pMessage; |
| 29 return VK_TRUE; |
| 30 } |
| 31 |
| 32 VKAPI_ATTR VkBool32 VKAPI_CALL VulkanWarningCallback( |
| 33 VkDebugReportFlagsEXT flags, |
| 34 VkDebugReportObjectTypeEXT objectType, |
| 35 uint64_t object, |
| 36 size_t location, |
| 37 int32_t messageCode, |
| 38 const char* pLayerPrefix, |
| 39 const char* pMessage, |
| 40 void* pUserData) { |
| 41 LOG(WARNING) << pMessage; |
| 42 return VK_TRUE; |
| 43 } |
| 44 |
16 namespace gpu { | 45 namespace gpu { |
17 | 46 |
18 struct VulkanInstance { | 47 struct VulkanInstance { |
19 VulkanInstance() {} | 48 VulkanInstance() {} |
20 | 49 |
21 void Initialize() { valid = InitializeVulkanInstance(); } | 50 void Initialize() { valid = InitializeVulkanInstance(); } |
22 | 51 |
23 bool InitializeVulkanInstance() { | 52 bool InitializeVulkanInstance() { |
24 VkResult status = VK_SUCCESS; | 53 VkResult result = VK_SUCCESS; |
25 | 54 |
26 VkApplicationInfo app_info = {}; | 55 VkApplicationInfo app_info = {}; |
27 app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; | 56 app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; |
28 app_info.pApplicationName = "Chromium"; | 57 app_info.pApplicationName = "Chromium"; |
29 app_info.apiVersion = VK_MAKE_VERSION(1, 0, 2); | 58 app_info.apiVersion = VK_MAKE_VERSION(1, 0, 2); |
30 | 59 |
31 const char* instance_extensions[] = { | 60 std::vector<const char*> enabled_ext_names; |
32 VK_KHR_SURFACE_EXTENSION_NAME, | 61 enabled_ext_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME); |
33 | 62 |
34 #if defined(VK_USE_PLATFORM_XLIB_KHR) | 63 #if defined(VK_USE_PLATFORM_XLIB_KHR) |
35 VK_KHR_XLIB_SURFACE_EXTENSION_NAME, | 64 enabled_ext_names.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); |
36 #endif // defined(VK_USE_PLATFORM_XLIB_KHR) | 65 #endif |
37 }; | 66 |
| 67 uint32_t num_instance_exts = 0; |
| 68 result = vkEnumerateInstanceExtensionProperties(nullptr, &num_instance_exts, |
| 69 nullptr); |
| 70 if (VK_SUCCESS != result) { |
| 71 DLOG(ERROR) << "vkEnumerateInstanceExtensionProperties(NULL) failed: " |
| 72 << result; |
| 73 return false; |
| 74 } |
| 75 |
| 76 std::vector<VkExtensionProperties> instance_exts(num_instance_exts); |
| 77 result = vkEnumerateInstanceExtensionProperties(nullptr, &num_instance_exts, |
| 78 instance_exts.data()); |
| 79 if (VK_SUCCESS != result) { |
| 80 DLOG(ERROR) << "vkEnumerateInstanceExtensionProperties() failed: " |
| 81 << result; |
| 82 return false; |
| 83 } |
| 84 |
| 85 bool debug_report_enabled = false; |
| 86 for (const VkExtensionProperties& ext_property : instance_exts) { |
| 87 if (strcmp(ext_property.extensionName, |
| 88 VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) { |
| 89 debug_report_enabled = true; |
| 90 enabled_ext_names.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); |
| 91 } |
| 92 } |
| 93 |
| 94 std::vector<const char*> enabled_layer_names; |
| 95 #if DCHECK_IS_ON() |
| 96 uint32_t num_instance_layers = 0; |
| 97 result = vkEnumerateInstanceLayerProperties(&num_instance_layers, nullptr); |
| 98 if (VK_SUCCESS != result) { |
| 99 DLOG(ERROR) << "vkEnumerateInstanceLayerProperties(NULL) failed: " |
| 100 << result; |
| 101 return false; |
| 102 } |
| 103 |
| 104 std::vector<VkLayerProperties> instance_layers(num_instance_layers); |
| 105 result = vkEnumerateInstanceLayerProperties(&num_instance_layers, |
| 106 instance_layers.data()); |
| 107 if (VK_SUCCESS != result) { |
| 108 DLOG(ERROR) << "vkEnumerateInstanceLayerProperties() failed: " << result; |
| 109 return false; |
| 110 } |
| 111 |
| 112 std::unordered_set<std::string> desired_layers({ |
| 113 "VK_LAYER_LUNARG_standard_validation", |
| 114 }); |
| 115 |
| 116 for (const VkLayerProperties& layer_property : instance_layers) { |
| 117 if (desired_layers.find(layer_property.layerName) != desired_layers.end()) |
| 118 enabled_layer_names.push_back(layer_property.layerName); |
| 119 } |
| 120 #endif |
38 | 121 |
39 VkInstanceCreateInfo instance_create_info = {}; | 122 VkInstanceCreateInfo instance_create_info = {}; |
40 instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; | 123 instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; |
41 instance_create_info.pApplicationInfo = &app_info; | 124 instance_create_info.pApplicationInfo = &app_info; |
42 instance_create_info.ppEnabledExtensionNames = instance_extensions; | 125 instance_create_info.enabledLayerCount = enabled_layer_names.size(); |
43 instance_create_info.enabledExtensionCount = arraysize(instance_extensions); | 126 instance_create_info.ppEnabledLayerNames = enabled_layer_names.data(); |
| 127 instance_create_info.enabledExtensionCount = enabled_ext_names.size(); |
| 128 instance_create_info.ppEnabledExtensionNames = enabled_ext_names.data(); |
44 | 129 |
45 status = vkCreateInstance(&instance_create_info, nullptr, &vk_instance); | 130 result = vkCreateInstance(&instance_create_info, nullptr, &vk_instance); |
46 DCHECK_EQ(VK_SUCCESS, status); | 131 if (VK_SUCCESS != result) { |
47 if (VK_SUCCESS != status) | 132 DLOG(ERROR) << "vkCreateInstance() failed: " << result; |
48 return false; | 133 return false; |
| 134 } |
| 135 |
| 136 // Register our error logging function. |
| 137 if (debug_report_enabled) { |
| 138 PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = |
| 139 reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT> |
| 140 (vkGetInstanceProcAddr(vk_instance, |
| 141 "vkCreateDebugReportCallbackEXT")); |
| 142 DCHECK(vkCreateDebugReportCallbackEXT); |
| 143 |
| 144 VkDebugReportCallbackCreateInfoEXT cb_create_info = {}; |
| 145 cb_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; |
| 146 |
| 147 cb_create_info.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT; |
| 148 cb_create_info.pfnCallback = &VulkanErrorCallback; |
| 149 result = vkCreateDebugReportCallbackEXT(vk_instance, &cb_create_info, |
| 150 nullptr, &error_callback); |
| 151 if (VK_SUCCESS != result) { |
| 152 DLOG(ERROR) << "vkCreateDebugReportCallbackEXT(ERROR) failed: " |
| 153 << result; |
| 154 return false; |
| 155 } |
| 156 |
| 157 cb_create_info.flags = VK_DEBUG_REPORT_WARNING_BIT_EXT | |
| 158 VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; |
| 159 cb_create_info.pfnCallback = &VulkanWarningCallback; |
| 160 result = vkCreateDebugReportCallbackEXT(vk_instance, &cb_create_info, |
| 161 nullptr, &warning_callback); |
| 162 if (VK_SUCCESS != result) { |
| 163 DLOG(ERROR) << "vkCreateDebugReportCallbackEXT(WARN) failed: " |
| 164 << result; |
| 165 return false; |
| 166 } |
| 167 } |
49 | 168 |
50 return true; | 169 return true; |
51 } | 170 } |
52 | 171 |
53 bool valid = false; | 172 bool valid = false; |
54 VkInstance vk_instance = VK_NULL_HANDLE; | 173 VkInstance vk_instance = VK_NULL_HANDLE; |
| 174 #if DCHECK_IS_ON() |
| 175 VkDebugReportCallbackEXT error_callback = VK_NULL_HANDLE; |
| 176 VkDebugReportCallbackEXT warning_callback = VK_NULL_HANDLE; |
| 177 #endif |
55 }; | 178 }; |
56 | 179 |
57 static VulkanInstance* vulkan_instance = nullptr; | 180 static VulkanInstance* vulkan_instance = nullptr; |
58 | 181 |
59 bool InitializeVulkan() { | 182 bool InitializeVulkan() { |
60 DCHECK(!vulkan_instance); | 183 DCHECK(!vulkan_instance); |
61 vulkan_instance = new VulkanInstance; | 184 vulkan_instance = new VulkanInstance; |
62 vulkan_instance->Initialize(); | 185 vulkan_instance->Initialize(); |
63 return vulkan_instance->valid; | 186 return vulkan_instance->valid; |
64 } | 187 } |
65 | 188 |
66 VkInstance GetVulkanInstance() { | 189 VkInstance GetVulkanInstance() { |
67 DCHECK(vulkan_instance); | 190 DCHECK(vulkan_instance); |
68 DCHECK(vulkan_instance->valid); | 191 DCHECK(vulkan_instance->valid); |
69 return vulkan_instance->vk_instance; | 192 return vulkan_instance->vk_instance; |
70 } | 193 } |
71 | 194 |
72 } // namespace gpu | 195 } // namespace gpu |
OLD | NEW |