53#include "common/probe_sim.hlsli"
78 0, 0, 0, sim::PROBE_GRID_SIZE, sim::PROBE_GRID_SIZE, sim::PROBE_GRID_SIZE};
84 std::optional<uint32_t>
ParseCount(std::wstring_view text, uint32_t maximum) {
86 const std::string utf8 =
ToUtf8(text);
87 const auto [end, error] = std::from_chars(utf8.data(), utf8.data() + utf8.size(), value);
88 if (error != std::errc{} || end != utf8.data() + utf8.size() || value > maximum)
96 std::optional<std::array<uint64_t, N>>
ParseNumbers(std::wstring_view text) {
97 const std::string utf8 =
ToUtf8(text);
98 std::array<uint64_t, N> values{};
99 const char* cursor = utf8.data();
100 const char* end = utf8.data() + utf8.size();
102 for (
size_t index = 0; index < N; ++index) {
103 const auto [next, error] = std::from_chars(cursor, end, values[index]);
104 if (error != std::errc{})
107 const bool last = index + 1 == N;
108 if (last ? next != end : (next == end || (*next !=
',' && *next !=
':')))
118 std::expected<void, std::string>
ParseTraceRange(std::wstring_view argument, std::wstring_view text,
120 if (argument == L
"--trace-ticks") {
122 if (!ticks || (*ticks)[0] >= (*ticks)[1])
123 return std::unexpected(std::format(
"--trace-ticks の値が不正: {}(例: 10:20)",
ToUtf8(text)));
131 const bool ordered = cells && (*cells)[0] < (*cells)[3] && (*cells)[1] < (*cells)[4] &&
132 (*cells)[2] < (*cells)[5];
134 return std::unexpected(std::format(
"--trace-cells の値が不正: {}(例: 0,0,28:64,64,36)",
ToUtf8(text)));
146 const auto cell = [&options](
size_t index) {
147 return static_cast<uint32_t
>(std::min<uint64_t>(options.
traceCells[index], sim::PROBE_GRID_SIZE));
151 options.
traceTicks[0], options.
traceTicks[1], {cell(0), cell(1), cell(2)}, {cell(3), cell(4), cell(5)},
156 std::optional<render::OrbitCameraState>
ParseCamera(std::wstring_view text) {
157 const std::string utf8 =
ToUtf8(text);
158 std::array<float, 3> values{};
159 const char* cursor = utf8.data();
160 const char* end = utf8.data() + utf8.size();
162 for (
size_t index = 0; index < values.size(); ++index) {
163 const auto [next, error] = std::from_chars(cursor, end, values[index]);
164 if (error != std::errc{})
166 const bool last = index + 1 == values.size();
167 if (last ? next != end : (next == end || *next !=
','))
173 if (!(values[2] > 0.0f))
185 std::expected<void, std::string>
ParsePeekOption(std::wstring_view argument, std::wstring_view text,
187 if (argument == L
"--peek-depth") {
190 return std::unexpected(
199 if (!cell || std::ranges::any_of(*cell, [](uint64_t value) {
return value >= sim::PROBE_GRID_SIZE; }))
200 return std::unexpected(std::format(
"--peek の値が不正: {}(例: 28,32,32)",
ToUtf8(text)));
203 loop.
peekCell = {.x =
static_cast<uint32_t
>((*cell)[0]),
204 .y =
static_cast<uint32_t
>((*cell)[1]),
205 .z =
static_cast<uint32_t
>((*cell)[2])};
211 std::expected<void, std::string>
ParseViewOption(std::wstring_view argument, std::wstring_view text,
213 if (argument == L
"--screenshot") {
218 if (argument == L
"--peek" || argument == L
"--peek-depth")
221 if (argument == L
"--view") {
224 return std::unexpected(std::format(
"--view の値が不正: {}(volume・mip・slice)",
ToUtf8(text)));
229 return std::unexpected(std::format(
"--camera の値が不正: {}(例: 35,25,150)",
ToUtf8(text)));
243 const uint32_t maximum = argument == L
"--latency" ? 3u
245 : argument == L
"--sim-load" ? sim::PROBE_BUSY_ITERATIONS_LIMIT
246 : argument == L
"--sim-split" ? sim::PROBE_MAX_BUSY_PIECES
250 if (!value || (argument == L
"--latency" && *value < 2) || (argument == L
"--sim-split" && *value == 0) ||
252 return std::unexpected(std::format(
"{} の値が不正: {}",
ToUtf8(argument),
ToUtf8(text)));
255 if (argument == L
"--frames")
258 if (argument == L
"--latency")
261 if (argument == L
"--target-fps")
264 if (argument == L
"--sim-load")
267 if (argument == L
"--sim-split")
270 if (argument == L
"--screenshot-tick")
273 if (argument == L
"--save-points")
276 if (argument == L
"--save-interval")
284 if (argument == L
"--no-vsync")
286 else if (argument == L
"--auto-click")
288 else if (argument == L
"--auto-trace")
290 else if (argument == L
"--auto-push")
292 else if (argument == L
"--auto-ignite")
294 else if (argument == L
"--no-physics")
296 else if (argument == L
"--check-physics")
298 else if (argument == L
"--physics-compute")
300 else if (argument == L
"--warp")
302 else if (argument == L
"--render-normal")
304 else if (argument == L
"--editor")
306 else if (argument == L
"--auto-time")
308 else if (argument == L
"--auto-rewind")
310 else if (argument == L
"--auto-lab")
318 std::expected<Options, std::string>
ParseOptions(std::span<wchar_t*> arguments) {
320 for (
size_t i = 1; i < arguments.size(); ++i) {
321 const std::wstring_view argument = arguments[i];
322 const bool hasValue = i + 1 < arguments.size();
323 if (argument == L
"--caps")
327 else if ((argument == L
"--frames" || argument == L
"--latency" || argument == L
"--target-fps" ||
328 argument == L
"--sim-load" || argument == L
"--sim-split" || argument == L
"--screenshot-tick" ||
329 argument == L
"--save-points" || argument == L
"--save-interval") &&
333 return std::unexpected(parsed.error());
334 }
else if ((argument == L
"--view" || argument == L
"--camera" || argument == L
"--screenshot" ||
335 argument == L
"--peek" || argument == L
"--peek-depth") &&
339 return std::unexpected(parsed.error());
340 }
else if ((argument == L
"--trace-ticks" || argument == L
"--trace-cells") && hasValue) {
341 const auto parsed =
ParseTraceRange(argument, arguments[++i], options);
343 return std::unexpected(parsed.error());
344 }
else if (argument == L
"--trace" && hasValue)
346 else if (argument == L
"--trace-dir" && hasValue)
348 else if (argument == L
"--record" && hasValue)
350 else if (argument == L
"--replay" && hasValue)
352 else if (argument == L
"--packages" && hasValue)
354 else if (argument == L
"--log-dir" && hasValue)
356 else if (argument == L
"--log-level" && hasValue) {
357 const std::string name =
ToUtf8(arguments[++i]);
360 return std::unexpected(std::format(
"知らないログの重大度: {}", name));
362 return std::unexpected(std::format(
"知らない引数: {}",
ToUtf8(argument)));
374 int Run(std::span<wchar_t*> arguments) {
382 if (options->hasLogLevel)
385 const fs::path logDirectory = options->logDirectory.empty() ?
DefaultLogDirectory() : options->logDirectory;
386 if (
const auto logFile =
OpenLogFile(logger, logDirectory))
391 if (options->runCaps)
399int wmain(
int argc,
wchar_t** argv) {
400 const int exitCode =
Run(std::span(argv,
static_cast<size_t>(argc)));
void SetMinLevel(Level level)
int wmain(int argc, wchar_t **argv)
std::expected< void, std::string > ParseTraceRange(std::wstring_view argument, std::wstring_view text, Options &options)
int Run(std::span< wchar_t * > arguments)
std::optional< uint32_t > ParseCount(std::wstring_view text, uint32_t maximum)
std::expected< void, std::string > ParseFrameLoopCount(std::wstring_view argument, std::wstring_view text, frame::FrameLoopOptions &loop)
constexpr uint32_t MAX_TARGET_FPS
std::expected< void, std::string > ParseViewOption(std::wstring_view argument, std::wstring_view text, frame::FrameLoopOptions &loop)
std::expected< Options, std::string > ParseOptions(std::span< wchar_t * > arguments)
constexpr uint32_t MIN_TARGET_FPS
std::expected< void, std::string > ParsePeekOption(std::wstring_view argument, std::wstring_view text, frame::FrameLoopOptions &loop)
std::optional< std::array< uint64_t, N > > ParseNumbers(std::wstring_view text)
bool ParseFrameLoopFlag(std::wstring_view argument, frame::FrameLoopOptions &loop)
std::optional< render::OrbitCameraState > ParseCamera(std::wstring_view text)
void ApplyTraceRange(Options &options)
constexpr uint32_t TRACE_CAPACITY_PER_FRAME
int RunFrameLoop(const FrameLoopOptions &options)
constexpr uint32_t PEEK_MAX_DEPTH
bool ParseDebugViewMode(std::string_view name, DebugViewMode &mode)
gpu::GraphTraceFilter ProbeTraceFilterForCells(uint64_t tickBegin, uint64_t tickEnd, std::array< uint32_t, 3 > cellMin, std::array< uint32_t, 3 > cellMax, uint32_t capacity)
std::expected< fs::path, std::string > OpenLogFile(Logger &logger, const fs::path &directory)
fs::path DefaultLogDirectory()
fs::path ExecutableDirectory()
void Log(Channel channel, Level level, FormatWithLocation< std::type_identity_t< Args >... > pattern, Args &&... args)
std::string ToUtf8(std::wstring_view text)
bool ParseLevel(std::string_view text, Level &level)
std::array< uint64_t, 2 > traceTicks
frame::FrameLoopOptions frameLoop
std::array< uint64_t, 6 > traceCells
render::CellCoordinate peekCell
std::optional< uint64_t > screenshotTick
render::OrbitCameraState camera
uint64_t saveIntervalTicks
render::DebugViewSettings view
bool physicsComputeBroadphase
gpu::GraphTraceFilter trace