xref: /aosp_15_r20/external/skia/tests/VkPriorityExtensionTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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