|
4 | 4 | #include <chrono> |
5 | 5 | #include <cstdint> |
6 | 6 | #include <cstdlib> |
| 7 | +#include <cstring> |
| 8 | +#include <filesystem> |
7 | 9 | #include <fstream> |
8 | 10 | #include <iomanip> |
9 | 11 | #include <iostream> |
|
13 | 15 | #include <string> |
14 | 16 | #include <vector> |
15 | 17 |
|
16 | | -#ifndef VK_BENCH_SHADER_DIR |
17 | | -#define VK_BENCH_SHADER_DIR "./shaders" |
18 | | -#endif |
19 | | - |
20 | 18 | struct Config { |
21 | 19 | bool headless = false; |
22 | 20 | uint32_t frames = 300; |
@@ -108,6 +106,41 @@ Config parse_args(int argc, char **argv) { |
108 | 106 | return cfg; |
109 | 107 | } |
110 | 108 |
|
| 109 | +std::string pick_shader_dir(const char *argv0) { |
| 110 | + namespace fs = std::filesystem; |
| 111 | + |
| 112 | + std::vector<fs::path> candidates; |
| 113 | + if (argv0 != nullptr && std::strlen(argv0) > 0) { |
| 114 | + fs::path exe_path(argv0); |
| 115 | + if (!exe_path.is_absolute()) { |
| 116 | + exe_path = fs::absolute(exe_path); |
| 117 | + } |
| 118 | + candidates.push_back(exe_path.parent_path() / "shaders"); |
| 119 | + } |
| 120 | + |
| 121 | +#ifdef VK_BENCH_SHADER_DIR |
| 122 | + candidates.emplace_back(VK_BENCH_SHADER_DIR); |
| 123 | +#endif |
| 124 | + candidates.emplace_back(fs::current_path() / "shaders"); |
| 125 | + |
| 126 | + for (const auto &candidate : candidates) { |
| 127 | + std::error_code ec; |
| 128 | + if (fs::exists(candidate / "triangle.vert.spv", ec) && |
| 129 | + fs::exists(candidate / "triangle.frag.spv", ec)) { |
| 130 | + return candidate.string(); |
| 131 | + } |
| 132 | + } |
| 133 | + |
| 134 | + std::string searched; |
| 135 | + for (const auto &candidate : candidates) { |
| 136 | + if (!searched.empty()) { |
| 137 | + searched += ", "; |
| 138 | + } |
| 139 | + searched += candidate.string(); |
| 140 | + } |
| 141 | + fail("Failed to locate shader directory. Checked: " + searched); |
| 142 | +} |
| 143 | + |
111 | 144 | std::vector<uint32_t> read_spirv(const std::string &path) { |
112 | 145 | std::ifstream file(path, std::ios::binary | std::ios::ate); |
113 | 146 | if (!file) { |
@@ -179,7 +212,8 @@ void destroy_buffer(VkDevice device, BufferWithMemory &buffer) { |
179 | 212 |
|
180 | 213 | TriangleResources create_triangle_resources(VkPhysicalDevice physical, |
181 | 214 | VkDevice device, uint32_t width, |
182 | | - uint32_t height) { |
| 215 | + uint32_t height, |
| 216 | + const std::string &shader_dir) { |
183 | 217 | TriangleResources out{}; |
184 | 218 |
|
185 | 219 | VkImageCreateInfo ici{VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO}; |
@@ -267,10 +301,8 @@ TriangleResources create_triangle_resources(VkPhysicalDevice physical, |
267 | 301 | fail("vkCreateFramebuffer failed"); |
268 | 302 | } |
269 | 303 |
|
270 | | - const auto vert = |
271 | | - read_spirv(std::string(VK_BENCH_SHADER_DIR) + "/triangle.vert.spv"); |
272 | | - const auto frag = |
273 | | - read_spirv(std::string(VK_BENCH_SHADER_DIR) + "/triangle.frag.spv"); |
| 304 | + const auto vert = read_spirv(shader_dir + "/triangle.vert.spv"); |
| 305 | + const auto frag = read_spirv(shader_dir + "/triangle.frag.spv"); |
274 | 306 |
|
275 | 307 | VkShaderModuleCreateInfo smci{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO}; |
276 | 308 | smci.codeSize = vert.size() * sizeof(uint32_t); |
@@ -482,10 +514,11 @@ int main(int argc, char **argv) { |
482 | 514 |
|
483 | 515 | const bool graphics_scene = |
484 | 516 | cfg.scene == "triangle" || cfg.scene == "million-tris"; |
| 517 | + const std::string shader_dir = pick_shader_dir(argv[0]); |
485 | 518 | TriangleResources triangle{}; |
486 | 519 | if (graphics_scene) { |
487 | | - triangle = |
488 | | - create_triangle_resources(physical, device, cfg.width, cfg.height); |
| 520 | + triangle = create_triangle_resources(physical, device, cfg.width, |
| 521 | + cfg.height, shader_dir); |
489 | 522 | } |
490 | 523 |
|
491 | 524 | BufferWithMemory src{}; |
|
0 commit comments