xref: /aosp_15_r20/external/deqp/external/vulkancts/framework/vulkan/vkDeviceUtil.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * Vulkan CTS Framework
3  * --------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Instance and device initialization utilities.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "deSTLUtil.hpp"
25 #include "vkDeviceUtil.hpp"
26 #include "vkQueryUtil.hpp"
27 #include "vkRefUtil.hpp"
28 #include "vkApiVersion.hpp"
29 #include "vkDebugReportUtil.hpp"
30 
31 #include "tcuCommandLine.hpp"
32 
33 #include "qpInfo.h"
34 
35 #ifdef CTS_USES_VULKANSC
36 #include "vkAppParamsUtil.hpp"
37 #endif // CTS_USES_VULKANSC
38 
39 namespace vk
40 {
41 
42 using std::string;
43 using std::vector;
44 
createDefaultInstance(const PlatformInterface & vkPlatform,uint32_t apiVersion,const vector<string> & enabledLayers,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine,DebugReportRecorder * recorder,const VkAllocationCallbacks * pAllocator)45 Move<VkInstance> createDefaultInstance(const PlatformInterface &vkPlatform, uint32_t apiVersion,
46                                        const vector<string> &enabledLayers, const vector<string> &enabledExtensions,
47                                        const tcu::CommandLine &cmdLine,
48 #ifndef CTS_USES_VULKANSC
49                                        DebugReportRecorder *recorder,
50 #endif // CTS_USES_VULKANSC
51                                        const VkAllocationCallbacks *pAllocator)
52 {
53     bool validationEnabled          = (!enabledLayers.empty());
54     vector<string> actualExtensions = enabledExtensions;
55 
56     // Enumerate once, pass it in to the various functions that require the list of available extensions
57     vector<vk::VkExtensionProperties> availableExtensions = enumerateInstanceExtensionProperties(vkPlatform, DE_NULL);
58 
59 #ifndef CTS_USES_VULKANSC
60     if (validationEnabled)
61     {
62         // Make sure the debug report extension is enabled when validation is enabled.
63         if (!isExtensionStructSupported(availableExtensions, RequiredExtension("VK_EXT_debug_report")))
64             TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
65 
66         if (!de::contains(begin(actualExtensions), end(actualExtensions), "VK_EXT_debug_report"))
67             actualExtensions.push_back("VK_EXT_debug_report");
68 
69         DE_ASSERT(recorder);
70     }
71 
72     // Make sure portability enumeration is enabled whenever it is available
73     bool portability_enumeration_available =
74         isExtensionStructSupported(availableExtensions, RequiredExtension("VK_KHR_portability_enumeration"));
75     if (portability_enumeration_available)
76     {
77         actualExtensions.push_back("VK_KHR_portability_enumeration");
78     }
79 
80 #endif // CTS_USES_VULKANSC
81 
82     vector<const char *> layerNamePtrs(enabledLayers.size());
83     vector<const char *> extensionNamePtrs(actualExtensions.size());
84 
85     for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
86         layerNamePtrs[ndx] = enabledLayers[ndx].c_str();
87 
88     for (size_t ndx = 0; ndx < actualExtensions.size(); ++ndx)
89         extensionNamePtrs[ndx] = actualExtensions[ndx].c_str();
90 
91 #ifdef CTS_USES_VULKANSC
92     vector<VkApplicationParametersEXT> appParams;
93     const bool hasAppParams = readApplicationParameters(appParams, cmdLine, true);
94 #else
95     DE_UNREF(cmdLine);
96 #endif // CTS_USES_VULKANSC
97 
98     const struct VkApplicationInfo appInfo = {
99         VK_STRUCTURE_TYPE_APPLICATION_INFO,
100 #ifdef CTS_USES_VULKANSC
101         hasAppParams ? &appParams[0] : DE_NULL,
102 #else
103         DE_NULL,
104 #endif                    // CTS_USES_VULKANSC
105         "deqp",           // pAppName
106         qpGetReleaseId(), // appVersion
107         "deqp",           // pEngineName
108         qpGetReleaseId(), // engineVersion
109         apiVersion        // apiVersion
110     };
111 
112 #ifndef CTS_USES_VULKANSC
113     const VkDebugReportCallbackCreateInfoEXT callbackInfo =
114         (validationEnabled ? recorder->makeCreateInfo() : initVulkanStructure());
115 #endif // CTS_USES_VULKANSC
116 
117     const struct VkInstanceCreateInfo instanceInfo = {
118         VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
119 #ifndef CTS_USES_VULKANSC
120         (validationEnabled ? &callbackInfo : nullptr),
121         (VkInstanceCreateFlags)(portability_enumeration_available ? VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR :
122                                                                     0),
123 #else
124         nullptr,
125         (VkInstanceCreateFlags)0,
126 #endif // CTS_USES_VULKANSC
127         &appInfo,
128         (uint32_t)layerNamePtrs.size(),
129         (validationEnabled ? layerNamePtrs.data() : nullptr),
130         (uint32_t)extensionNamePtrs.size(),
131         (extensionNamePtrs.empty() ? nullptr : extensionNamePtrs.data()),
132     };
133 
134     return createInstance(vkPlatform, &instanceInfo, pAllocator);
135 }
136 
createDefaultInstance(const PlatformInterface & vkPlatform,uint32_t apiVersion,const tcu::CommandLine & cmdLine)137 Move<VkInstance> createDefaultInstance(const PlatformInterface &vkPlatform, uint32_t apiVersion,
138                                        const tcu::CommandLine &cmdLine)
139 {
140 #ifndef CTS_USES_VULKANSC
141     return createDefaultInstance(vkPlatform, apiVersion, vector<string>(), vector<string>(), cmdLine, nullptr, nullptr);
142 #else
143     return createDefaultInstance(vkPlatform, apiVersion, vector<string>(), vector<string>(), cmdLine, nullptr);
144 #endif
145 }
146 
chooseDeviceIndex(const InstanceInterface & vkInstance,const VkInstance instance,const tcu::CommandLine & cmdLine)147 uint32_t chooseDeviceIndex(const InstanceInterface &vkInstance, const VkInstance instance,
148                            const tcu::CommandLine &cmdLine)
149 {
150     const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(vkInstance, instance);
151 
152     if (devices.empty())
153         TCU_THROW(NotSupportedError, "No Vulkan devices available");
154 
155     const uint32_t deviceIdFromCmdLine = cmdLine.getVKDeviceId();
156     if (!de::inBounds(deviceIdFromCmdLine, 0u, static_cast<uint32_t>(devices.size() + 1)))
157         TCU_THROW(InternalError, "Invalid --deqp-vk-device-id");
158 
159     if (deviceIdFromCmdLine > 0)
160         return deviceIdFromCmdLine - 1u;
161 
162     uint32_t maxReportedApiVersion = 0u;
163     uint32_t ndxOfMaximumVersion   = 0u;
164 
165     for (uint32_t deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
166     {
167         const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(vkInstance, devices[deviceNdx]);
168 
169         if (props.apiVersion > maxReportedApiVersion)
170         {
171             maxReportedApiVersion = props.apiVersion;
172             ndxOfMaximumVersion   = deviceNdx;
173         }
174     }
175 
176     return ndxOfMaximumVersion;
177 }
178 
chooseDevice(const InstanceInterface & vkInstance,const VkInstance instance,const tcu::CommandLine & cmdLine)179 VkPhysicalDevice chooseDevice(const InstanceInterface &vkInstance, const VkInstance instance,
180                               const tcu::CommandLine &cmdLine)
181 {
182     const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(vkInstance, instance);
183 
184     if (devices.empty())
185         TCU_THROW(NotSupportedError, "No Vulkan devices available");
186 
187     const size_t deviceId = chooseDeviceIndex(vkInstance, instance, cmdLine);
188     return devices[deviceId];
189 }
190 
191 } // namespace vk
192