1c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos/*-------------------------------------------------------------------------
2846cc3ce8e721a972ef38c44e24da49ea96110caPyry Haulos * Vulkan CTS Framework
3846cc3ce8e721a972ef38c44e24da49ea96110caPyry Haulos * --------------------
4c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *
5846cc3ce8e721a972ef38c44e24da49ea96110caPyry Haulos * Copyright (c) 2015 Google Inc.
6c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *
7978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License");
8978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * you may not use this file except in compliance with the License.
9978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * You may obtain a copy of the License at
10c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *
11978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos *      http://www.apache.org/licenses/LICENSE-2.0
12c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *
13978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Unless required by applicable law or agreed to in writing, software
14978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS,
15978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * See the License for the specific language governing permissions and
17978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * limitations under the License.
18c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *
19c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *//*!
20c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos * \file
21c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos * \brief Instance and device initialization utilities.
22c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos *//*--------------------------------------------------------------------*/
23c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
24c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos#include "vkDeviceUtil.hpp"
25b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos#include "vkQueryUtil.hpp"
264b11ca9132ae388bc41f83a8fceaff3791314769Jarkko Pöyry#include "vkRefUtil.hpp"
2712021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos#include "vkApiVersion.hpp"
28c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
2932675035be2a05886457025598f90c131d83c670Pyry Haulos#include "tcuCommandLine.hpp"
3032675035be2a05886457025598f90c131d83c670Pyry Haulos
31c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos#include "qpInfo.h"
32c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
33c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulosnamespace vk
34c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos{
35c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
36c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulosusing std::vector;
3712021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulosusing std::string;
38c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
39f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry HaulosMove<VkInstance> createDefaultInstance (const PlatformInterface&		vkPlatform,
40aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin										deUint32						apiVersion,
41f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos										const vector<string>&			enabledLayers,
42f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos										const vector<string>&			enabledExtensions,
43f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos										const VkAllocationCallbacks*	pAllocator)
44c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos{
4512021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos	vector<const char*>		layerNamePtrs		(enabledLayers.size());
4612021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos	vector<const char*>		extensionNamePtrs	(enabledExtensions.size());
4712021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos
48c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos	const struct VkApplicationInfo		appInfo			=
49c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos	{
5068e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos		VK_STRUCTURE_TYPE_APPLICATION_INFO,
5168e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos		DE_NULL,
5268e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos		"deqp",									// pAppName
5368e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos		qpGetReleaseId(),						// appVersion
5468e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos		"deqp",									// pEngineName
5568e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos		qpGetReleaseId(),						// engineVersion
5612021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos		apiVersion								// apiVersion
57c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos	};
58c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos	const struct VkInstanceCreateInfo	instanceInfo	=
59c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos	{
6068e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
6168e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos		DE_NULL,
6268e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos		(VkInstanceCreateFlags)0,
6368e7282426d639b54d15c4710d97ba97e72c76efPyry Haulos		&appInfo,
6412021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos		(deUint32)layerNamePtrs.size(),
6512021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos		layerNamePtrs.empty() ? DE_NULL : &layerNamePtrs[0],
6612021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos		(deUint32)extensionNamePtrs.size(),
6712021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos		extensionNamePtrs.empty() ? DE_NULL : &extensionNamePtrs[0],
68c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos	};
69c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
7012021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos	for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
7112021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos		layerNamePtrs[ndx] = enabledLayers[ndx].c_str();
7212021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos
7312021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos	for (size_t ndx = 0; ndx < enabledExtensions.size(); ++ndx)
7412021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos		extensionNamePtrs[ndx] = enabledExtensions[ndx].c_str();
7512021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos
76f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos	return createInstance(vkPlatform, &instanceInfo, pAllocator);
77c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos}
78c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
79aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander GalazinMove<VkInstance> createDefaultInstance (const PlatformInterface& vkPlatform, deUint32 apiVersion)
8012021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos{
81aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	return createDefaultInstance(vkPlatform, apiVersion, vector<string>(), vector<string>(), DE_NULL);
8212021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos}
8312021ac26c6d6f8923f526bd7635dcf68e0c4061Pyry Haulos
84aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander GalazindeUint32 chooseDeviceIndex (const InstanceInterface& vkInstance, const VkInstance instance, const tcu::CommandLine& cmdLine)
85c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos{
86aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	const vector<VkPhysicalDevice>			devices					= enumeratePhysicalDevices(vkInstance, instance);
87c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
88b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos	if (devices.empty())
89b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos		TCU_THROW(NotSupportedError, "No Vulkan devices available");
90c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
91aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	const deUint32							deviceIdFromCmdLine		= cmdLine.getVKDeviceId();
92aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	if (!de::inBounds(deviceIdFromCmdLine, 0u, static_cast<deUint32>(devices.size() + 1)))
93b1a7d2198497be32dfc22386f99945656ff4080ePyry Haulos		TCU_THROW(InternalError, "Invalid --deqp-vk-device-id");
9432675035be2a05886457025598f90c131d83c670Pyry Haulos
95aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	if (deviceIdFromCmdLine > 0)
96aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin		return deviceIdFromCmdLine - 1u;
97aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin
98aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	deUint32								maxReportedApiVersion	= 0u;
99aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	deUint32								ndxOfMaximumVersion		= 0u;
100aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin
101aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
102aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	{
103aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin		const VkPhysicalDeviceProperties	props					= getPhysicalDeviceProperties(vkInstance, devices[deviceNdx]);
104aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin
105aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin		if (props.apiVersion > maxReportedApiVersion)
106aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin		{
107aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin			maxReportedApiVersion = props.apiVersion;
108aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin			ndxOfMaximumVersion = deviceNdx;
109aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin		}
110aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	}
111aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin
112aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	return ndxOfMaximumVersion;
113aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin}
114aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin
115aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander GalazinVkPhysicalDevice chooseDevice (const InstanceInterface& vkInstance, const VkInstance instance, const tcu::CommandLine& cmdLine)
116aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin{
117aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	const vector<VkPhysicalDevice>	devices		= enumeratePhysicalDevices(vkInstance, instance);
118aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin
119aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	if (devices.empty())
120aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin		TCU_THROW(NotSupportedError, "No Vulkan devices available");
121aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin
122aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	const size_t					deviceId	= chooseDeviceIndex(vkInstance, instance, cmdLine);
123aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	return devices[deviceId];
124c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos}
125c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos
126c33eade2c4cc2cfc1dd10bc2f95aa5622981e50ePyry Haulos} // vk
127