ACMX 2.136.0
Dual-Backend Real-Time GPU Video Synthesis
Loading...
Searching...
No Matches
resource_paths.cpp
Go to the documentation of this file.
1#include "resource_paths.hpp"
2
3#include <algorithm>
4#include <cstdlib>
5#include <stdexcept>
6#include <string>
7
8#ifdef _WIN32
9#ifndef NOMINMAX
10#define NOMINMAX
11#endif
12#include <vector>
13#include <windows.h>
14#endif
15
16#ifndef ACMXVK_BUILD_RESOURCE_DIRECTORY
17#define ACMXVK_BUILD_RESOURCE_DIRECTORY "."
18#endif
19
20#ifndef ACMXVK_INSTALL_RESOURCE_DIRECTORY
21#define ACMXVK_INSTALL_RESOURCE_DIRECTORY "."
22#endif
23
24#ifndef ACMXVK_BUILD_SPRITE_VERTEX_SHADER
25#define ACMXVK_BUILD_SPRITE_VERTEX_SHADER "sprite.vert.spv"
26#endif
27
28#ifndef ACMXVK_INSTALL_SPRITE_VERTEX_SHADER
29#define ACMXVK_INSTALL_SPRITE_VERTEX_SHADER "sprite.vert.spv"
30#endif
31
32#ifndef ACMXVK_BUILD_ECHO_CACHE_SHADER
33#define ACMXVK_BUILD_ECHO_CACHE_SHADER "echo_cache.frag.spv"
34#endif
35
36#ifndef ACMXVK_INSTALL_ECHO_CACHE_SHADER
37#define ACMXVK_INSTALL_ECHO_CACHE_SHADER "echo_cache.frag.spv"
38#endif
39
40#ifndef ACMXVK_BUILD_FLIP_SHADER
41#define ACMXVK_BUILD_FLIP_SHADER "flip.frag.spv"
42#endif
43
44#ifndef ACMXVK_INSTALL_FLIP_SHADER
45#define ACMXVK_INSTALL_FLIP_SHADER "flip.frag.spv"
46#endif
47
48#ifndef ACMXVK_BUILD_PASSTHROUGH_SHADER
49#define ACMXVK_BUILD_PASSTHROUGH_SHADER "passthrough.frag.spv"
50#endif
51
52#ifndef ACMXVK_INSTALL_PASSTHROUGH_SHADER
53#define ACMXVK_INSTALL_PASSTHROUGH_SHADER "passthrough.frag.spv"
54#endif
55
56#ifndef ACMXVK_BUILD_HDR_TRANSFER_DIRECTORY
57#define ACMXVK_BUILD_HDR_TRANSFER_DIRECTORY "."
58#endif
59
60#ifndef ACMXVK_INSTALL_HDR_TRANSFER_DIRECTORY
61#define ACMXVK_INSTALL_HDR_TRANSFER_DIRECTORY "."
62#endif
63
64#ifndef ACMXVK_BUILD_HUMAN_COMPOSITE_SHADER
65#define ACMXVK_BUILD_HUMAN_COMPOSITE_SHADER "human_composite.frag.spv"
66#endif
67
68#ifndef ACMXVK_INSTALL_HUMAN_COMPOSITE_SHADER
69#define ACMXVK_INSTALL_HUMAN_COMPOSITE_SHADER "human_composite.frag.spv"
70#endif
71
72#ifndef ACMXVK_BUILD_MODEL_VERTEX_SHADER
73#define ACMXVK_BUILD_MODEL_VERTEX_SHADER "model.vert.spv"
74#endif
75
76#ifndef ACMXVK_INSTALL_MODEL_VERTEX_SHADER
77#define ACMXVK_INSTALL_MODEL_VERTEX_SHADER "model.vert.spv"
78#endif
79
80#ifndef ACMXVK_BUILD_MODEL_FRAGMENT_SHADER
81#define ACMXVK_BUILD_MODEL_FRAGMENT_SHADER "model.frag.spv"
82#endif
83
84#ifndef ACMXVK_INSTALL_MODEL_FRAGMENT_SHADER
85#define ACMXVK_INSTALL_MODEL_FRAGMENT_SHADER "model.frag.spv"
86#endif
87
88#ifndef ACMXVK_BUILD_DEFAULT_MODEL
89#define ACMXVK_BUILD_DEFAULT_MODEL "cube.obj"
90#endif
91
92#ifndef ACMXVK_INSTALL_DEFAULT_MODEL
93#define ACMXVK_INSTALL_DEFAULT_MODEL "cube.obj"
94#endif
95
96#ifndef ACMXVK_BUILD_OVERLAY_FONT
97#define ACMXVK_BUILD_OVERLAY_FONT "font.ttf"
98#endif
99
100#ifndef ACMXVK_INSTALL_OVERLAY_FONT
101#define ACMXVK_INSTALL_OVERLAY_FONT "font.ttf"
102#endif
103
104#ifndef ACMXVK_BUILD_CROSSFADE_DIRECTORY
105#define ACMXVK_BUILD_CROSSFADE_DIRECTORY "shaders/xfade"
106#endif
107
108#ifndef ACMXVK_INSTALL_CROSSFADE_DIRECTORY
109#define ACMXVK_INSTALL_CROSSFADE_DIRECTORY "shaders/xfade"
110#endif
111
112namespace acmxvk {
113 namespace {
114#ifdef _WIN32
115 [[nodiscard]] fs::path executable_resource_directory() {
116 std::vector<wchar_t> buffer(MAX_PATH);
117 for (;;) {
118 const DWORD length = GetModuleFileNameW(
119 nullptr, buffer.data(),
120 static_cast<DWORD>(buffer.size()));
121 if (length == 0U) {
122 return {};
123 }
124 if (length < buffer.size() - 1U) {
125 const std::wstring executable_name(buffer.data(), length);
126 const fs::path executable(executable_name);
127 return executable.parent_path().parent_path() / "share" /
128 "acmxvk";
129 }
130 if (buffer.size() >= 32768U) {
131 return {};
132 }
133 buffer.resize(buffer.size() * 2U);
134 }
135 }
136#endif
137
138 [[nodiscard]] fs::path
139 resolve_resource(const Options &options, const fs::path &relative_path,
140 const fs::path &installed_path,
141 const fs::path &built_path) {
142 const fs::path resource = find_resource(options, relative_path);
143 if (!resource.empty()) {
144 return resource;
145 }
146 if (fs::is_regular_file(installed_path)) {
147 return installed_path;
148 }
149 return built_path;
150 }
151 } // namespace
152
153 std::vector<fs::path> resource_directories(const Options &options) {
154 std::vector<fs::path> directories;
155 const auto append = [&](const fs::path &directory) {
156 if (directory.empty()) {
157 return;
158 }
159 const fs::path normalized =
160 fs::absolute(directory).lexically_normal();
161 if (std::find(directories.begin(), directories.end(), normalized) ==
162 directories.end()) {
163 directories.push_back(normalized);
164 }
165 };
166 append(options.resource_directory);
169#ifdef _WIN32
170 append(executable_resource_directory());
171#endif
172 append(fs::current_path());
173 return directories;
174 }
175
176 fs::path find_resource(const Options &options,
177 const fs::path &relative_path) {
178 if (relative_path.empty() || relative_path.is_absolute()) {
179 return {};
180 }
181 const fs::path normalized_relative = relative_path.lexically_normal();
182 const std::string relative_text = normalized_relative.generic_string();
183 if (relative_text == ".." || relative_text.starts_with("../") ||
184 relative_text.find("/../") != std::string::npos) {
185 return {};
186 }
187 for (const fs::path &directory : resource_directories(options)) {
188 const fs::path candidate =
189 (directory / normalized_relative).lexically_normal();
190 if (fs::is_regular_file(candidate)) {
191 return candidate;
192 }
193 }
194 return {};
195 }
196
197 fs::path sprite_vertex_shader_path(const Options &options) {
198 return resolve_resource(options, "shaders/sprite.vert.spv",
201 }
202
203 fs::path echo_cache_shader_path(const Options &options) {
204 return resolve_resource(options, "shaders/echo_cache.frag.spv",
207 }
208
209 fs::path flip_shader_path(const Options &options) {
210 return resolve_resource(options, "shaders/flip.frag.spv",
213 }
214
215 fs::path passthrough_shader_path(const Options &options) {
216 return resolve_resource(options, "shaders/passthrough.frag.spv",
219 }
220
221 fs::path hdr_transfer_shader_path(const Options &options, bool hlg,
222 bool encode) {
223 const std::string filename =
224 std::string("hdr_") + (hlg ? "hlg_" : "pq_") +
225 (encode ? "encode.frag.spv" : "decode.frag.spv");
226 return resolve_resource(
227 options, fs::path("shaders") / filename,
228 fs::path(ACMXVK_INSTALL_HDR_TRANSFER_DIRECTORY) / filename,
229 fs::path(ACMXVK_BUILD_HDR_TRANSFER_DIRECTORY) / filename);
230 }
231
232 fs::path hdr_preview_shader_path(const Options &options, bool hlg) {
233 const std::string filename =
234 std::string("hdr_preview_") + (hlg ? "hlg" : "pq") +
235 ".frag.spv";
236 return resolve_resource(
237 options, fs::path("shaders") / filename,
238 fs::path(ACMXVK_INSTALL_HDR_TRANSFER_DIRECTORY) / filename,
239 fs::path(ACMXVK_BUILD_HDR_TRANSFER_DIRECTORY) / filename);
240 }
241
242 fs::path human_composite_shader_path(const Options &options) {
243 return resolve_resource(options, "shaders/human_composite.frag.spv",
246 }
247
248 fs::path crossfade_shader_path(const Options &options,
249 std::size_t shader_index) {
250 if (shader_index >= CROSSFADE_NAMES.size()) {
251 throw std::out_of_range("crossfade shader index is out of range");
252 }
253 const std::string filename =
254 std::string(CROSSFADE_NAMES[shader_index]) + ".frag.spv";
255 const fs::path resource =
256 find_resource(options, fs::path("shaders/xfade") / filename);
257 if (!resource.empty()) {
258 return resource;
259 }
260 const fs::path installed =
261 fs::path(ACMXVK_INSTALL_CROSSFADE_DIRECTORY) / filename;
262 if (fs::is_regular_file(installed)) {
263 return installed;
264 }
265 const fs::path built =
266 fs::path(ACMXVK_BUILD_CROSSFADE_DIRECTORY) / filename;
267 if (fs::is_regular_file(built)) {
268 return built;
269 }
270 throw std::runtime_error("crossfade shader was not found: " +
271 filename);
272 }
273
274 fs::path model_vertex_shader_path(const Options &options) {
275 return resolve_resource(options, "shaders/model.vert.spv",
278 }
279
280 fs::path model_fragment_shader_path(const Options &options) {
281 return resolve_resource(options, "shaders/model.frag.spv",
284 }
285
286 fs::path default_model_path(const Options &options) {
287 return resolve_resource(options, "models/cube.obj",
290 }
291
292 fs::path overlay_font_path(const Options &options) {
293 return resolve_resource(options, "data/font.ttf",
296 }
297} // namespace acmxvk
GLsizei GLsizei * length
fs::path resolve_resource(const Options &options, const fs::path &relative_path, const fs::path &installed_path, const fs::path &built_path)
fs::path default_model_path(const Options &options)
fs::path echo_cache_shader_path(const Options &options)
fs::path human_composite_shader_path(const Options &options)
std::vector< fs::path > resource_directories(const Options &options)
fs::path model_fragment_shader_path(const Options &options)
fs::path model_vertex_shader_path(const Options &options)
fs::path passthrough_shader_path(const Options &options)
fs::path hdr_preview_shader_path(const Options &options, bool hlg)
fs::path crossfade_shader_path(const Options &options, std::size_t shader_index)
fs::path sprite_vertex_shader_path(const Options &options)
fs::path hdr_transfer_shader_path(const Options &options, bool hlg, bool encode)
constexpr std::array< std::string_view, 35 > CROSSFADE_NAMES
Definition options.hpp:15
fs::path overlay_font_path(const Options &options)
fs::path flip_shader_path(const Options &options)
fs::path find_resource(const Options &options, const fs::path &relative_path)
#define ACMXVK_BUILD_MODEL_VERTEX_SHADER
#define ACMXVK_INSTALL_HDR_TRANSFER_DIRECTORY
#define ACMXVK_INSTALL_PASSTHROUGH_SHADER
#define ACMXVK_INSTALL_OVERLAY_FONT
#define ACMXVK_BUILD_HUMAN_COMPOSITE_SHADER
#define ACMXVK_BUILD_CROSSFADE_DIRECTORY
#define ACMXVK_BUILD_PASSTHROUGH_SHADER
#define ACMXVK_BUILD_ECHO_CACHE_SHADER
#define ACMXVK_BUILD_RESOURCE_DIRECTORY
#define ACMXVK_INSTALL_MODEL_VERTEX_SHADER
#define ACMXVK_INSTALL_RESOURCE_DIRECTORY
#define ACMXVK_INSTALL_SPRITE_VERTEX_SHADER
#define ACMXVK_BUILD_DEFAULT_MODEL
#define ACMXVK_INSTALL_HUMAN_COMPOSITE_SHADER
#define ACMXVK_INSTALL_MODEL_FRAGMENT_SHADER
#define ACMXVK_BUILD_FLIP_SHADER
#define ACMXVK_INSTALL_ECHO_CACHE_SHADER
#define ACMXVK_BUILD_SPRITE_VERTEX_SHADER
#define ACMXVK_INSTALL_FLIP_SHADER
#define ACMXVK_BUILD_OVERLAY_FONT
#define ACMXVK_INSTALL_CROSSFADE_DIRECTORY
#define ACMXVK_BUILD_MODEL_FRAGMENT_SHADER
#define ACMXVK_INSTALL_DEFAULT_MODEL
#define ACMXVK_BUILD_HDR_TRANSFER_DIRECTORY
std::string resource_directory
Definition options.hpp:192