0ce56438
scenario: guard scale change + tighten captureCb errdefer
a73x 2026-04-19 13:39
Commit message
src/main.zig
| Old | New | ||
|---|---|---|---|
| @@ -237,9 +237,15 @@ pub fn runScenarios(alloc: std.mem.Allocator, argv: []const [:0]const u8) !u8 { | |||
| 237 | }; | 237 | }; |
| 238 | defer rc.deinit(); | 238 | defer rc.deinit(); |
| 239 | 239 | ||
| 240 | runTerminal(alloc, &rc) catch |err| { | 240 | runTerminal(alloc, &rc) catch |err| switch (err) { |
| 241 | std.debug.print("scenario {s}: runtime error: {s}\n", .{ scenario_name, @errorName(err) }); | 241 | error.ScenarioScaleChangeNotSupported => { |
| 242 | return @intFromEnum(scenario_runtime.ExitCode.other_error); | 242 | // already printed; return exit 6 (other render error) |
| 243 | return @intFromEnum(scenario_runtime.ExitCode.other_error); | ||
| 244 | }, | ||
| 245 | else => { | ||
| 246 | std.debug.print("scenario {s}: runtime error: {s}\n", .{ scenario_name, @errorName(err) }); | ||
| 247 | return @intFromEnum(scenario_runtime.ExitCode.other_error); | ||
| 248 | }, | ||
| 243 | }; | 249 | }; |
| 244 | 250 | ||
| 245 | if (rc.tick_fatal) |err| { | 251 | if (rc.tick_fatal) |err| { |
| @@ -608,6 +614,10 @@ fn runTerminal(alloc: std.mem.Allocator, tick_ctx: ?*scenario_runtime.RunContext | |||
| 608 | if (!render_pending) continue; | 614 | if (!render_pending) continue; |
| 609 | 615 | ||
| 610 | if (scale_pending) { | 616 | if (scale_pending) { |
| 617 | if (tick_ctx) |_| { | ||
| 618 | std.debug.print("scenario: runtime scale change not supported; please pin the compositor output to scale 1 (or re-run on a scale-1 monitor).\n", .{}); | ||
| 619 | return error.ScenarioScaleChangeNotSupported; | ||
| 620 | } | ||
| 611 | vk_sync.waitIdleForShutdown(ctx.vkd, ctx.device); | 621 | vk_sync.waitIdleForShutdown(ctx.vkd, ctx.device); |
| 612 | 622 | ||
| 613 | geom = try rebuildFaceForScale( | 623 | geom = try rebuildFaceForScale( |
src/scenario_runtime.zig
| Old | New | ||
|---|---|---|---|
| @@ -155,10 +155,10 @@ pub fn captureCb(ctx: *anyopaque, label: []const u8) anyerror!png.Image { | |||
| 155 | 155 | ||
| 156 | // --- readback --- | 156 | // --- readback --- |
| 157 | const pixels = try rc.alloc.alloc(u8, @as(usize, rc.px_w) * rc.px_h * 4); | 157 | const pixels = try rc.alloc.alloc(u8, @as(usize, rc.px_w) * rc.px_h * 4); |
| 158 | errdefer rc.alloc.free(pixels); | ||
| 159 | try rctx.readbackOffscreen(offscreen, pixels); | 158 | try rctx.readbackOffscreen(offscreen, pixels); |
| 160 | 159 | ||
| 161 | const img: png.Image = .{ .width = rc.px_w, .height = rc.px_h, .pixels = pixels }; | 160 | const img: png.Image = .{ .width = rc.px_w, .height = rc.px_h, .pixels = pixels }; |
| 161 | errdefer rc.alloc.free(img.pixels); // covers all subsequent error paths | ||
| 162 | 162 | ||
| 163 | // --- write out/<scenario>/<label>.png --- | 163 | // --- write out/<scenario>/<label>.png --- |
| 164 | const out_dir = try std.fmt.allocPrint( | 164 | const out_dir = try std.fmt.allocPrint( |
| @@ -230,7 +230,7 @@ pub fn captureCb(ctx: *anyopaque, label: []const u8) anyerror!png.Image { | |||
| 230 | return img; | 230 | return img; |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | const diff = imgdiff.compare(img, golden) catch |err| return err; | 233 | const diff = try imgdiff.compare(img, golden); |
| 234 | if (diff.rmse > imgdiff.RMSE_DEFAULT or diff.max_pixel > imgdiff.PIXEL_MAX_DEFAULT) { | 234 | if (diff.rmse > imgdiff.RMSE_DEFAULT or diff.max_pixel > imgdiff.PIXEL_MAX_DEFAULT) { |
| 235 | const lbl = try rc.alloc.dupe(u8, label); | 235 | const lbl = try rc.alloc.dupe(u8, label); |
| 236 | errdefer rc.alloc.free(lbl); | 236 | errdefer rc.alloc.free(lbl); |