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::vector;
43 using std::string;
44
createDefaultInstance(const PlatformInterface & vkPlatform,deUint32 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,
46 deUint32 apiVersion,
47 const vector<string>& enabledLayers,
48 const vector<string>& enabledExtensions,
49 const tcu::CommandLine& cmdLine,
50 #ifndef CTS_USES_VULKANSC
51 DebugReportRecorder* recorder,
52 #endif // CTS_USES_VULKANSC
53 const VkAllocationCallbacks* pAllocator)
54 {
55 bool validationEnabled = (!enabledLayers.empty());
56 vector<string> actualExtensions = enabledExtensions;
57
58 // Enumerate once, pass it in to the various functions that require the list of available extensions
59 vector<vk::VkExtensionProperties> availableExtensions = enumerateInstanceExtensionProperties(vkPlatform, DE_NULL);
60
61 #ifndef CTS_USES_VULKANSC
62 if (validationEnabled)
63 {
64 // Make sure the debug report extension is enabled when validation is enabled.
65 if (!isExtensionStructSupported(availableExtensions, RequiredExtension("VK_EXT_debug_report")))
66 TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
67
68 if (!de::contains(begin(actualExtensions), end(actualExtensions), "VK_EXT_debug_report"))
69 actualExtensions.push_back("VK_EXT_debug_report");
70
71 DE_ASSERT(recorder);
72 }
73
74 // Make sure portability enumeration is enabled whenever it is available
75 bool portability_enumeration_available = isExtensionStructSupported(availableExtensions, RequiredExtension("VK_KHR_portability_enumeration"));
76 if (portability_enumeration_available)
77 {
78 actualExtensions.push_back("VK_KHR_portability_enumeration");
79 }
80
81 #endif // CTS_USES_VULKANSC
82
83 vector<const char*> layerNamePtrs (enabledLayers.size());
84 vector<const char*> extensionNamePtrs (actualExtensions.size());
85
86 for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
87 layerNamePtrs[ndx] = enabledLayers[ndx].c_str();
88
89 for (size_t ndx = 0; ndx < actualExtensions.size(); ++ndx)
90 extensionNamePtrs[ndx] = actualExtensions[ndx].c_str();
91
92 #ifdef CTS_USES_VULKANSC
93 vector<VkApplicationParametersEXT> appParams;
94 const bool hasAppParams = readApplicationParameters(appParams, cmdLine, true);
95 #else
96 DE_UNREF(cmdLine);
97 #endif // CTS_USES_VULKANSC
98
99 const struct VkApplicationInfo appInfo =
100 {
101 VK_STRUCTURE_TYPE_APPLICATION_INFO,
102 #ifdef CTS_USES_VULKANSC
103 hasAppParams ? &appParams[0] : DE_NULL,
104 #else
105 DE_NULL,
106 #endif // CTS_USES_VULKANSC
107 "deqp", // pAppName
108 qpGetReleaseId(), // appVersion
109 "deqp", // pEngineName
110 qpGetReleaseId(), // engineVersion
111 apiVersion // apiVersion
112 };
113
114
115 #ifndef CTS_USES_VULKANSC
116 const VkDebugReportCallbackCreateInfoEXT callbackInfo = (validationEnabled ? recorder->makeCreateInfo() : initVulkanStructure());
117 #endif // CTS_USES_VULKANSC
118
119 const struct VkInstanceCreateInfo instanceInfo =
120 {
121 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
122 #ifndef CTS_USES_VULKANSC
123 (validationEnabled ? &callbackInfo : nullptr),
124 (VkInstanceCreateFlags)(portability_enumeration_available ? VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR : 0),
125 #else
126 nullptr,
127 (VkInstanceCreateFlags)0,
128 #endif // CTS_USES_VULKANSC
129 &appInfo,
130 (deUint32)layerNamePtrs.size(),
131 (validationEnabled ? layerNamePtrs.data() : nullptr),
132 (deUint32)extensionNamePtrs.size(),
133 (extensionNamePtrs.empty() ? nullptr : extensionNamePtrs.data()),
134 };
135
136 return createInstance(vkPlatform, &instanceInfo, pAllocator);
137 }
138
createDefaultInstance(const PlatformInterface & vkPlatform,deUint32 apiVersion,const tcu::CommandLine & cmdLine)139 Move<VkInstance> createDefaultInstance (const PlatformInterface& vkPlatform, deUint32 apiVersion, const tcu::CommandLine& cmdLine)
140 {
141 #ifndef CTS_USES_VULKANSC
142 return createDefaultInstance(vkPlatform, apiVersion, vector<string>(), vector<string>(), cmdLine, nullptr, nullptr);
143 #else
144 return createDefaultInstance(vkPlatform, apiVersion, vector<string>(), vector<string>(), cmdLine, nullptr);
145 #endif
146 }
147
chooseDeviceIndex(const InstanceInterface & vkInstance,const VkInstance instance,const tcu::CommandLine & cmdLine)148 deUint32 chooseDeviceIndex (const InstanceInterface& vkInstance, const VkInstance instance, 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 deUint32 deviceIdFromCmdLine = cmdLine.getVKDeviceId();
156 if (!de::inBounds(deviceIdFromCmdLine, 0u, static_cast<deUint32>(devices.size() + 1)))
157 TCU_THROW(InternalError, "Invalid --deqp-vk-device-id");
158
159 if (deviceIdFromCmdLine > 0)
160 return deviceIdFromCmdLine - 1u;
161
162 deUint32 maxReportedApiVersion = 0u;
163 deUint32 ndxOfMaximumVersion = 0u;
164
165 for (deUint32 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, const tcu::CommandLine& cmdLine)
180 {
181 const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(vkInstance, instance);
182
183 if (devices.empty())
184 TCU_THROW(NotSupportedError, "No Vulkan devices available");
185
186 const size_t deviceId = chooseDeviceIndex(vkInstance, instance, cmdLine);
187 return devices[deviceId];
188 }
189
190 } // vk
191