1 /*
2  * Copyright (c) 2015-2016 The Khronos Group Inc.
3  * Copyright (c) 2015-2016 Valve Corporation
4  * Copyright (c) 2015-2016 LunarG, Inc.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Author: Chia-I Wu <olvaffe@gmail.com>
19  * Author: Chris Forbes <chrisf@ijw.co.nz>
20  * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
21  * Author: Mark Lobodzinski <mark@lunarg.com>
22  * Author: Mike Stroyan <mike@LunarG.com>
23  * Author: Tobin Ehlis <tobine@google.com>
24  * Author: Tony Barbour <tony@LunarG.com>
25  */
26 
27 #include "test_common.h"
28 #include "test_environment.h"
29 
30 #if defined(NDEBUG) && defined(__GNUC__)
31 #define U_ASSERT_ONLY __attribute__((unused))
32 #else
33 #define U_ASSERT_ONLY
34 #endif
35 
36 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
37 
38 namespace vk_testing {
39 
Environment()40 Environment::Environment() : default_dev_(0) {
41     app_.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
42     app_.pApplicationName = "vk_testing";
43     app_.applicationVersion = 1;
44     app_.pEngineName = "vk_testing";
45     app_.engineVersion = 1;
46     app_.apiVersion = VK_API_VERSION_1_0;
47     app_.pNext = NULL;
48 }
49 
parse_args(int argc,char ** argv)50 bool Environment::parse_args(int argc, char **argv) {
51     int i;
52 
53     for (i = 1; i < argc; i++) {
54 #define ARG(name) (strcmp(argv[i], name) == 0)
55 #define ARG_P(name) (i < argc - 1 && ARG(name))
56         if (ARG_P("--gpu")) {
57             default_dev_ = atoi(argv[++i]);
58         } else {
59             break;
60         }
61 #undef ARG
62 #undef ARG_P
63     }
64 
65     if (i < argc) {
66         std::cout << "invalid argument: " << argv[i] << "\n\n"
67                   << "Usage: " << argv[0] << " <options>\n\n"
68                   << "Options:\n"
69                      "  --gpu <n>  Use GPU<n> as the default GPU\n";
70 
71         return false;
72     }
73 
74     return true;
75 }
76 
SetUp()77 void Environment::SetUp() {
78     uint32_t count;
79     VkResult U_ASSERT_ONLY err;
80     VkInstanceCreateInfo inst_info = {};
81     std::vector<VkExtensionProperties> instance_extensions;
82     std::vector<VkExtensionProperties> device_extensions;
83 
84     std::vector<const char *> instance_extension_names;
85     std::vector<const char *> device_extension_names;
86 
87     instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
88     device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
89 #ifdef _WIN32
90     instance_extension_names.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
91 #endif
92 #ifdef VK_USE_PLATFORM_XCB_KHR
93     instance_extension_names.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
94 #endif
95 
96     VkBool32 extFound;
97 
98     instance_extensions = vk_testing::GetGlobalExtensions();
99 
100     for (uint32_t i = 0; i < instance_extension_names.size(); i++) {
101         extFound = 0;
102         for (uint32_t j = 0; j < instance_extensions.size(); j++) {
103             if (!strcmp(instance_extension_names[i], instance_extensions[j].extensionName)) {
104                 extFound = 1;
105             }
106         }
107         ASSERT_EQ(extFound, 1) << "ERROR: Cannot find extension named " << instance_extension_names[i]
108                                << " which is necessary to pass this test";
109     }
110     inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
111     inst_info.pNext = NULL;
112     inst_info.pApplicationInfo = &app_;
113     inst_info.enabledExtensionCount = instance_extension_names.size();
114     inst_info.ppEnabledExtensionNames = (instance_extension_names.size()) ? &instance_extension_names[0] : NULL;
115     inst_info.enabledLayerCount = 0;
116     inst_info.ppEnabledLayerNames = NULL;
117     err = vkCreateInstance(&inst_info, NULL, &inst);
118     ASSERT_EQ(VK_SUCCESS, err);
119     err = vkEnumeratePhysicalDevices(inst, &count, NULL);
120     ASSERT_EQ(VK_SUCCESS, err);
121     ASSERT_LE(count, ARRAY_SIZE(gpus));
122     err = vkEnumeratePhysicalDevices(inst, &count, gpus);
123     ASSERT_EQ(VK_SUCCESS, err);
124     ASSERT_GT(count, default_dev_);
125 
126     vk_testing::PhysicalDevice phys_dev(gpus[0]);
127     device_extensions = phys_dev.extensions();
128 
129     for (uint32_t i = 0; i < device_extension_names.size(); i++) {
130         extFound = 0;
131         for (uint32_t j = 0; j < device_extensions.size(); j++) {
132             if (!strcmp(device_extension_names[i], device_extensions[j].extensionName)) {
133                 extFound = 1;
134             }
135         }
136         ASSERT_EQ(extFound, 1) << "ERROR: Cannot find extension named " << device_extension_names[i]
137                                << " which is necessary to pass this test";
138     }
139 
140     devs_.reserve(count);
141     for (uint32_t i = 0; i < count; i++) {
142         devs_.push_back(new Device(gpus[i]));
143         if (i == default_dev_) {
144             devs_[i]->init(device_extension_names);
145             ASSERT_NE(true, devs_[i]->graphics_queues().empty());
146         }
147     }
148 }
149 
TearDown()150 void Environment::TearDown() {
151     // destroy devices first
152     for (std::vector<Device *>::iterator it = devs_.begin(); it != devs_.end(); it++) delete *it;
153     devs_.clear();
154 
155     if (inst) vkDestroyInstance(inst, NULL);
156 }
157 }  // namespace vk_testing
158