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 namespace vk
36 {
37
38 using std::vector;
39 using std::string;
40
createDefaultInstance(const PlatformInterface & vkPlatform,deUint32 apiVersion,const vector<string> & enabledLayers,const vector<string> & enabledExtensions,DebugReportRecorder * recorder,const VkAllocationCallbacks * pAllocator)41 Move<VkInstance> createDefaultInstance (const PlatformInterface& vkPlatform,
42 deUint32 apiVersion,
43 const vector<string>& enabledLayers,
44 const vector<string>& enabledExtensions,
45 DebugReportRecorder* recorder,
46 const VkAllocationCallbacks* pAllocator)
47 {
48 bool validationEnabled = (!enabledLayers.empty());
49 vector<string> actualExtensions = enabledExtensions;
50
51 if (validationEnabled)
52 {
53 // Make sure the debug report extension is enabled when validation is enabled.
54 if (!isDebugReportSupported(vkPlatform))
55 TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
56
57 if (!de::contains(begin(actualExtensions), end(actualExtensions), "VK_EXT_debug_report"))
58 actualExtensions.push_back("VK_EXT_debug_report");
59
60 DE_ASSERT(recorder);
61 }
62
63 vector<const char*> layerNamePtrs (enabledLayers.size());
64 vector<const char*> extensionNamePtrs (actualExtensions.size());
65
66 for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
67 layerNamePtrs[ndx] = enabledLayers[ndx].c_str();
68
69 for (size_t ndx = 0; ndx < actualExtensions.size(); ++ndx)
70 extensionNamePtrs[ndx] = actualExtensions[ndx].c_str();
71
72 const struct VkApplicationInfo appInfo =
73 {
74 VK_STRUCTURE_TYPE_APPLICATION_INFO,
75 DE_NULL,
76 "deqp", // pAppName
77 qpGetReleaseId(), // appVersion
78 "deqp", // pEngineName
79 qpGetReleaseId(), // engineVersion
80 apiVersion // apiVersion
81 };
82
83 const VkDebugReportCallbackCreateInfoEXT callbackInfo = (validationEnabled ? recorder->makeCreateInfo() : initVulkanStructure());
84
85 const struct VkInstanceCreateInfo instanceInfo =
86 {
87 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
88 (validationEnabled ? &callbackInfo : nullptr),
89 (VkInstanceCreateFlags)0,
90 &appInfo,
91 (deUint32)layerNamePtrs.size(),
92 (validationEnabled ? layerNamePtrs.data() : nullptr),
93 (deUint32)extensionNamePtrs.size(),
94 (extensionNamePtrs.empty() ? nullptr : extensionNamePtrs.data()),
95 };
96
97 return createInstance(vkPlatform, &instanceInfo, pAllocator);
98 }
99
createDefaultInstance(const PlatformInterface & vkPlatform,deUint32 apiVersion)100 Move<VkInstance> createDefaultInstance (const PlatformInterface& vkPlatform, deUint32 apiVersion)
101 {
102 return createDefaultInstance(vkPlatform, apiVersion, vector<string>(), vector<string>(), nullptr, nullptr);
103 }
104
chooseDeviceIndex(const InstanceInterface & vkInstance,const VkInstance instance,const tcu::CommandLine & cmdLine)105 deUint32 chooseDeviceIndex (const InstanceInterface& vkInstance, const VkInstance instance, const tcu::CommandLine& cmdLine)
106 {
107 const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(vkInstance, instance);
108
109 if (devices.empty())
110 TCU_THROW(NotSupportedError, "No Vulkan devices available");
111
112 const deUint32 deviceIdFromCmdLine = cmdLine.getVKDeviceId();
113 if (!de::inBounds(deviceIdFromCmdLine, 0u, static_cast<deUint32>(devices.size() + 1)))
114 TCU_THROW(InternalError, "Invalid --deqp-vk-device-id");
115
116 if (deviceIdFromCmdLine > 0)
117 return deviceIdFromCmdLine - 1u;
118
119 deUint32 maxReportedApiVersion = 0u;
120 deUint32 ndxOfMaximumVersion = 0u;
121
122 for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
123 {
124 const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(vkInstance, devices[deviceNdx]);
125
126 if (props.apiVersion > maxReportedApiVersion)
127 {
128 maxReportedApiVersion = props.apiVersion;
129 ndxOfMaximumVersion = deviceNdx;
130 }
131 }
132
133 return ndxOfMaximumVersion;
134 }
135
chooseDevice(const InstanceInterface & vkInstance,const VkInstance instance,const tcu::CommandLine & cmdLine)136 VkPhysicalDevice chooseDevice (const InstanceInterface& vkInstance, const VkInstance instance, const tcu::CommandLine& cmdLine)
137 {
138 const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(vkInstance, instance);
139
140 if (devices.empty())
141 TCU_THROW(NotSupportedError, "No Vulkan devices available");
142
143 const size_t deviceId = chooseDeviceIndex(vkInstance, instance, cmdLine);
144 return devices[deviceId];
145 }
146
147 } // vk
148