1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
const std = @import("std");
const build_config = @import("pardes_config");
const config = @import("config.zig");
const filesystem = @import("fs.zig");
const shader_dir = if (build_config.gui_shader_sources_prebuilt)
"shaders/prebuilt/"
else
"shaders/";
const ui_vertex_path = shader_dir ++ "ui.vert.glsl";
const ui_fragment_path = shader_dir ++ "ui.frag.glsl";
const image_vertex_path = shader_dir ++ "image.vert.glsl";
const image_fragment_path = shader_dir ++ "image.frag.glsl";
const post_vertex_path = shader_dir ++ "post.vert.glsl";
// The bundled post pass as compiled: the prefix and the pass together.
const post_crt_path = shader_dir ++ "post-crt.frag.glsl";
const post_bloom_path = shader_dir ++ "post-bloom.frag.glsl";
const post_vignette_path = shader_dir ++ "post-vignette.frag.glsl";
const post_grain_path = shader_dir ++ "post-grain.frag.glsl";
const bloom_down_path = shader_dir ++ "bloom-down.frag.glsl";
const bloom_up_path = shader_dir ++ "bloom-up.frag.glsl";
pub const Backend = @TypeOf(build_config.platform);
pub const backend: Backend = build_config.platform;
pub const GuiShaderSourceMode = enum {
live,
prebuilt_snapshot,
pub fn label(mode: GuiShaderSourceMode) []const u8 {
return switch (mode) {
.live => "live GLSL compiled during this build",
.prebuilt_snapshot => "paired GLSL snapshot for committed SPIR-V",
};
}
};
/// Only the SDL backend consumes GLSL/SPIR-V. Other backends deliberately have
/// no shader-source mode rather than being mislabeled "live" or "prebuilt".
pub fn guiShaderSourceMode() ?GuiShaderSourceMode {
if (backend != .gui) return null;
return if (build_config.gui_shader_sources_prebuilt)
.prebuilt_snapshot
else
.live;
}
pub const files = switch (backend) {
.tty => [_]filesystem.Source{
.{ .path = "src/tty/panel_compositor.zig", .contents = @embedFile("tty/panel_compositor.zig") },
},
.gui => [_]filesystem.Source{
.{ .path = "src/gui/gui.zig", .contents = @embedFile("gui/gui.zig") },
.{ .path = "src/gui/Post.zig", .contents = @embedFile("gui/Post.zig") },
.{ .path = ui_vertex_path, .contents = @embedFile("effect-source-ui.vert.glsl") },
.{ .path = ui_fragment_path, .contents = @embedFile("effect-source-ui.frag.glsl") },
.{ .path = image_vertex_path, .contents = @embedFile("effect-source-image.vert.glsl") },
.{ .path = image_fragment_path, .contents = @embedFile("effect-source-image.frag.glsl") },
.{ .path = post_vertex_path, .contents = @embedFile("effect-source-post.vert.glsl") },
.{ .path = post_crt_path, .contents = @embedFile("effect-source-post-crt.frag.glsl") },
.{ .path = post_bloom_path, .contents = @embedFile("effect-source-post-bloom.frag.glsl") },
.{ .path = post_vignette_path, .contents = @embedFile("effect-source-post-vignette.frag.glsl") },
.{ .path = post_grain_path, .contents = @embedFile("effect-source-post-grain.frag.glsl") },
.{ .path = bloom_down_path, .contents = @embedFile("effect-source-bloom-down.frag.glsl") },
.{ .path = bloom_up_path, .contents = @embedFile("effect-source-bloom-up.frag.glsl") },
},
.macos => [_]filesystem.Source{
.{ .path = "src/macos/Sources/PardesView.swift", .contents = @embedFile("macos/Sources/PardesView.swift") },
.{ .path = "src/macos/Sources/ScenePostprocessor.swift", .contents = @embedFile("macos/Sources/ScenePostprocessor.swift") },
.{ .path = "shaders/crt.ci.metal", .contents = @embedFile("effect-source-crt.ci.metal") },
},
.web, .esp32p4 => [_]filesystem.Source{},
};
pub fn forSetting(setting: config.Runtime.Setting) ?[]const []const u8 {
return switch (setting.action) {
.transition => switch (backend) {
.tty => &.{ "src/layout.zig", "src/pardes.zig", "src/tty/panel_compositor.zig" },
.gui => &.{ "src/layout.zig", "src/pardes.zig", "src/gui/gui.zig", ui_vertex_path, ui_fragment_path, image_vertex_path, image_fragment_path },
.macos => &.{ "src/layout.zig", "src/pardes.zig", "src/macos/Sources/PardesView.swift", "src/macos/Sources/ScenePostprocessor.swift", "shaders/crt.ci.metal" },
.web, .esp32p4 => null,
},
.scene => |effect| switch (backend) {
.gui => switch (effect) {
.crt => &.{ "src/gui/Post.zig", "src/gui/gui.zig", post_vertex_path, post_crt_path },
.bloom => &.{ "src/gui/Post.zig", "src/gui/gui.zig", post_vertex_path, bloom_down_path, bloom_up_path, post_bloom_path },
.vignette => &.{ "src/gui/Post.zig", "src/gui/gui.zig", post_vertex_path, post_vignette_path },
.grain => &.{ "src/gui/Post.zig", "src/gui/gui.zig", post_vertex_path, post_grain_path },
},
.macos => &.{ "src/macos/Sources/PardesView.swift", "src/macos/Sources/ScenePostprocessor.swift", "shaders/crt.ci.metal" },
.tty, .web, .esp32p4 => null,
},
else => null,
};
}
test "EffectCode paths resolve uniquely to this backend's archived inputs" {
if (!@import("memory.zig").limits.embedded_sources) return error.SkipZigTest;
for (config.Runtime.settings) |setting| {
const available = switch (setting.action) {
.transition => backend == .tty or backend == .gui or backend == .macos,
.scene => backend == .gui or backend == .macos,
else => false,
};
const paths = forSetting(setting);
try std.testing.expectEqual(available, paths != null);
if (paths) |listed| for (listed, 0..) |path, i| {
const bytes = filesystem.sourceBytes(path) orelse return error.MissingEffectSource;
try std.testing.expect(bytes.len > 0);
for (listed[0..i]) |previous| try std.testing.expect(!std.mem.eql(u8, path, previous));
};
}
for (files) |file| {
const archived = filesystem.sourceBytes(file.path) orelse return error.MissingEffectSource;
try std.testing.expectEqualStrings(file.contents, archived);
var matches: usize = 0;
for (filesystem.sources) |source| if (std.mem.eql(u8, source.path, file.path)) {
matches += 1;
};
try std.testing.expectEqual(@as(usize, 1), matches);
}
try std.testing.expectEqual(backend == .tty, filesystem.sourceBytes("src/tty/panel_compositor.zig") != null);
try std.testing.expectEqual(backend == .gui, filesystem.sourceBytes("src/gui/gui.zig") != null);
try std.testing.expectEqual(backend == .macos, filesystem.sourceBytes("src/macos/Sources/PardesView.swift") != null);
}
test "shader source provenance is GUI-only and follows the build input" {
if (comptime backend == .gui) {
const expected: GuiShaderSourceMode = if (build_config.gui_shader_sources_prebuilt)
.prebuilt_snapshot
else
.live;
try std.testing.expectEqual(expected, guiShaderSourceMode().?);
try std.testing.expect(expected.label().len > 0);
} else try std.testing.expect(guiShaderSourceMode() == null);
}
|