xref: /aosp_15_r20/external/swiftshader/tests/VulkanWrapper/VulkanTester.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2021 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #include "VulkanTester.hpp"
16*03ce13f7SAndroid Build Coastguard Worker #include <cstdlib>
17*03ce13f7SAndroid Build Coastguard Worker #include <filesystem>
18*03ce13f7SAndroid Build Coastguard Worker #include <fstream>
19*03ce13f7SAndroid Build Coastguard Worker #include <iostream>
20*03ce13f7SAndroid Build Coastguard Worker 
21*03ce13f7SAndroid Build Coastguard Worker namespace fs = std::filesystem;
22*03ce13f7SAndroid Build Coastguard Worker 
23*03ce13f7SAndroid Build Coastguard Worker // By default, load SwiftShader via loader
24*03ce13f7SAndroid Build Coastguard Worker #ifndef LOAD_NATIVE_DRIVER
25*03ce13f7SAndroid Build Coastguard Worker #	define LOAD_NATIVE_DRIVER 0
26*03ce13f7SAndroid Build Coastguard Worker #endif
27*03ce13f7SAndroid Build Coastguard Worker 
28*03ce13f7SAndroid Build Coastguard Worker #ifndef LOAD_SWIFTSHADER_DIRECTLY
29*03ce13f7SAndroid Build Coastguard Worker #	define LOAD_SWIFTSHADER_DIRECTLY 0
30*03ce13f7SAndroid Build Coastguard Worker #endif
31*03ce13f7SAndroid Build Coastguard Worker 
32*03ce13f7SAndroid Build Coastguard Worker #if LOAD_NATIVE_DRIVER && LOAD_SWIFTSHADER_DIRECTLY
33*03ce13f7SAndroid Build Coastguard Worker #	error Enable only one of LOAD_NATIVE_DRIVER and LOAD_SWIFTSHADER_DIRECTLY
34*03ce13f7SAndroid Build Coastguard Worker #endif
35*03ce13f7SAndroid Build Coastguard Worker 
36*03ce13f7SAndroid Build Coastguard Worker // By default, enable validation layers in DEBUG builds
37*03ce13f7SAndroid Build Coastguard Worker #if !defined(ENABLE_VALIDATION_LAYERS) && !defined(NDEBUG)
38*03ce13f7SAndroid Build Coastguard Worker #	define ENABLE_VALIDATION_LAYERS 1
39*03ce13f7SAndroid Build Coastguard Worker #endif
40*03ce13f7SAndroid Build Coastguard Worker 
41*03ce13f7SAndroid Build Coastguard Worker #if defined(_WIN32)
42*03ce13f7SAndroid Build Coastguard Worker #	define OS_WINDOWS 1
43*03ce13f7SAndroid Build Coastguard Worker #elif defined(__APPLE__)
44*03ce13f7SAndroid Build Coastguard Worker #	include "dlfcn.h"
45*03ce13f7SAndroid Build Coastguard Worker #	define OS_MAC 1
46*03ce13f7SAndroid Build Coastguard Worker #elif defined(__ANDROID__)
47*03ce13f7SAndroid Build Coastguard Worker #	include "dlfcn.h"
48*03ce13f7SAndroid Build Coastguard Worker #	define OS_ANDROID 1
49*03ce13f7SAndroid Build Coastguard Worker #elif defined(__linux__)
50*03ce13f7SAndroid Build Coastguard Worker #	include "dlfcn.h"
51*03ce13f7SAndroid Build Coastguard Worker #	define OS_LINUX 1
52*03ce13f7SAndroid Build Coastguard Worker #elif defined(__Fuchsia__)
53*03ce13f7SAndroid Build Coastguard Worker #	include <zircon/dlfcn.h>
54*03ce13f7SAndroid Build Coastguard Worker #	define OS_FUCHSIA 1
55*03ce13f7SAndroid Build Coastguard Worker #else
56*03ce13f7SAndroid Build Coastguard Worker #	error Unimplemented platform
57*03ce13f7SAndroid Build Coastguard Worker #endif
58*03ce13f7SAndroid Build Coastguard Worker 
59*03ce13f7SAndroid Build Coastguard Worker // TODO: move to its own header/cpp
60*03ce13f7SAndroid Build Coastguard Worker // Wraps a single environment variable, allowing it to be set
61*03ce13f7SAndroid Build Coastguard Worker // and automatically restored on destruction.
62*03ce13f7SAndroid Build Coastguard Worker class ScopedSetEnvVar
63*03ce13f7SAndroid Build Coastguard Worker {
64*03ce13f7SAndroid Build Coastguard Worker public:
ScopedSetEnvVar(std::string name)65*03ce13f7SAndroid Build Coastguard Worker 	ScopedSetEnvVar(std::string name)
66*03ce13f7SAndroid Build Coastguard Worker 	    : name(name)
67*03ce13f7SAndroid Build Coastguard Worker 	{
68*03ce13f7SAndroid Build Coastguard Worker 		assert(!name.empty());
69*03ce13f7SAndroid Build Coastguard Worker 	}
70*03ce13f7SAndroid Build Coastguard Worker 
ScopedSetEnvVar(std::string name,std::string value)71*03ce13f7SAndroid Build Coastguard Worker 	ScopedSetEnvVar(std::string name, std::string value)
72*03ce13f7SAndroid Build Coastguard Worker 	    : name(name)
73*03ce13f7SAndroid Build Coastguard Worker 	{
74*03ce13f7SAndroid Build Coastguard Worker 		set(value);
75*03ce13f7SAndroid Build Coastguard Worker 	}
76*03ce13f7SAndroid Build Coastguard Worker 
~ScopedSetEnvVar()77*03ce13f7SAndroid Build Coastguard Worker 	~ScopedSetEnvVar()
78*03ce13f7SAndroid Build Coastguard Worker 	{
79*03ce13f7SAndroid Build Coastguard Worker 		restore();
80*03ce13f7SAndroid Build Coastguard Worker 	}
81*03ce13f7SAndroid Build Coastguard Worker 
set(std::string value)82*03ce13f7SAndroid Build Coastguard Worker 	void set(std::string value)
83*03ce13f7SAndroid Build Coastguard Worker 	{
84*03ce13f7SAndroid Build Coastguard Worker 		restore();
85*03ce13f7SAndroid Build Coastguard Worker 		if(auto ov = getEnv(name.data()))
86*03ce13f7SAndroid Build Coastguard Worker 		{
87*03ce13f7SAndroid Build Coastguard Worker 			oldValue = ov;
88*03ce13f7SAndroid Build Coastguard Worker 		}
89*03ce13f7SAndroid Build Coastguard Worker 		putEnv((name + std::string("=") + value).c_str());
90*03ce13f7SAndroid Build Coastguard Worker 	}
91*03ce13f7SAndroid Build Coastguard Worker 
restore()92*03ce13f7SAndroid Build Coastguard Worker 	void restore()
93*03ce13f7SAndroid Build Coastguard Worker 	{
94*03ce13f7SAndroid Build Coastguard Worker 		if(!oldValue.empty())
95*03ce13f7SAndroid Build Coastguard Worker 		{
96*03ce13f7SAndroid Build Coastguard Worker 			putEnv((name + std::string("=") + oldValue).c_str());
97*03ce13f7SAndroid Build Coastguard Worker 			oldValue.clear();
98*03ce13f7SAndroid Build Coastguard Worker 		}
99*03ce13f7SAndroid Build Coastguard Worker 	}
100*03ce13f7SAndroid Build Coastguard Worker 
101*03ce13f7SAndroid Build Coastguard Worker private:
putEnv(const char * env)102*03ce13f7SAndroid Build Coastguard Worker 	void putEnv(const char *env)
103*03ce13f7SAndroid Build Coastguard Worker 	{
104*03ce13f7SAndroid Build Coastguard Worker 		// POSIX putenv needs 'env' to live beyond the call
105*03ce13f7SAndroid Build Coastguard Worker 		envCopy = env;
106*03ce13f7SAndroid Build Coastguard Worker #if OS_WINDOWS
107*03ce13f7SAndroid Build Coastguard Worker 		[[maybe_unused]] auto r = ::_putenv(envCopy.c_str());
108*03ce13f7SAndroid Build Coastguard Worker 		assert(r == 0);
109*03ce13f7SAndroid Build Coastguard Worker #else
110*03ce13f7SAndroid Build Coastguard Worker 		[[maybe_unused]] auto r = ::putenv(const_cast<char *>(envCopy.c_str()));
111*03ce13f7SAndroid Build Coastguard Worker 		assert(r == 0);
112*03ce13f7SAndroid Build Coastguard Worker #endif
113*03ce13f7SAndroid Build Coastguard Worker 	}
114*03ce13f7SAndroid Build Coastguard Worker 
getEnv(const char * name)115*03ce13f7SAndroid Build Coastguard Worker 	const char *getEnv(const char *name)
116*03ce13f7SAndroid Build Coastguard Worker 	{
117*03ce13f7SAndroid Build Coastguard Worker 		return ::getenv(name);
118*03ce13f7SAndroid Build Coastguard Worker 	}
119*03ce13f7SAndroid Build Coastguard Worker 
120*03ce13f7SAndroid Build Coastguard Worker 	std::string name;
121*03ce13f7SAndroid Build Coastguard Worker 	std::string oldValue;
122*03ce13f7SAndroid Build Coastguard Worker 	std::string envCopy;
123*03ce13f7SAndroid Build Coastguard Worker };
124*03ce13f7SAndroid Build Coastguard Worker 
125*03ce13f7SAndroid Build Coastguard Worker // Generates a temporary icd.json file that sets library_path at the input driverPath,
126*03ce13f7SAndroid Build Coastguard Worker // and sets VK_ICD_FILENAMES environment variable to this file, restoring the env var
127*03ce13f7SAndroid Build Coastguard Worker // and deleting the temp file on destruction.
128*03ce13f7SAndroid Build Coastguard Worker class ScopedSetIcdFilenames
129*03ce13f7SAndroid Build Coastguard Worker {
130*03ce13f7SAndroid Build Coastguard Worker public:
131*03ce13f7SAndroid Build Coastguard Worker 	ScopedSetIcdFilenames() = default;
ScopedSetIcdFilenames(const char * driverPath)132*03ce13f7SAndroid Build Coastguard Worker 	ScopedSetIcdFilenames(const char *driverPath)
133*03ce13f7SAndroid Build Coastguard Worker 	{
134*03ce13f7SAndroid Build Coastguard Worker 		std::ofstream fout(icdFileName);
135*03ce13f7SAndroid Build Coastguard Worker 		assert(fout && "Failed to create generated icd file");
136*03ce13f7SAndroid Build Coastguard Worker 		fout << R"raw({ "file_format_version": "1.0.0", "ICD": { "library_path": ")raw" << driverPath << R"raw(", "api_version": "1.0.5" } } )raw";
137*03ce13f7SAndroid Build Coastguard Worker 		fout.close();
138*03ce13f7SAndroid Build Coastguard Worker 
139*03ce13f7SAndroid Build Coastguard Worker 		setEnvVar.set(icdFileName);
140*03ce13f7SAndroid Build Coastguard Worker 	}
141*03ce13f7SAndroid Build Coastguard Worker 
~ScopedSetIcdFilenames()142*03ce13f7SAndroid Build Coastguard Worker 	~ScopedSetIcdFilenames()
143*03ce13f7SAndroid Build Coastguard Worker 	{
144*03ce13f7SAndroid Build Coastguard Worker 		if(fs::exists("vk_swiftshader_generated_icd.json"))
145*03ce13f7SAndroid Build Coastguard Worker 		{
146*03ce13f7SAndroid Build Coastguard Worker 			fs::remove("vk_swiftshader_generated_icd.json");
147*03ce13f7SAndroid Build Coastguard Worker 		}
148*03ce13f7SAndroid Build Coastguard Worker 	}
149*03ce13f7SAndroid Build Coastguard Worker 
150*03ce13f7SAndroid Build Coastguard Worker private:
151*03ce13f7SAndroid Build Coastguard Worker 	static constexpr const char *icdFileName = "vk_swiftshader_generated_icd.json";
152*03ce13f7SAndroid Build Coastguard Worker 	ScopedSetEnvVar setEnvVar{ "VK_ICD_FILENAMES" };
153*03ce13f7SAndroid Build Coastguard Worker };
154*03ce13f7SAndroid Build Coastguard Worker 
155*03ce13f7SAndroid Build Coastguard Worker namespace {
156*03ce13f7SAndroid Build Coastguard Worker 
getDriverPaths()157*03ce13f7SAndroid Build Coastguard Worker std::vector<const char *> getDriverPaths()
158*03ce13f7SAndroid Build Coastguard Worker {
159*03ce13f7SAndroid Build Coastguard Worker #if OS_WINDOWS
160*03ce13f7SAndroid Build Coastguard Worker #	if !defined(STANDALONE)
161*03ce13f7SAndroid Build Coastguard Worker 	// The DLL is delay loaded (see BUILD.gn), so we can load
162*03ce13f7SAndroid Build Coastguard Worker 	// the correct ones from Chrome's swiftshader subdirectory.
163*03ce13f7SAndroid Build Coastguard Worker 	// HMODULE libvulkan = LoadLibraryA("swiftshader\\libvulkan.dll");
164*03ce13f7SAndroid Build Coastguard Worker 	// EXPECT_NE((HMODULE)NULL, libvulkan);
165*03ce13f7SAndroid Build Coastguard Worker 	// return true;
166*03ce13f7SAndroid Build Coastguard Worker #		error TODO: !STANDALONE
167*03ce13f7SAndroid Build Coastguard Worker #	elif defined(NDEBUG)
168*03ce13f7SAndroid Build Coastguard Worker #		if defined(_WIN64)
169*03ce13f7SAndroid Build Coastguard Worker 	return { "./build/Release_x64/vk_swiftshader.dll",
170*03ce13f7SAndroid Build Coastguard Worker 		     "./build/Release/vk_swiftshader.dll",
171*03ce13f7SAndroid Build Coastguard Worker 		     "./build/RelWithDebInfo/vk_swiftshader.dll",
172*03ce13f7SAndroid Build Coastguard Worker 		     "./build/vk_swiftshader.dll",
173*03ce13f7SAndroid Build Coastguard Worker 		     "./vk_swiftshader.dll" };
174*03ce13f7SAndroid Build Coastguard Worker #		else
175*03ce13f7SAndroid Build Coastguard Worker 	return { "./build/Release_Win32/vk_swiftshader.dll",
176*03ce13f7SAndroid Build Coastguard Worker 		     "./build/Release/vk_swiftshader.dll",
177*03ce13f7SAndroid Build Coastguard Worker 		     "./build/RelWithDebInfo/vk_swiftshader.dll",
178*03ce13f7SAndroid Build Coastguard Worker 		     "./build/vk_swiftshader.dll",
179*03ce13f7SAndroid Build Coastguard Worker 		     "./vk_swiftshader.dll" };
180*03ce13f7SAndroid Build Coastguard Worker #		endif
181*03ce13f7SAndroid Build Coastguard Worker #	else
182*03ce13f7SAndroid Build Coastguard Worker #		if defined(_WIN64)
183*03ce13f7SAndroid Build Coastguard Worker 	return { "./build/Debug_x64/vk_swiftshader.dll",
184*03ce13f7SAndroid Build Coastguard Worker 		     "./build/Debug/vk_swiftshader.dll",
185*03ce13f7SAndroid Build Coastguard Worker 		     "./build/vk_swiftshader.dll",
186*03ce13f7SAndroid Build Coastguard Worker 		     "./vk_swiftshader.dll" };
187*03ce13f7SAndroid Build Coastguard Worker #		else
188*03ce13f7SAndroid Build Coastguard Worker 	return { "./build/Debug_Win32/vk_swiftshader.dll",
189*03ce13f7SAndroid Build Coastguard Worker 		     "./build/Debug/vk_swiftshader.dll",
190*03ce13f7SAndroid Build Coastguard Worker 		     "./build/vk_swiftshader.dll",
191*03ce13f7SAndroid Build Coastguard Worker 		     "./vk_swiftshader.dll" };
192*03ce13f7SAndroid Build Coastguard Worker #		endif
193*03ce13f7SAndroid Build Coastguard Worker #	endif
194*03ce13f7SAndroid Build Coastguard Worker #elif OS_MAC
195*03ce13f7SAndroid Build Coastguard Worker 	return { "./build/Darwin/libvk_swiftshader.dylib",
196*03ce13f7SAndroid Build Coastguard Worker 		     "swiftshader/libvk_swiftshader.dylib",
197*03ce13f7SAndroid Build Coastguard Worker 		     "libvk_swiftshader.dylib" };
198*03ce13f7SAndroid Build Coastguard Worker #elif OS_LINUX
199*03ce13f7SAndroid Build Coastguard Worker 	return { "./build/Linux/libvk_swiftshader.so",
200*03ce13f7SAndroid Build Coastguard Worker 		     "swiftshader/libvk_swiftshader.so",
201*03ce13f7SAndroid Build Coastguard Worker 		     "./libvk_swiftshader.so",
202*03ce13f7SAndroid Build Coastguard Worker 		     "libvk_swiftshader.so" };
203*03ce13f7SAndroid Build Coastguard Worker #elif OS_ANDROID || OS_FUCHSIA
204*03ce13f7SAndroid Build Coastguard Worker 	return
205*03ce13f7SAndroid Build Coastguard Worker 	{
206*03ce13f7SAndroid Build Coastguard Worker 		"libvk_swiftshader.so"
207*03ce13f7SAndroid Build Coastguard Worker 	}
208*03ce13f7SAndroid Build Coastguard Worker #else
209*03ce13f7SAndroid Build Coastguard Worker #	error Unimplemented platform
210*03ce13f7SAndroid Build Coastguard Worker 	return {};
211*03ce13f7SAndroid Build Coastguard Worker #endif
212*03ce13f7SAndroid Build Coastguard Worker }
213*03ce13f7SAndroid Build Coastguard Worker 
fileExists(const char * path)214*03ce13f7SAndroid Build Coastguard Worker bool fileExists(const char *path)
215*03ce13f7SAndroid Build Coastguard Worker {
216*03ce13f7SAndroid Build Coastguard Worker 	std::ifstream f(path);
217*03ce13f7SAndroid Build Coastguard Worker 	return f.good();
218*03ce13f7SAndroid Build Coastguard Worker }
219*03ce13f7SAndroid Build Coastguard Worker 
findDriverPath()220*03ce13f7SAndroid Build Coastguard Worker std::string findDriverPath()
221*03ce13f7SAndroid Build Coastguard Worker {
222*03ce13f7SAndroid Build Coastguard Worker 	for(auto &path : getDriverPaths())
223*03ce13f7SAndroid Build Coastguard Worker 	{
224*03ce13f7SAndroid Build Coastguard Worker 		if(fileExists(path))
225*03ce13f7SAndroid Build Coastguard Worker 			return path;
226*03ce13f7SAndroid Build Coastguard Worker 	}
227*03ce13f7SAndroid Build Coastguard Worker 
228*03ce13f7SAndroid Build Coastguard Worker #if(OS_LINUX || OS_ANDROID || OS_FUCHSIA)
229*03ce13f7SAndroid Build Coastguard Worker 	// On Linux-based OSes, the lib path may be resolved by dlopen
230*03ce13f7SAndroid Build Coastguard Worker 	for(auto &path : getDriverPaths())
231*03ce13f7SAndroid Build Coastguard Worker 	{
232*03ce13f7SAndroid Build Coastguard Worker 		auto lib = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
233*03ce13f7SAndroid Build Coastguard Worker 		if(lib)
234*03ce13f7SAndroid Build Coastguard Worker 		{
235*03ce13f7SAndroid Build Coastguard Worker 			char libPath[2048] = { '\0' };
236*03ce13f7SAndroid Build Coastguard Worker 			dlinfo(lib, RTLD_DI_ORIGIN, libPath);
237*03ce13f7SAndroid Build Coastguard Worker 			dlclose(lib);
238*03ce13f7SAndroid Build Coastguard Worker 			return std::string{ libPath } + "/" + path;
239*03ce13f7SAndroid Build Coastguard Worker 		}
240*03ce13f7SAndroid Build Coastguard Worker 	}
241*03ce13f7SAndroid Build Coastguard Worker #endif
242*03ce13f7SAndroid Build Coastguard Worker 
243*03ce13f7SAndroid Build Coastguard Worker 	return {};
244*03ce13f7SAndroid Build Coastguard Worker }
245*03ce13f7SAndroid Build Coastguard Worker 
246*03ce13f7SAndroid Build Coastguard Worker }  // namespace
247*03ce13f7SAndroid Build Coastguard Worker 
248*03ce13f7SAndroid Build Coastguard Worker VulkanTester::VulkanTester() = default;
249*03ce13f7SAndroid Build Coastguard Worker 
~VulkanTester()250*03ce13f7SAndroid Build Coastguard Worker VulkanTester::~VulkanTester()
251*03ce13f7SAndroid Build Coastguard Worker {
252*03ce13f7SAndroid Build Coastguard Worker 	device.waitIdle();
253*03ce13f7SAndroid Build Coastguard Worker 	device.destroy(nullptr);
254*03ce13f7SAndroid Build Coastguard Worker 	if(debugReport) instance.destroy(debugReport);
255*03ce13f7SAndroid Build Coastguard Worker 	instance.destroy(nullptr);
256*03ce13f7SAndroid Build Coastguard Worker }
257*03ce13f7SAndroid Build Coastguard Worker 
initialize()258*03ce13f7SAndroid Build Coastguard Worker void VulkanTester::initialize()
259*03ce13f7SAndroid Build Coastguard Worker {
260*03ce13f7SAndroid Build Coastguard Worker 	dl = loadDriver();
261*03ce13f7SAndroid Build Coastguard Worker 	assert(dl && dl->success());
262*03ce13f7SAndroid Build Coastguard Worker 
263*03ce13f7SAndroid Build Coastguard Worker 	PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = dl->getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
264*03ce13f7SAndroid Build Coastguard Worker 	VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);
265*03ce13f7SAndroid Build Coastguard Worker 
266*03ce13f7SAndroid Build Coastguard Worker 	vk::InstanceCreateInfo instanceCreateInfo;
267*03ce13f7SAndroid Build Coastguard Worker 	std::vector<const char *> extensionNames
268*03ce13f7SAndroid Build Coastguard Worker 	{
269*03ce13f7SAndroid Build Coastguard Worker 		VK_KHR_SURFACE_EXTENSION_NAME,
270*03ce13f7SAndroid Build Coastguard Worker #if USE_HEADLESS_SURFACE
271*03ce13f7SAndroid Build Coastguard Worker 		    VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME,
272*03ce13f7SAndroid Build Coastguard Worker #endif
273*03ce13f7SAndroid Build Coastguard Worker #if defined(VK_USE_PLATFORM_WIN32_KHR)
274*03ce13f7SAndroid Build Coastguard Worker 		    VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
275*03ce13f7SAndroid Build Coastguard Worker #endif
276*03ce13f7SAndroid Build Coastguard Worker 	};
277*03ce13f7SAndroid Build Coastguard Worker #if ENABLE_VALIDATION_LAYERS
278*03ce13f7SAndroid Build Coastguard Worker 	extensionNames.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
279*03ce13f7SAndroid Build Coastguard Worker #endif
280*03ce13f7SAndroid Build Coastguard Worker 
281*03ce13f7SAndroid Build Coastguard Worker 	std::vector<const char *> layerNames;
282*03ce13f7SAndroid Build Coastguard Worker #if ENABLE_VALIDATION_LAYERS
283*03ce13f7SAndroid Build Coastguard Worker 	auto addLayerIfAvailable = [](std::vector<const char *> &layers, const char *layer) {
284*03ce13f7SAndroid Build Coastguard Worker 		static auto layerProperties = vk::enumerateInstanceLayerProperties();
285*03ce13f7SAndroid Build Coastguard Worker 		if(std::find_if(layerProperties.begin(), layerProperties.end(), [layer](auto &lp) {
286*03ce13f7SAndroid Build Coastguard Worker 			   return strcmp(layer, lp.layerName) == 0;
287*03ce13f7SAndroid Build Coastguard Worker 		   }) != layerProperties.end())
288*03ce13f7SAndroid Build Coastguard Worker 		{
289*03ce13f7SAndroid Build Coastguard Worker 			// std::cout << "Enabled layer: " << layer << std::endl;
290*03ce13f7SAndroid Build Coastguard Worker 			layers.push_back(layer);
291*03ce13f7SAndroid Build Coastguard Worker 		}
292*03ce13f7SAndroid Build Coastguard Worker 	};
293*03ce13f7SAndroid Build Coastguard Worker 
294*03ce13f7SAndroid Build Coastguard Worker 	addLayerIfAvailable(layerNames, "VK_LAYER_KHRONOS_validation");
295*03ce13f7SAndroid Build Coastguard Worker 	addLayerIfAvailable(layerNames, "VK_LAYER_LUNARG_standard_validation");
296*03ce13f7SAndroid Build Coastguard Worker #endif
297*03ce13f7SAndroid Build Coastguard Worker 
298*03ce13f7SAndroid Build Coastguard Worker 	instanceCreateInfo.ppEnabledExtensionNames = extensionNames.data();
299*03ce13f7SAndroid Build Coastguard Worker 	instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(extensionNames.size());
300*03ce13f7SAndroid Build Coastguard Worker 	instanceCreateInfo.ppEnabledLayerNames = layerNames.data();
301*03ce13f7SAndroid Build Coastguard Worker 	instanceCreateInfo.enabledLayerCount = static_cast<uint32_t>(layerNames.size());
302*03ce13f7SAndroid Build Coastguard Worker 
303*03ce13f7SAndroid Build Coastguard Worker 	instance = vk::createInstance(instanceCreateInfo, nullptr);
304*03ce13f7SAndroid Build Coastguard Worker 	VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);
305*03ce13f7SAndroid Build Coastguard Worker 
306*03ce13f7SAndroid Build Coastguard Worker #if ENABLE_VALIDATION_LAYERS
307*03ce13f7SAndroid Build Coastguard Worker 	if(VULKAN_HPP_DEFAULT_DISPATCHER.vkCreateDebugUtilsMessengerEXT)
308*03ce13f7SAndroid Build Coastguard Worker 	{
309*03ce13f7SAndroid Build Coastguard Worker 		vk::DebugUtilsMessengerCreateInfoEXT debugInfo;
310*03ce13f7SAndroid Build Coastguard Worker 		debugInfo.messageSeverity =
311*03ce13f7SAndroid Build Coastguard Worker 		    // vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
312*03ce13f7SAndroid Build Coastguard Worker 		    vk::DebugUtilsMessageSeverityFlagBitsEXT::eError |
313*03ce13f7SAndroid Build Coastguard Worker 		    vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning;
314*03ce13f7SAndroid Build Coastguard Worker 
315*03ce13f7SAndroid Build Coastguard Worker 		debugInfo.messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
316*03ce13f7SAndroid Build Coastguard Worker 		                        vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
317*03ce13f7SAndroid Build Coastguard Worker 		                        vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance;
318*03ce13f7SAndroid Build Coastguard Worker 
319*03ce13f7SAndroid Build Coastguard Worker 		PFN_vkDebugUtilsMessengerCallbackEXT debugInfoCallback =
320*03ce13f7SAndroid Build Coastguard Worker 		    [](
321*03ce13f7SAndroid Build Coastguard Worker 		        VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
322*03ce13f7SAndroid Build Coastguard Worker 		        VkDebugUtilsMessageTypeFlagsEXT messageTypes,
323*03ce13f7SAndroid Build Coastguard Worker 		        const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
324*03ce13f7SAndroid Build Coastguard Worker 		        void *pUserData) -> VkBool32 {
325*03ce13f7SAndroid Build Coastguard Worker 			// assert(false);
326*03ce13f7SAndroid Build Coastguard Worker 			std::cerr << "[DebugInfoCallback] " << pCallbackData->pMessage << std::endl;
327*03ce13f7SAndroid Build Coastguard Worker 			return VK_FALSE;
328*03ce13f7SAndroid Build Coastguard Worker 		};
329*03ce13f7SAndroid Build Coastguard Worker 
330*03ce13f7SAndroid Build Coastguard Worker 		debugInfo.pfnUserCallback = debugInfoCallback;
331*03ce13f7SAndroid Build Coastguard Worker 		debugReport = instance.createDebugUtilsMessengerEXT(debugInfo);
332*03ce13f7SAndroid Build Coastguard Worker 	}
333*03ce13f7SAndroid Build Coastguard Worker #endif
334*03ce13f7SAndroid Build Coastguard Worker 
335*03ce13f7SAndroid Build Coastguard Worker 	std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
336*03ce13f7SAndroid Build Coastguard Worker 	assert(!physicalDevices.empty());
337*03ce13f7SAndroid Build Coastguard Worker 	physicalDevice = physicalDevices[0];
338*03ce13f7SAndroid Build Coastguard Worker 
339*03ce13f7SAndroid Build Coastguard Worker 	const float defaultQueuePriority = 0.0f;
340*03ce13f7SAndroid Build Coastguard Worker 	vk::DeviceQueueCreateInfo queueCreateInfo;
341*03ce13f7SAndroid Build Coastguard Worker 	queueCreateInfo.queueFamilyIndex = queueFamilyIndex;
342*03ce13f7SAndroid Build Coastguard Worker 	queueCreateInfo.queueCount = 1;
343*03ce13f7SAndroid Build Coastguard Worker 	queueCreateInfo.pQueuePriorities = &defaultQueuePriority;
344*03ce13f7SAndroid Build Coastguard Worker 
345*03ce13f7SAndroid Build Coastguard Worker 	std::vector<const char *> deviceExtensions = {
346*03ce13f7SAndroid Build Coastguard Worker 		VK_KHR_SWAPCHAIN_EXTENSION_NAME,
347*03ce13f7SAndroid Build Coastguard Worker 	};
348*03ce13f7SAndroid Build Coastguard Worker 
349*03ce13f7SAndroid Build Coastguard Worker 	vk::DeviceCreateInfo deviceCreateInfo;
350*03ce13f7SAndroid Build Coastguard Worker 	deviceCreateInfo.queueCreateInfoCount = 1;
351*03ce13f7SAndroid Build Coastguard Worker 	deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
352*03ce13f7SAndroid Build Coastguard Worker 	deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
353*03ce13f7SAndroid Build Coastguard Worker 	deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
354*03ce13f7SAndroid Build Coastguard Worker 
355*03ce13f7SAndroid Build Coastguard Worker 	device = physicalDevice.createDevice(deviceCreateInfo, nullptr);
356*03ce13f7SAndroid Build Coastguard Worker 
357*03ce13f7SAndroid Build Coastguard Worker 	queue = device.getQueue(queueFamilyIndex, 0);
358*03ce13f7SAndroid Build Coastguard Worker }
359*03ce13f7SAndroid Build Coastguard Worker 
loadDriver()360*03ce13f7SAndroid Build Coastguard Worker std::unique_ptr<vk::DynamicLoader> VulkanTester::loadDriver()
361*03ce13f7SAndroid Build Coastguard Worker {
362*03ce13f7SAndroid Build Coastguard Worker 	if(LOAD_NATIVE_DRIVER)
363*03ce13f7SAndroid Build Coastguard Worker 	{
364*03ce13f7SAndroid Build Coastguard Worker 		return std::make_unique<vk::DynamicLoader>();
365*03ce13f7SAndroid Build Coastguard Worker 	}
366*03ce13f7SAndroid Build Coastguard Worker 
367*03ce13f7SAndroid Build Coastguard Worker 	auto driverPath = findDriverPath();
368*03ce13f7SAndroid Build Coastguard Worker 	assert(!driverPath.empty());
369*03ce13f7SAndroid Build Coastguard Worker 
370*03ce13f7SAndroid Build Coastguard Worker 	if(LOAD_SWIFTSHADER_DIRECTLY)
371*03ce13f7SAndroid Build Coastguard Worker 	{
372*03ce13f7SAndroid Build Coastguard Worker 		return std::make_unique<vk::DynamicLoader>(driverPath);
373*03ce13f7SAndroid Build Coastguard Worker 	}
374*03ce13f7SAndroid Build Coastguard Worker 
375*03ce13f7SAndroid Build Coastguard Worker 	// Load SwiftShader via loader
376*03ce13f7SAndroid Build Coastguard Worker 
377*03ce13f7SAndroid Build Coastguard Worker 	// Set VK_ICD_FILENAMES env var so it gets picked up by the loading of the ICD driver
378*03ce13f7SAndroid Build Coastguard Worker 	setIcdFilenames = std::make_unique<ScopedSetIcdFilenames>(driverPath.c_str());
379*03ce13f7SAndroid Build Coastguard Worker 
380*03ce13f7SAndroid Build Coastguard Worker 	std::unique_ptr<vk::DynamicLoader> dl;
381*03ce13f7SAndroid Build Coastguard Worker #ifndef VULKAN_HPP_NO_EXCEPTIONS
382*03ce13f7SAndroid Build Coastguard Worker 	try
383*03ce13f7SAndroid Build Coastguard Worker 	{
384*03ce13f7SAndroid Build Coastguard Worker 		dl = std::make_unique<vk::DynamicLoader>();
385*03ce13f7SAndroid Build Coastguard Worker 	}
386*03ce13f7SAndroid Build Coastguard Worker 	catch(std::exception &ex)
387*03ce13f7SAndroid Build Coastguard Worker 	{
388*03ce13f7SAndroid Build Coastguard Worker 		std::cerr << "vk::DynamicLoader exception: " << ex.what() << std::endl;
389*03ce13f7SAndroid Build Coastguard Worker 		std::cerr << "Falling back to loading SwiftShader directly (i.e. no validation layers)" << std::endl;
390*03ce13f7SAndroid Build Coastguard Worker 		dl = std::make_unique<vk::DynamicLoader>(driverPath);
391*03ce13f7SAndroid Build Coastguard Worker 	}
392*03ce13f7SAndroid Build Coastguard Worker #else
393*03ce13f7SAndroid Build Coastguard Worker 	dl = std::make_unique<vk::DynamicLoader>();
394*03ce13f7SAndroid Build Coastguard Worker #endif
395*03ce13f7SAndroid Build Coastguard Worker 
396*03ce13f7SAndroid Build Coastguard Worker 	return dl;
397*03ce13f7SAndroid Build Coastguard Worker }
398