OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "vk/GrVkBackendContext.h" | 8 #include "vk/GrVkBackendContext.h" |
| 9 #include "vk/GrVkExtensions.h" |
9 #include "vk/GrVkInterface.h" | 10 #include "vk/GrVkInterface.h" |
10 #include "vk/GrVkUtil.h" | 11 #include "vk/GrVkUtil.h" |
11 | 12 |
12 //////////////////////////////////////////////////////////////////////////////// | 13 //////////////////////////////////////////////////////////////////////////////// |
13 // Helper code to set up Vulkan context objects | 14 // Helper code to set up Vulkan context objects |
14 | 15 |
15 #ifdef ENABLE_VK_LAYERS | 16 #ifdef ENABLE_VK_LAYERS |
16 const char* kEnabledLayerNames[] = { | 17 const char* kDebugLayerNames[] = { |
17 // elements of VK_LAYER_LUNARG_standard_validation | 18 // elements of VK_LAYER_LUNARG_standard_validation |
18 "VK_LAYER_LUNARG_threading", | 19 "VK_LAYER_LUNARG_threading", |
19 "VK_LAYER_LUNARG_param_checker", | 20 "VK_LAYER_LUNARG_param_checker", |
20 "VK_LAYER_LUNARG_device_limits", | 21 "VK_LAYER_LUNARG_device_limits", |
21 "VK_LAYER_LUNARG_object_tracker", | 22 "VK_LAYER_LUNARG_object_tracker", |
22 "VK_LAYER_LUNARG_image", | 23 "VK_LAYER_LUNARG_image", |
23 "VK_LAYER_LUNARG_mem_tracker", | 24 "VK_LAYER_LUNARG_mem_tracker", |
24 "VK_LAYER_LUNARG_draw_state", | 25 "VK_LAYER_LUNARG_draw_state", |
25 "VK_LAYER_LUNARG_swapchain", | 26 "VK_LAYER_LUNARG_swapchain", |
26 "VK_LAYER_GOOGLE_unique_objects", | 27 "VK_LAYER_GOOGLE_unique_objects", |
27 // not included in standard_validation | 28 // not included in standard_validation |
28 //"VK_LAYER_LUNARG_api_dump", | 29 //"VK_LAYER_LUNARG_api_dump", |
| 30 //"VK_LAYER_LUNARG_vktrace", |
| 31 //"VK_LAYER_LUNARG_screenshot", |
29 }; | 32 }; |
30 const char* kEnabledInstanceExtensionNames[] = { | 33 #endif |
31 VK_EXT_DEBUG_REPORT_EXTENSION_NAME | |
32 }; | |
33 | 34 |
34 bool verify_instance_layers() { | 35 // the minimum version of Vulkan supported |
35 // make sure we can actually use the extensions and layers above | 36 const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 3); |
36 uint32_t extensionCount; | |
37 VkResult res = vkEnumerateInstanceExtensionProperties(nullptr, &extensionCou
nt, nullptr); | |
38 if (VK_SUCCESS != res) { | |
39 return false; | |
40 } | |
41 VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount
]; | |
42 res = vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, exten
sions); | |
43 if (VK_SUCCESS != res) { | |
44 return false; | |
45 } | |
46 int instanceExtensionsFound = 0; | |
47 for (uint32_t j = 0; j < ARRAYSIZE(kEnabledInstanceExtensionNames); ++j) { | |
48 for (uint32_t i = 0; i < extensionCount; ++i) { | |
49 if (!strncmp(extensions[i].extensionName, kEnabledInstanceExtensionN
ames[j], | |
50 strlen(kEnabledInstanceExtensionNames[j]))) { | |
51 ++instanceExtensionsFound; | |
52 break; | |
53 } | |
54 } | |
55 } | |
56 delete[] extensions; | |
57 | |
58 uint32_t layerCount; | |
59 res = vkEnumerateInstanceLayerProperties(&layerCount, nullptr); | |
60 if (VK_SUCCESS != res) { | |
61 return false; | |
62 } | |
63 VkLayerProperties* layers = new VkLayerProperties[layerCount]; | |
64 res = vkEnumerateInstanceLayerProperties(&layerCount, layers); | |
65 if (VK_SUCCESS != res) { | |
66 return false; | |
67 } | |
68 int instanceLayersFound = 0; | |
69 for (uint32_t j = 0; j < ARRAYSIZE(kEnabledLayerNames); ++j) { | |
70 for (uint32_t i = 0; i < layerCount; ++i) { | |
71 if (!strncmp(layers[i].layerName, kEnabledLayerNames[j], | |
72 strlen(kEnabledLayerNames[j]))) { | |
73 ++instanceLayersFound; | |
74 break; | |
75 } | |
76 } | |
77 } | |
78 delete[] layers; | |
79 | |
80 return instanceExtensionsFound == ARRAYSIZE(kEnabledInstanceExtensionNames)
&& | |
81 instanceLayersFound == ARRAYSIZE(kEnabledLayerNames); | |
82 } | |
83 | |
84 bool verify_device_layers(VkPhysicalDevice physDev) { | |
85 uint32_t layerCount; | |
86 VkResult res = vkEnumerateDeviceLayerProperties(physDev, &layerCount, nullpt
r); | |
87 if (VK_SUCCESS != res) { | |
88 return false; | |
89 } | |
90 VkLayerProperties* layers = new VkLayerProperties[layerCount]; | |
91 res = vkEnumerateDeviceLayerProperties(physDev, &layerCount, layers); | |
92 if (VK_SUCCESS != res) { | |
93 return false; | |
94 } | |
95 int deviceLayersFound = 0; | |
96 for (uint32_t j = 0; j < ARRAYSIZE(kEnabledLayerNames); ++j) { | |
97 for (uint32_t i = 0; i < layerCount; ++i) { | |
98 if (!strncmp(layers[i].layerName, kEnabledLayerNames[j], | |
99 strlen(kEnabledLayerNames[j]))) { | |
100 ++deviceLayersFound; | |
101 break; | |
102 } | |
103 } | |
104 } | |
105 delete[] layers; | |
106 | |
107 return deviceLayersFound == ARRAYSIZE(kEnabledLayerNames); | |
108 } | |
109 #endif | |
110 | 37 |
111 // Create the base Vulkan objects needed by the GrVkGpu object | 38 // Create the base Vulkan objects needed by the GrVkGpu object |
112 const GrVkBackendContext* GrVkBackendContext::Create() { | 39 const GrVkBackendContext* GrVkBackendContext::Create() { |
113 VkPhysicalDevice physDev; | 40 VkPhysicalDevice physDev; |
114 VkDevice device; | 41 VkDevice device; |
115 VkInstance inst; | 42 VkInstance inst; |
116 VkResult err; | 43 VkResult err; |
117 | 44 |
118 const VkApplicationInfo app_info = { | 45 const VkApplicationInfo app_info = { |
119 VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType | 46 VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType |
120 nullptr, // pNext | 47 nullptr, // pNext |
121 "vktest", // pApplicationName | 48 "vktest", // pApplicationName |
122 0, // applicationVersion | 49 0, // applicationVersion |
123 "vktest", // pEngineName | 50 "vktest", // pEngineName |
124 0, // engineVerison | 51 0, // engineVerison |
125 kGrVkMinimumVersion, // apiVersion | 52 kGrVkMinimumVersion, // apiVersion |
126 }; | 53 }; |
127 | 54 |
128 const char** enabledLayerNames = nullptr; | 55 GrVkExtensions extensions; |
129 int enabledLayerCount = 0; | 56 extensions.initInstance(kGrVkMinimumVersion); |
130 const char** enabledInstanceExtensionNames = nullptr; | 57 |
131 int enabledInstanceExtensionCount = 0; | 58 SkTArray<const char*> instanceLayerNames; |
| 59 SkTArray<const char*> instanceExtensionNames; |
| 60 uint32_t extensionFlags = 0; |
132 #ifdef ENABLE_VK_LAYERS | 61 #ifdef ENABLE_VK_LAYERS |
133 if (verify_instance_layers()) { | 62 for (int i = 0; i < SK_ARRAY_COUNT(kDebugLayerNames); ++i) { |
134 enabledLayerNames = kEnabledLayerNames; | 63 if (extensions.hasInstanceLayer(kDebugLayerNames[i])) { |
135 enabledLayerCount = ARRAYSIZE(kEnabledLayerNames); | 64 instanceLayerNames.push_back(kDebugLayerNames[i]); |
136 enabledInstanceExtensionNames = kEnabledInstanceExtensionNames; | 65 } |
137 enabledInstanceExtensionCount = ARRAYSIZE(kEnabledInstanceExtensionNames
); | 66 } |
| 67 if (extensions.hasInstanceExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) { |
| 68 instanceExtensionNames.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); |
| 69 extensionFlags |= kEXT_debug_report_GrVkExtensionFlag; |
138 } | 70 } |
139 #endif | 71 #endif |
140 | 72 |
141 const VkInstanceCreateInfo instance_create = { | 73 const VkInstanceCreateInfo instance_create = { |
142 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType | 74 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType |
143 nullptr, // pNext | 75 nullptr, // pNext |
144 0, // flags | 76 0, // flags |
145 &app_info, // pApplicationInfo | 77 &app_info, // pApplicationInfo |
146 enabledLayerCount, // enabledLayerNameCount | 78 instanceLayerNames.count(), // enabledLayerNameCount |
147 enabledLayerNames, // ppEnabledLayerNames | 79 instanceLayerNames.begin(), // ppEnabledLayerNames |
148 enabledInstanceExtensionCount, // enabledExtensionNameCount | 80 instanceExtensionNames.count(), // enabledExtensionNameCount |
149 enabledInstanceExtensionNames, // ppEnabledExtensionNames | 81 instanceExtensionNames.begin(), // ppEnabledExtensionNames |
150 }; | 82 }; |
151 | 83 |
152 err = vkCreateInstance(&instance_create, nullptr, &inst); | 84 err = vkCreateInstance(&instance_create, nullptr, &inst); |
153 if (err < 0) { | 85 if (err < 0) { |
154 SkDebugf("vkCreateInstance failed: %d\n", err); | 86 SkDebugf("vkCreateInstance failed: %d\n", err); |
155 SkFAIL("failing"); | 87 SkFAIL("failing"); |
156 } | 88 } |
157 | 89 |
158 uint32_t gpuCount; | 90 uint32_t gpuCount; |
159 err = vkEnumeratePhysicalDevices(inst, &gpuCount, nullptr); | 91 err = vkEnumeratePhysicalDevices(inst, &gpuCount, nullptr); |
(...skipping 25 matching lines...) Expand all Loading... |
185 // iterate to find the graphics queue | 117 // iterate to find the graphics queue |
186 uint32_t graphicsQueueIndex = -1; | 118 uint32_t graphicsQueueIndex = -1; |
187 for (uint32_t i = 0; i < queueCount; i++) { | 119 for (uint32_t i = 0; i < queueCount; i++) { |
188 if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { | 120 if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { |
189 graphicsQueueIndex = i; | 121 graphicsQueueIndex = i; |
190 break; | 122 break; |
191 } | 123 } |
192 } | 124 } |
193 SkASSERT(graphicsQueueIndex < queueCount); | 125 SkASSERT(graphicsQueueIndex < queueCount); |
194 | 126 |
| 127 extensions.initDevice(kGrVkMinimumVersion, inst, physDev); |
| 128 |
| 129 SkTArray<const char*> deviceLayerNames; |
| 130 SkTArray<const char*> deviceExtensionNames; |
195 #ifdef ENABLE_VK_LAYERS | 131 #ifdef ENABLE_VK_LAYERS |
196 // unlikely that the device will have different layers than the instance, bu
t good to check | 132 for (int i = 0; i < SK_ARRAY_COUNT(kDebugLayerNames); ++i) { |
197 if (!verify_device_layers(physDev)) { | 133 if (extensions.hasDeviceLayer(kDebugLayerNames[i])) { |
198 enabledLayerNames = nullptr; | 134 deviceLayerNames.push_back(kDebugLayerNames[i]); |
199 enabledLayerCount = 0; | 135 } |
200 } | 136 } |
201 #endif | 137 #endif |
| 138 if (extensions.hasDeviceExtension("VK_NV_glsl_shader")) { |
| 139 deviceExtensionNames.push_back("VK_NV_glsl_shader"); |
| 140 extensionFlags |= kNV_glsl_shader_GrVkExtensionFlag; |
| 141 } |
| 142 |
| 143 // query to get the physical device properties |
| 144 VkPhysicalDeviceFeatures deviceFeatures; |
| 145 vkGetPhysicalDeviceFeatures(physDev, &deviceFeatures); |
| 146 // this looks like it would slow things down, |
| 147 // and we can't depend on it on all platforms |
| 148 deviceFeatures.robustBufferAccess = VK_FALSE; |
| 149 |
| 150 uint32_t featureFlags = 0; |
| 151 if (deviceFeatures.geometryShader) { |
| 152 featureFlags |= kGeometryShader_GrVkFeatureFlag; |
| 153 } |
| 154 if (deviceFeatures.dualSrcBlend) { |
| 155 featureFlags |= kDualSrcBlend_GrVkFeatureFlag; |
| 156 } |
| 157 if (deviceFeatures.sampleRateShading) { |
| 158 featureFlags |= kSampleRateShading_GrVkFeatureFlag; |
| 159 } |
202 | 160 |
203 float queuePriorities[1] = { 0.0 }; | 161 float queuePriorities[1] = { 0.0 }; |
204 // Here we assume no need for swapchain queue | 162 // Here we assume no need for swapchain queue |
205 // If one is needed, the client will need its own setup code | 163 // If one is needed, the client will need its own setup code |
206 const VkDeviceQueueCreateInfo queueInfo = { | 164 const VkDeviceQueueCreateInfo queueInfo = { |
207 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType | 165 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType |
208 nullptr, // pNext | 166 nullptr, // pNext |
209 0, // VkDeviceQueueCreateFlags | 167 0, // VkDeviceQueueCreateFlags |
210 graphicsQueueIndex, // queueFamilyIndex | 168 graphicsQueueIndex, // queueFamilyIndex |
211 1, // queueCount | 169 1, // queueCount |
212 queuePriorities, // pQueuePriorities | 170 queuePriorities, // pQueuePriorities |
213 }; | 171 }; |
214 const VkDeviceCreateInfo deviceInfo = { | 172 const VkDeviceCreateInfo deviceInfo = { |
215 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType | 173 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType |
216 nullptr, // pNext | 174 nullptr, // pNext |
217 0, // VkDeviceCreateFlags | 175 0, // VkDeviceCreateFlags |
218 1, // queueCreateInfoCount | 176 1, // queueCreateInfoCount |
219 &queueInfo, // pQueueCreateInfos | 177 &queueInfo, // pQueueCreateInfos |
220 enabledLayerCount, // layerCount | 178 deviceLayerNames.count(), // layerCount |
221 enabledLayerNames, // ppEnabledLayerNames | 179 deviceLayerNames.begin(), // ppEnabledLayerNames |
222 0, // extensionCount | 180 deviceExtensionNames.count(), // extensionCount |
223 nullptr, // ppEnabledExtensionNames | 181 deviceExtensionNames.begin(), // ppEnabledExtensionNames |
224 nullptr // ppEnabledFeatures | 182 &deviceFeatures // ppEnabledFeatures |
225 }; | 183 }; |
226 | 184 |
227 err = vkCreateDevice(physDev, &deviceInfo, nullptr, &device); | 185 err = vkCreateDevice(physDev, &deviceInfo, nullptr, &device); |
228 if (err) { | 186 if (err) { |
229 SkDebugf("CreateDevice failed: %d\n", err); | 187 SkDebugf("CreateDevice failed: %d\n", err); |
230 return nullptr; | 188 return nullptr; |
231 } | 189 } |
232 | 190 |
233 VkQueue queue; | 191 VkQueue queue; |
234 vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue); | 192 vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue); |
235 | 193 |
236 GrVkBackendContext* ctx = new GrVkBackendContext(); | 194 GrVkBackendContext* ctx = new GrVkBackendContext(); |
237 ctx->fInstance = inst; | 195 ctx->fInstance = inst; |
238 ctx->fPhysicalDevice = physDev; | 196 ctx->fPhysicalDevice = physDev; |
239 ctx->fDevice = device; | 197 ctx->fDevice = device; |
240 ctx->fQueue = queue; | 198 ctx->fQueue = queue; |
241 ctx->fQueueFamilyIndex = graphicsQueueIndex; | 199 ctx->fQueueFamilyIndex = graphicsQueueIndex; |
242 ctx->fInterface.reset(GrVkCreateInterface(inst, physDev, device)); | 200 ctx->fMinAPIVersion = kGrVkMinimumVersion; |
| 201 ctx->fExtensions = extensionFlags; |
| 202 ctx->fFeatures = featureFlags; |
| 203 ctx->fInterface.reset(GrVkCreateInterface(inst, device, extensionFlags)); |
243 | 204 |
244 return ctx; | 205 return ctx; |
245 } | 206 } |
246 | 207 |
247 GrVkBackendContext::~GrVkBackendContext() { | 208 GrVkBackendContext::~GrVkBackendContext() { |
248 vkDestroyDevice(fDevice, nullptr); | 209 vkDestroyDevice(fDevice, nullptr); |
249 fDevice = VK_NULL_HANDLE; | 210 fDevice = VK_NULL_HANDLE; |
250 vkDestroyInstance(fInstance, nullptr); | 211 vkDestroyInstance(fInstance, nullptr); |
251 fInstance = VK_NULL_HANDLE; | 212 fInstance = VK_NULL_HANDLE; |
252 } | 213 } |
OLD | NEW |