1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2019 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_GANESH) && defined(SK_VULKAN)
11*c8dee2aaSAndroid Build Coastguard Worker
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/vk/VulkanTypes.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkAutoMalloc.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "tests/CtsEnforcement.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/vk/VkTestUtils.h"
18*c8dee2aaSAndroid Build Coastguard Worker
19*c8dee2aaSAndroid Build Coastguard Worker #include <algorithm>
20*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
21*c8dee2aaSAndroid Build Coastguard Worker #include <cstring>
22*c8dee2aaSAndroid Build Coastguard Worker #include <functional>
23*c8dee2aaSAndroid Build Coastguard Worker #include <initializer_list>
24*c8dee2aaSAndroid Build Coastguard Worker #include <vulkan/vulkan_core.h>
25*c8dee2aaSAndroid Build Coastguard Worker
26*c8dee2aaSAndroid Build Coastguard Worker struct GrContextOptions;
27*c8dee2aaSAndroid Build Coastguard Worker
28*c8dee2aaSAndroid Build Coastguard Worker #define ACQUIRE_VK_PROC_NOCHECK(name, instance) \
29*c8dee2aaSAndroid Build Coastguard Worker PFN_vk##name grVk##name = \
30*c8dee2aaSAndroid Build Coastguard Worker reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, VK_NULL_HANDLE))
31*c8dee2aaSAndroid Build Coastguard Worker
32*c8dee2aaSAndroid Build Coastguard Worker #define ACQUIRE_VK_PROC(name, instance) \
33*c8dee2aaSAndroid Build Coastguard Worker PFN_vk##name grVk##name = \
34*c8dee2aaSAndroid Build Coastguard Worker reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, VK_NULL_HANDLE)); \
35*c8dee2aaSAndroid Build Coastguard Worker do { \
36*c8dee2aaSAndroid Build Coastguard Worker if (grVk##name == nullptr) { \
37*c8dee2aaSAndroid Build Coastguard Worker if (instance != VK_NULL_HANDLE) { \
38*c8dee2aaSAndroid Build Coastguard Worker destroy_instance(getProc, instance); \
39*c8dee2aaSAndroid Build Coastguard Worker } \
40*c8dee2aaSAndroid Build Coastguard Worker return; \
41*c8dee2aaSAndroid Build Coastguard Worker } \
42*c8dee2aaSAndroid Build Coastguard Worker } while (0)
43*c8dee2aaSAndroid Build Coastguard Worker
44*c8dee2aaSAndroid Build Coastguard Worker #define ACQUIRE_VK_PROC_LOCAL(name, instance) \
45*c8dee2aaSAndroid Build Coastguard Worker PFN_vk##name grVk##name = \
46*c8dee2aaSAndroid Build Coastguard Worker reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, VK_NULL_HANDLE)); \
47*c8dee2aaSAndroid Build Coastguard Worker do { \
48*c8dee2aaSAndroid Build Coastguard Worker if (grVk##name == nullptr) { \
49*c8dee2aaSAndroid Build Coastguard Worker return; \
50*c8dee2aaSAndroid Build Coastguard Worker } \
51*c8dee2aaSAndroid Build Coastguard Worker } while (0)
52*c8dee2aaSAndroid Build Coastguard Worker
53*c8dee2aaSAndroid Build Coastguard Worker #define GET_PROC_LOCAL(F, inst) PFN_vk ## F F = (PFN_vk ## F) getProc("vk" #F, inst, VK_NULL_HANDLE)
54*c8dee2aaSAndroid Build Coastguard Worker
destroy_instance(const skgpu::VulkanGetProc & getProc,VkInstance inst)55*c8dee2aaSAndroid Build Coastguard Worker static void destroy_instance(const skgpu::VulkanGetProc& getProc, VkInstance inst) {
56*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_VK_PROC_LOCAL(DestroyInstance, inst);
57*c8dee2aaSAndroid Build Coastguard Worker grVkDestroyInstance(inst, nullptr);
58*c8dee2aaSAndroid Build Coastguard Worker }
59*c8dee2aaSAndroid Build Coastguard Worker
60*c8dee2aaSAndroid Build Coastguard Worker // If the extension VK_EXT_GLOBAL_PRIORITY is supported, this test just tries to create a VkDevice
61*c8dee2aaSAndroid Build Coastguard Worker // using the various global priorities. The test passes if no errors are reported or the test
62*c8dee2aaSAndroid Build Coastguard Worker // doesn't crash.
DEF_GANESH_TEST_FOR_VULKAN_CONTEXT(VulkanPriorityExtension,reporter,context_info,CtsEnforcement::kApiLevel_T)63*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_VULKAN_CONTEXT(VulkanPriorityExtension,
64*c8dee2aaSAndroid Build Coastguard Worker reporter,
65*c8dee2aaSAndroid Build Coastguard Worker context_info,
66*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
67*c8dee2aaSAndroid Build Coastguard Worker PFN_vkGetInstanceProcAddr instProc;
68*c8dee2aaSAndroid Build Coastguard Worker if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) {
69*c8dee2aaSAndroid Build Coastguard Worker return;
70*c8dee2aaSAndroid Build Coastguard Worker }
71*c8dee2aaSAndroid Build Coastguard Worker // This isn't the most effecient but we just use the instProc to get all ptrs.
72*c8dee2aaSAndroid Build Coastguard Worker auto getProc = [instProc](const char* proc_name, VkInstance instance, VkDevice) {
73*c8dee2aaSAndroid Build Coastguard Worker return instProc(instance, proc_name);
74*c8dee2aaSAndroid Build Coastguard Worker };
75*c8dee2aaSAndroid Build Coastguard Worker
76*c8dee2aaSAndroid Build Coastguard Worker VkResult err;
77*c8dee2aaSAndroid Build Coastguard Worker
78*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_VK_PROC_NOCHECK(EnumerateInstanceVersion, VK_NULL_HANDLE);
79*c8dee2aaSAndroid Build Coastguard Worker uint32_t instanceVersion = 0;
80*c8dee2aaSAndroid Build Coastguard Worker if (!grVkEnumerateInstanceVersion) {
81*c8dee2aaSAndroid Build Coastguard Worker instanceVersion = VK_MAKE_VERSION(1, 0, 0);
82*c8dee2aaSAndroid Build Coastguard Worker } else {
83*c8dee2aaSAndroid Build Coastguard Worker err = grVkEnumerateInstanceVersion(&instanceVersion);
84*c8dee2aaSAndroid Build Coastguard Worker if (err) {
85*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "failed ot enumerate instance version. Err: %d", err);
86*c8dee2aaSAndroid Build Coastguard Worker return;
87*c8dee2aaSAndroid Build Coastguard Worker }
88*c8dee2aaSAndroid Build Coastguard Worker }
89*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(instanceVersion >= VK_MAKE_VERSION(1, 0, 0));
90*c8dee2aaSAndroid Build Coastguard Worker uint32_t apiVersion = VK_MAKE_VERSION(1, 0, 0);
91*c8dee2aaSAndroid Build Coastguard Worker if (instanceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
92*c8dee2aaSAndroid Build Coastguard Worker // If the instance version is 1.0 we must have the apiVersion also be 1.0. However, if the
93*c8dee2aaSAndroid Build Coastguard Worker // instance version is 1.1 or higher, we can set the apiVersion to be whatever the highest
94*c8dee2aaSAndroid Build Coastguard Worker // api we may use in skia (technically it can be arbitrary). So for now we set it to 1.1
95*c8dee2aaSAndroid Build Coastguard Worker // since that is the highest vulkan version.
96*c8dee2aaSAndroid Build Coastguard Worker apiVersion = VK_MAKE_VERSION(1, 1, 0);
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker
99*c8dee2aaSAndroid Build Coastguard Worker instanceVersion = std::min(instanceVersion, apiVersion);
100*c8dee2aaSAndroid Build Coastguard Worker
101*c8dee2aaSAndroid Build Coastguard Worker VkPhysicalDevice physDev;
102*c8dee2aaSAndroid Build Coastguard Worker VkDevice device;
103*c8dee2aaSAndroid Build Coastguard Worker VkInstance inst;
104*c8dee2aaSAndroid Build Coastguard Worker
105*c8dee2aaSAndroid Build Coastguard Worker const VkApplicationInfo app_info = {
106*c8dee2aaSAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType
107*c8dee2aaSAndroid Build Coastguard Worker nullptr, // pNext
108*c8dee2aaSAndroid Build Coastguard Worker "vktest", // pApplicationName
109*c8dee2aaSAndroid Build Coastguard Worker 0, // applicationVersion
110*c8dee2aaSAndroid Build Coastguard Worker "vktest", // pEngineName
111*c8dee2aaSAndroid Build Coastguard Worker 0, // engineVersion
112*c8dee2aaSAndroid Build Coastguard Worker apiVersion, // apiVersion
113*c8dee2aaSAndroid Build Coastguard Worker };
114*c8dee2aaSAndroid Build Coastguard Worker
115*c8dee2aaSAndroid Build Coastguard Worker const VkInstanceCreateInfo instance_create = {
116*c8dee2aaSAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
117*c8dee2aaSAndroid Build Coastguard Worker nullptr, // pNext
118*c8dee2aaSAndroid Build Coastguard Worker 0, // flags
119*c8dee2aaSAndroid Build Coastguard Worker &app_info, // pApplicationInfo
120*c8dee2aaSAndroid Build Coastguard Worker 0, // enabledLayerNameCount
121*c8dee2aaSAndroid Build Coastguard Worker nullptr, // ppEnabledLayerNames
122*c8dee2aaSAndroid Build Coastguard Worker 0, // enabledExtensionNameCount
123*c8dee2aaSAndroid Build Coastguard Worker nullptr, // ppEnabledExtensionNames
124*c8dee2aaSAndroid Build Coastguard Worker };
125*c8dee2aaSAndroid Build Coastguard Worker
126*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_VK_PROC(CreateInstance, VK_NULL_HANDLE);
127*c8dee2aaSAndroid Build Coastguard Worker err = grVkCreateInstance(&instance_create, nullptr, &inst);
128*c8dee2aaSAndroid Build Coastguard Worker if (err < 0) {
129*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to create VkInstance");
130*c8dee2aaSAndroid Build Coastguard Worker return;
131*c8dee2aaSAndroid Build Coastguard Worker }
132*c8dee2aaSAndroid Build Coastguard Worker
133*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_VK_PROC(EnumeratePhysicalDevices, inst);
134*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_VK_PROC(GetPhysicalDeviceProperties, inst);
135*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_VK_PROC(GetPhysicalDeviceQueueFamilyProperties, inst);
136*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_VK_PROC(GetPhysicalDeviceFeatures, inst);
137*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_VK_PROC(CreateDevice, inst);
138*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_VK_PROC(GetDeviceQueue, inst);
139*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_VK_PROC(DeviceWaitIdle, inst);
140*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_VK_PROC(DestroyDevice, inst);
141*c8dee2aaSAndroid Build Coastguard Worker
142*c8dee2aaSAndroid Build Coastguard Worker uint32_t gpuCount;
143*c8dee2aaSAndroid Build Coastguard Worker err = grVkEnumeratePhysicalDevices(inst, &gpuCount, nullptr);
144*c8dee2aaSAndroid Build Coastguard Worker if (err) {
145*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "vkEnumeratePhysicalDevices failed: %d", err);
146*c8dee2aaSAndroid Build Coastguard Worker destroy_instance(getProc, inst);
147*c8dee2aaSAndroid Build Coastguard Worker return;
148*c8dee2aaSAndroid Build Coastguard Worker }
149*c8dee2aaSAndroid Build Coastguard Worker if (!gpuCount) {
150*c8dee2aaSAndroid Build Coastguard Worker // Don't throw and error here, because this behavior is allowed by Android CTS. A device
151*c8dee2aaSAndroid Build Coastguard Worker // count of 0 effectively means Vulkan is not supported.
152*c8dee2aaSAndroid Build Coastguard Worker destroy_instance(getProc, inst);
153*c8dee2aaSAndroid Build Coastguard Worker return;
154*c8dee2aaSAndroid Build Coastguard Worker }
155*c8dee2aaSAndroid Build Coastguard Worker // Just returning the first physical device instead of getting the whole array.
156*c8dee2aaSAndroid Build Coastguard Worker // TODO: find best match for our needs
157*c8dee2aaSAndroid Build Coastguard Worker gpuCount = 1;
158*c8dee2aaSAndroid Build Coastguard Worker err = grVkEnumeratePhysicalDevices(inst, &gpuCount, &physDev);
159*c8dee2aaSAndroid Build Coastguard Worker // VK_INCOMPLETE is returned when the count we provide is less than the total device count.
160*c8dee2aaSAndroid Build Coastguard Worker if (err && VK_INCOMPLETE != err) {
161*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "vkEnumeratePhysicalDevices failed: %d", err);
162*c8dee2aaSAndroid Build Coastguard Worker destroy_instance(getProc, inst);
163*c8dee2aaSAndroid Build Coastguard Worker return;
164*c8dee2aaSAndroid Build Coastguard Worker }
165*c8dee2aaSAndroid Build Coastguard Worker
166*c8dee2aaSAndroid Build Coastguard Worker // query to get the initial queue props size
167*c8dee2aaSAndroid Build Coastguard Worker uint32_t queueCount;
168*c8dee2aaSAndroid Build Coastguard Worker grVkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr);
169*c8dee2aaSAndroid Build Coastguard Worker if (!queueCount) {
170*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "vkGetPhysicalDeviceQueueFamilyProperties returned no queues.");
171*c8dee2aaSAndroid Build Coastguard Worker destroy_instance(getProc, inst);
172*c8dee2aaSAndroid Build Coastguard Worker return;
173*c8dee2aaSAndroid Build Coastguard Worker }
174*c8dee2aaSAndroid Build Coastguard Worker
175*c8dee2aaSAndroid Build Coastguard Worker SkAutoMalloc queuePropsAlloc(queueCount * sizeof(VkQueueFamilyProperties));
176*c8dee2aaSAndroid Build Coastguard Worker // now get the actual queue props
177*c8dee2aaSAndroid Build Coastguard Worker VkQueueFamilyProperties* queueProps = (VkQueueFamilyProperties*)queuePropsAlloc.get();
178*c8dee2aaSAndroid Build Coastguard Worker
179*c8dee2aaSAndroid Build Coastguard Worker grVkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueProps);
180*c8dee2aaSAndroid Build Coastguard Worker
181*c8dee2aaSAndroid Build Coastguard Worker // iterate to find the graphics queue
182*c8dee2aaSAndroid Build Coastguard Worker uint32_t graphicsQueueIndex = queueCount;
183*c8dee2aaSAndroid Build Coastguard Worker for (uint32_t i = 0; i < queueCount; i++) {
184*c8dee2aaSAndroid Build Coastguard Worker if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
185*c8dee2aaSAndroid Build Coastguard Worker graphicsQueueIndex = i;
186*c8dee2aaSAndroid Build Coastguard Worker break;
187*c8dee2aaSAndroid Build Coastguard Worker }
188*c8dee2aaSAndroid Build Coastguard Worker }
189*c8dee2aaSAndroid Build Coastguard Worker if (graphicsQueueIndex == queueCount) {
190*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Could not find any supported graphics queues.");
191*c8dee2aaSAndroid Build Coastguard Worker destroy_instance(getProc, inst);
192*c8dee2aaSAndroid Build Coastguard Worker return;
193*c8dee2aaSAndroid Build Coastguard Worker }
194*c8dee2aaSAndroid Build Coastguard Worker
195*c8dee2aaSAndroid Build Coastguard Worker GET_PROC_LOCAL(EnumerateDeviceExtensionProperties, inst);
196*c8dee2aaSAndroid Build Coastguard Worker GET_PROC_LOCAL(EnumerateDeviceLayerProperties, inst);
197*c8dee2aaSAndroid Build Coastguard Worker
198*c8dee2aaSAndroid Build Coastguard Worker if (!EnumerateDeviceExtensionProperties ||
199*c8dee2aaSAndroid Build Coastguard Worker !EnumerateDeviceLayerProperties) {
200*c8dee2aaSAndroid Build Coastguard Worker destroy_instance(getProc, inst);
201*c8dee2aaSAndroid Build Coastguard Worker return;
202*c8dee2aaSAndroid Build Coastguard Worker }
203*c8dee2aaSAndroid Build Coastguard Worker
204*c8dee2aaSAndroid Build Coastguard Worker // device extensions
205*c8dee2aaSAndroid Build Coastguard Worker // via Vulkan implementation and implicitly enabled layers
206*c8dee2aaSAndroid Build Coastguard Worker uint32_t extensionCount = 0;
207*c8dee2aaSAndroid Build Coastguard Worker err = EnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, nullptr);
208*c8dee2aaSAndroid Build Coastguard Worker if (VK_SUCCESS != err) {
209*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Could not enumerate device extension properties.");
210*c8dee2aaSAndroid Build Coastguard Worker destroy_instance(getProc, inst);
211*c8dee2aaSAndroid Build Coastguard Worker return;
212*c8dee2aaSAndroid Build Coastguard Worker }
213*c8dee2aaSAndroid Build Coastguard Worker VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
214*c8dee2aaSAndroid Build Coastguard Worker err = EnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, extensions);
215*c8dee2aaSAndroid Build Coastguard Worker if (VK_SUCCESS != err) {
216*c8dee2aaSAndroid Build Coastguard Worker delete[] extensions;
217*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Could not enumerate device extension properties.");
218*c8dee2aaSAndroid Build Coastguard Worker destroy_instance(getProc, inst);
219*c8dee2aaSAndroid Build Coastguard Worker return;
220*c8dee2aaSAndroid Build Coastguard Worker }
221*c8dee2aaSAndroid Build Coastguard Worker bool hasPriorityExt = false;
222*c8dee2aaSAndroid Build Coastguard Worker for (uint32_t i = 0; i < extensionCount; ++i) {
223*c8dee2aaSAndroid Build Coastguard Worker if (!strcmp(extensions[i].extensionName, VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME)) {
224*c8dee2aaSAndroid Build Coastguard Worker hasPriorityExt = true;
225*c8dee2aaSAndroid Build Coastguard Worker }
226*c8dee2aaSAndroid Build Coastguard Worker }
227*c8dee2aaSAndroid Build Coastguard Worker delete[] extensions;
228*c8dee2aaSAndroid Build Coastguard Worker
229*c8dee2aaSAndroid Build Coastguard Worker if (!hasPriorityExt) {
230*c8dee2aaSAndroid Build Coastguard Worker destroy_instance(getProc, inst);
231*c8dee2aaSAndroid Build Coastguard Worker return;
232*c8dee2aaSAndroid Build Coastguard Worker }
233*c8dee2aaSAndroid Build Coastguard Worker
234*c8dee2aaSAndroid Build Coastguard Worker const char* priorityExt = VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME;
235*c8dee2aaSAndroid Build Coastguard Worker
236*c8dee2aaSAndroid Build Coastguard Worker VkPhysicalDeviceFeatures deviceFeatures;
237*c8dee2aaSAndroid Build Coastguard Worker grVkGetPhysicalDeviceFeatures(physDev, &deviceFeatures);
238*c8dee2aaSAndroid Build Coastguard Worker
239*c8dee2aaSAndroid Build Coastguard Worker // this looks like it would slow things down,
240*c8dee2aaSAndroid Build Coastguard Worker // and we can't depend on it on all platforms
241*c8dee2aaSAndroid Build Coastguard Worker deviceFeatures.robustBufferAccess = VK_FALSE;
242*c8dee2aaSAndroid Build Coastguard Worker
243*c8dee2aaSAndroid Build Coastguard Worker float queuePriorities[1] = { 0.0 };
244*c8dee2aaSAndroid Build Coastguard Worker
245*c8dee2aaSAndroid Build Coastguard Worker VkDeviceQueueGlobalPriorityCreateInfoEXT queuePriorityCreateInfo;
246*c8dee2aaSAndroid Build Coastguard Worker queuePriorityCreateInfo.sType =
247*c8dee2aaSAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT;
248*c8dee2aaSAndroid Build Coastguard Worker queuePriorityCreateInfo.pNext = nullptr;
249*c8dee2aaSAndroid Build Coastguard Worker
250*c8dee2aaSAndroid Build Coastguard Worker VkDeviceQueueCreateInfo queueInfo = {
251*c8dee2aaSAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
252*c8dee2aaSAndroid Build Coastguard Worker &queuePriorityCreateInfo, // pNext
253*c8dee2aaSAndroid Build Coastguard Worker 0, // VkDeviceQueueCreateFlags
254*c8dee2aaSAndroid Build Coastguard Worker graphicsQueueIndex, // queueFamilyIndex
255*c8dee2aaSAndroid Build Coastguard Worker 1, // queueCount
256*c8dee2aaSAndroid Build Coastguard Worker queuePriorities, // pQueuePriorities
257*c8dee2aaSAndroid Build Coastguard Worker };
258*c8dee2aaSAndroid Build Coastguard Worker
259*c8dee2aaSAndroid Build Coastguard Worker for (VkQueueGlobalPriorityEXT globalPriority : { VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT,
260*c8dee2aaSAndroid Build Coastguard Worker VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT,
261*c8dee2aaSAndroid Build Coastguard Worker VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT,
262*c8dee2aaSAndroid Build Coastguard Worker VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT }) {
263*c8dee2aaSAndroid Build Coastguard Worker queuePriorityCreateInfo.globalPriority = globalPriority;
264*c8dee2aaSAndroid Build Coastguard Worker
265*c8dee2aaSAndroid Build Coastguard Worker const VkDeviceCreateInfo deviceInfo = {
266*c8dee2aaSAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
267*c8dee2aaSAndroid Build Coastguard Worker nullptr, // pNext
268*c8dee2aaSAndroid Build Coastguard Worker 0, // VkDeviceCreateFlags
269*c8dee2aaSAndroid Build Coastguard Worker 1, // queueCreateInfoCount
270*c8dee2aaSAndroid Build Coastguard Worker &queueInfo, // pQueueCreateInfos
271*c8dee2aaSAndroid Build Coastguard Worker 0, // layerCount
272*c8dee2aaSAndroid Build Coastguard Worker nullptr, // ppEnabledLayerNames
273*c8dee2aaSAndroid Build Coastguard Worker 1, // extensionCount
274*c8dee2aaSAndroid Build Coastguard Worker &priorityExt, // ppEnabledExtensionNames
275*c8dee2aaSAndroid Build Coastguard Worker &deviceFeatures // ppEnabledFeatures
276*c8dee2aaSAndroid Build Coastguard Worker };
277*c8dee2aaSAndroid Build Coastguard Worker
278*c8dee2aaSAndroid Build Coastguard Worker err = grVkCreateDevice(physDev, &deviceInfo, nullptr, &device);
279*c8dee2aaSAndroid Build Coastguard Worker
280*c8dee2aaSAndroid Build Coastguard Worker if (err != VK_SUCCESS && err != VK_ERROR_NOT_PERMITTED_EXT) {
281*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "CreateDevice failed: %d, priority %d", err, globalPriority);
282*c8dee2aaSAndroid Build Coastguard Worker destroy_instance(getProc, inst);
283*c8dee2aaSAndroid Build Coastguard Worker continue;
284*c8dee2aaSAndroid Build Coastguard Worker }
285*c8dee2aaSAndroid Build Coastguard Worker if (err != VK_ERROR_NOT_PERMITTED_EXT) {
286*c8dee2aaSAndroid Build Coastguard Worker grVkDestroyDevice(device, nullptr);
287*c8dee2aaSAndroid Build Coastguard Worker }
288*c8dee2aaSAndroid Build Coastguard Worker }
289*c8dee2aaSAndroid Build Coastguard Worker destroy_instance(getProc, inst);
290*c8dee2aaSAndroid Build Coastguard Worker }
291*c8dee2aaSAndroid Build Coastguard Worker
292*c8dee2aaSAndroid Build Coastguard Worker #endif
293