|
32 | 32 | #include <iostream> |
33 | 33 | #include <memory> |
34 | 34 | #include <map> |
| 35 | +#include <functional> |
| 36 | +#include <string> |
35 | 37 |
|
36 | 38 | #if defined(VK_USE_PLATFORM_XLIB_KHR) |
37 | 39 | #include "xlib_loader.h" |
@@ -228,91 +230,71 @@ enum class WsiPlatform { |
228 | 230 | invalid, // Sentinel just to indicate invalid user input |
229 | 231 | }; |
230 | 232 |
|
231 | | -WsiPlatform wsi_from_string(std::string const &str) { |
232 | | - if (str == "auto") return WsiPlatform::auto_; |
| 233 | +constexpr std::pair<const char*, WsiPlatform> platform_data_[] = { |
| 234 | + {"auto", WsiPlatform::auto_}, |
233 | 235 | #if defined(VK_USE_PLATFORM_WIN32_KHR) |
234 | | - if (str == "win32") return WsiPlatform::win32; |
| 236 | + {"win32", WsiPlatform::win32}, |
235 | 237 | #endif |
236 | 238 | #if defined(VK_USE_PLATFORM_METAL_EXT) |
237 | | - if (str == "metal") return WsiPlatform::metal; |
| 239 | + {"metal", WsiPlatform::metal}, |
238 | 240 | #endif |
239 | 241 | #if defined(VK_USE_PLATFORM_ANDROID_KHR) |
240 | | - if (str == "android") return WsiPlatform::android; |
| 242 | + {"android", WsiPlatform::android}, |
241 | 243 | #endif |
242 | 244 | #if defined(VK_USE_PLATFORM_SCREEN_QNX) |
243 | | - if (str == "qnx") return WsiPlatform::qnx; |
| 245 | + {"qnx", WsiPlatform::qnx}, |
244 | 246 | #endif |
245 | 247 | #if defined(VK_USE_PLATFORM_XCB_KHR) |
246 | | - if (str == "xcb") return WsiPlatform::xcb; |
| 248 | + {"xcb", WsiPlatform::xcb}, |
247 | 249 | #endif |
248 | 250 | #if defined(VK_USE_PLATFORM_XLIB_KHR) |
249 | | - if (str == "xlib") return WsiPlatform::xlib; |
| 251 | + {"xlib", WsiPlatform::xlib}, |
250 | 252 | #endif |
251 | 253 | #if defined(VK_USE_PLATFORM_WAYLAND_KHR) |
252 | | - if (str == "wayland") return WsiPlatform::wayland; |
| 254 | + {"wayland", WsiPlatform::wayland}, |
253 | 255 | #endif |
254 | 256 | #if defined(VK_USE_PLATFORM_DIRECTFB_EXT) |
255 | | - if (str == "directfb") return WsiPlatform::directfb; |
| 257 | + {"directfb", WsiPlatform::directfb}, |
256 | 258 | #endif |
257 | 259 | #if defined(VK_USE_PLATFORM_DISPLAY_KHR) |
258 | | - if (str == "display") return WsiPlatform::display; |
| 260 | + {"display", WsiPlatform::display}, |
259 | 261 | #endif |
260 | 262 | #if defined(VK_USE_PLATFORM_FUCHSIA) |
261 | | - if (str == "fuchsia_display") return WsiPlatform::fuchsia_display; |
262 | | - if (str == "fuchsia_scenic") return WsiPlatform::fuchsia_scenic; |
| 263 | + {"fuchsia_display", WsiPlatform::fuchsia_display}, |
| 264 | + {"fuchsia_scenic", WsiPlatform::fuchsia_scenic}, |
263 | 265 | #endif |
| 266 | +}; |
| 267 | + |
| 268 | +template<typename T, size_t N> |
| 269 | +constexpr auto construct_array(const T (&data)[N]) { |
| 270 | + std::array<T, N> res{}; |
| 271 | + |
| 272 | + for (size_t i = 0; i < N; ++i) { |
| 273 | + res[i].first = data[i].first; |
| 274 | + res[i].second = data[i].second; |
| 275 | + } |
| 276 | + |
| 277 | + return res; |
| 278 | +} |
| 279 | + |
| 280 | +constexpr auto platform_data = construct_array(platform_data_); |
| 281 | + |
| 282 | +WsiPlatform wsi_from_string(std::string const &str) { |
| 283 | + for (size_t i = 0; i < sizeof(platform_data)/sizeof(platform_data[0]); i++) { |
| 284 | + if (platform_data[i].first == str) { |
| 285 | + return platform_data[i].second; |
| 286 | + } |
| 287 | + } |
264 | 288 | return WsiPlatform::invalid; |
265 | 289 | }; |
266 | 290 |
|
267 | 291 | const char *wsi_to_string(WsiPlatform wsi_platform) { |
268 | | - switch (wsi_platform) { |
269 | | - case (WsiPlatform::auto_): |
270 | | - return "auto"; |
271 | | -#if defined(VK_USE_PLATFORM_WIN32_KHR) |
272 | | - case (WsiPlatform::win32): |
273 | | - return "win32"; |
274 | | -#endif |
275 | | -#if defined(VK_USE_PLATFORM_METAL_EXT) |
276 | | - case (WsiPlatform::metal): |
277 | | - return "metal"; |
278 | | -#endif |
279 | | -#if defined(VK_USE_PLATFORM_ANDROID_KHR) |
280 | | - case (WsiPlatform::android): |
281 | | - return "android"; |
282 | | -#endif |
283 | | -#if defined(VK_USE_PLATFORM_SCREEN_QNX) |
284 | | - case (WsiPlatform::qnx): |
285 | | - return "qnx"; |
286 | | -#endif |
287 | | -#if defined(VK_USE_PLATFORM_XCB_KHR) |
288 | | - case (WsiPlatform::xcb): |
289 | | - return "xcb"; |
290 | | -#endif |
291 | | -#if defined(VK_USE_PLATFORM_XLIB_KHR) |
292 | | - case (WsiPlatform::xlib): |
293 | | - return "xlib"; |
294 | | -#endif |
295 | | -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) |
296 | | - case (WsiPlatform::wayland): |
297 | | - return "wayland"; |
298 | | -#endif |
299 | | -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) |
300 | | - case (WsiPlatform::directfb): |
301 | | - return "directfb"; |
302 | | -#endif |
303 | | -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) |
304 | | - case (WsiPlatform::display): |
305 | | - return "display"; |
306 | | -#endif |
307 | | -#if defined(VK_USE_PLATFORM_FUCHSIA) |
308 | | - case (WsiPlatform::fuchsia_display): |
309 | | - return "fuchsia_display"; |
310 | | - case (WsiPlatform::fuchsia_scenic): |
311 | | - return "fuchsia_scenic"; |
312 | | -#endif |
313 | | - default: |
314 | | - return "unknown"; |
| 292 | + for (size_t i = 0; i < sizeof(platform_data)/sizeof(platform_data[0]); i++) { |
| 293 | + if (platform_data[i].second == wsi_platform) { |
| 294 | + return platform_data[i].first; |
| 295 | + } |
315 | 296 | } |
| 297 | + return "unknown"; |
316 | 298 | }; |
317 | 299 |
|
318 | 300 | struct SwapchainImageResources { |
@@ -1118,47 +1100,13 @@ void Demo::init(int argc, char **argv) { |
1118 | 1100 | } |
1119 | 1101 |
|
1120 | 1102 | std::string wsi_platforms; |
1121 | | -#if defined(VK_USE_PLATFORM_XCB_KHR) |
1122 | | - wsi_platforms.append("xcb"); |
1123 | | -#endif |
1124 | | -#if defined(VK_USE_PLATFORM_XLIB_KHR) |
1125 | | - if (!wsi_platforms.empty()) wsi_platforms.append("|"); |
1126 | | - wsi_platforms.append("xlib"); |
1127 | | -#endif |
1128 | | -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) |
1129 | | - if (!wsi_platforms.empty()) wsi_platforms.append("|"); |
1130 | | - wsi_platforms.append("wayland"); |
1131 | | -#endif |
1132 | | -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) |
1133 | | - if (!wsi_platforms.empty()) wsi_platforms.append("|"); |
1134 | | - wsi_platforms.append("directfb"); |
1135 | | -#endif |
1136 | | -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) |
1137 | | - if (!wsi_platforms.empty()) wsi_platforms.append("|"); |
1138 | | - wsi_platforms.append("display"); |
1139 | | -#endif |
1140 | | -#if defined(VK_USE_PLATFORM_METAL_EXT) |
1141 | | - if (!wsi_platforms.empty()) wsi_platforms.append("|"); |
1142 | | - wsi_platforms.append("metal"); |
1143 | | -#endif |
1144 | | -#if defined(VK_USE_PLATFORM_WIN32_KHR) |
1145 | | - if (!wsi_platforms.empty()) wsi_platforms.append("|"); |
1146 | | - wsi_platforms.append("win32"); |
1147 | | -#endif |
1148 | | -#if defined(VK_USE_PLATFORM_ANDROID_KHR) |
1149 | | - if (!wsi_platforms.empty()) wsi_platforms.append("|"); |
1150 | | - wsi_platforms.append("android"); |
1151 | | -#endif |
1152 | | -#if defined(VK_USE_PLATFORM_SCREEN_QNX) |
1153 | | - if (!wsi_platforms.empty()) wsi_platforms.append("|"); |
1154 | | - wsi_platforms.append("qnx"); |
1155 | | -#endif |
1156 | | -#if defined(VK_USE_PLATFORM_FUCHSIA) |
1157 | | - if (!wsi_platforms.empty()) wsi_platforms.append("|"); |
1158 | | - wsi_platforms.append("fuchsia_display"); |
1159 | | - if (!wsi_platforms.empty()) wsi_platforms.append("|"); |
1160 | | - wsi_platforms.append("fuchsia_scenic"); |
1161 | | -#endif |
| 1103 | + |
| 1104 | + wsi_platforms.append(platform_data[0].first); |
| 1105 | + for (size_t index = 1; index < sizeof(platform_data)/sizeof(platform_data[0]); ++index) { |
| 1106 | + wsi_platforms.append("|"); |
| 1107 | + wsi_platforms.append(platform_data[index].first); |
| 1108 | + } |
| 1109 | + |
1162 | 1110 | std::stringstream usage; |
1163 | 1111 | usage << "Usage:\n " << APP_SHORT_NAME << "\t[--use_staging] [--validate]\n" |
1164 | 1112 | << "\t[--break] [--c <framecount>] [--suppress_popups]\n" |
@@ -4094,57 +4042,75 @@ void Demo::execute<WsiPlatform::display>() { |
4094 | 4042 | run<WsiPlatform::display>(); |
4095 | 4043 | } |
4096 | 4044 |
|
| 4045 | +template<WsiPlatform platform> |
| 4046 | +auto get_dispatcher_element(Demo& demo) { |
| 4047 | + return std::pair<WsiPlatform, std::function<void()>>{ platform, [&demo](){demo.execute<platform>();} }; |
| 4048 | +} |
| 4049 | + |
| 4050 | +constexpr auto get_count_of_platform_run_from_main() { |
| 4051 | + size_t count = 0; |
| 4052 | + for (auto& data : platform_data) { |
| 4053 | + if (data.second == WsiPlatform::xcb || |
| 4054 | + data.second == WsiPlatform::xlib || |
| 4055 | + data.second == WsiPlatform::wayland || |
| 4056 | + data.second == WsiPlatform::directfb || |
| 4057 | + data.second == WsiPlatform::display || |
| 4058 | + data.second == WsiPlatform::qnx || |
| 4059 | + data.second == WsiPlatform::fuchsia_display || |
| 4060 | + data.second == WsiPlatform::fuchsia_scenic) { |
| 4061 | + count++; |
| 4062 | + } |
| 4063 | + } |
| 4064 | + return count; |
| 4065 | +} |
| 4066 | + |
| 4067 | +constexpr auto get_platform_run_from_main() { |
| 4068 | + std::array<WsiPlatform, get_count_of_platform_run_from_main()> platform_run_from_main{}; |
| 4069 | + int i = 0; |
| 4070 | + for (auto& data : platform_data) { |
| 4071 | + if (data.second == WsiPlatform::xcb || |
| 4072 | + data.second == WsiPlatform::xlib || |
| 4073 | + data.second == WsiPlatform::wayland || |
| 4074 | + data.second == WsiPlatform::directfb || |
| 4075 | + data.second == WsiPlatform::display || |
| 4076 | + data.second == WsiPlatform::qnx || |
| 4077 | + data.second == WsiPlatform::fuchsia_display || |
| 4078 | + data.second == WsiPlatform::fuchsia_scenic) { |
| 4079 | + platform_run_from_main[i++] = data.second; |
| 4080 | + } |
| 4081 | + } |
| 4082 | + return platform_run_from_main; |
| 4083 | +} |
| 4084 | + |
| 4085 | +constexpr auto platform_run_from_main = get_platform_run_from_main(); |
| 4086 | + |
| 4087 | +template<size_t i=0> |
| 4088 | +auto construct_dispatcher(std::map<WsiPlatform, std::function<void()>>& map, Demo& demo) { |
| 4089 | + map.emplace( |
| 4090 | + get_dispatcher_element<platform_run_from_main[i]>(demo) |
| 4091 | + ); |
| 4092 | + construct_dispatcher<i+1>(map, demo); |
| 4093 | +} |
| 4094 | +template<> |
| 4095 | +auto construct_dispatcher<platform_run_from_main.size()>(std::map<WsiPlatform, std::function<void()>>& map, Demo& demo) { |
| 4096 | +} |
| 4097 | + |
4097 | 4098 | int main(int argc, char **argv) { |
4098 | 4099 | Demo demo; |
4099 | 4100 |
|
4100 | 4101 | demo.init(argc, argv); |
4101 | 4102 |
|
4102 | | - switch (demo.wsi_platform) { |
4103 | | - default: |
4104 | | - case (WsiPlatform::auto_): |
4105 | | - fprintf(stderr, |
4106 | | - "WSI platform should have already been set, indicating a bug. Please set a WSI platform manually with " |
4107 | | - "--wsi\n"); |
4108 | | - exit(1); |
4109 | | - break; |
4110 | | -#if defined(VK_USE_PLATFORM_XCB_KHR) |
4111 | | - case (WsiPlatform::xcb): |
4112 | | - demo.execute<WsiPlatform::xcb>(); |
4113 | | - break; |
4114 | | -#endif |
4115 | | -#if defined(VK_USE_PLATFORM_XLIB_KHR) |
4116 | | - case (WsiPlatform::xlib): |
4117 | | - demo.execute<WsiPlatform::xlib>(); |
4118 | | - break; |
4119 | | -#endif |
4120 | | -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) |
4121 | | - case (WsiPlatform::wayland): |
4122 | | - demo.execute<WsiPlatform::wayland>(); |
4123 | | - break; |
4124 | | -#endif |
4125 | | -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) |
4126 | | - case (WsiPlatform::directfb): |
4127 | | - demo.execute<WsiPlatform::directfb>(); |
4128 | | - break; |
4129 | | -#endif |
4130 | | -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) |
4131 | | - case (WsiPlatform::display): |
4132 | | - demo.execute<WsiPlatform::display>(); |
4133 | | - break; |
4134 | | -#endif |
4135 | | -#if defined(VK_USE_PLATFORM_SCREEN_QNX) |
4136 | | - case (WsiPlatform::qnx): |
4137 | | - demo.execute<WsiPlatform::qnx>(); |
4138 | | - break; |
4139 | | -#endif |
4140 | | -#if defined(VK_USE_PLATFORM_FUCHSIA) |
4141 | | - case (WsiPlatform::fuchsia_display): |
4142 | | - demo.execute<WsiPlatform::fuchsia_display>(); |
4143 | | - break; |
4144 | | - case (WsiPlatform::fuchsia_scenic): |
4145 | | - demo.execute<WsiPlatform::fuchsia_scenic>(); |
4146 | | - break; |
4147 | | -#endif |
| 4103 | + auto platform_map = std::map<WsiPlatform, std::function<void()>>{}; |
| 4104 | + construct_dispatcher(platform_map, demo); |
| 4105 | + |
| 4106 | + if (platform_map.find(demo.wsi_platform) != platform_map.end()) { |
| 4107 | + platform_map[demo.wsi_platform](); |
| 4108 | + } |
| 4109 | + else { |
| 4110 | + fprintf(stderr, |
| 4111 | + "WSI platform should have already been set, indicating a bug. Please set a WSI platform manually with " |
| 4112 | + "--wsi\n"); |
| 4113 | + exit(1); |
4148 | 4114 | } |
4149 | 4115 |
|
4150 | 4116 | demo.cleanup(); |
|
0 commit comments