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
|
// This file is part of the 64k demo project.
// It tests the ShaderComposer utility.
#include "gpu/effects/shader_composer.h"
#include <cassert>
#include <iostream>
#include <string>
#if defined(USE_TEST_ASSETS)
#include "test_assets.h"
#else
#include "generated/assets.h"
#endif
// Forward declaration for asset loading
const uint8_t* GetAsset(AssetId asset_id, size_t* out_size);
void test_composition() {
std::cout << "Testing Shader Composition..." << std::endl;
auto& sc = ShaderComposer::Get();
sc.RegisterSnippet("math", "fn add(a: f32, b: f32) -> f32 { return a + b; }");
sc.RegisterSnippet("util", "fn square(a: f32) -> f32 { return a * a; }");
std::string main_code = "fn main() { let x = add(1.0, square(2.0)); }";
std::string result = sc.Compose({"math", "util"}, main_code);
// Verify order and presence
assert(result.find("Dependency: math") != std::string::npos);
assert(result.find("Dependency: util") != std::string::npos);
assert(result.find("Main Code") != std::string::npos);
size_t pos_math = result.find("Dependency: math");
size_t pos_util = result.find("Dependency: util");
size_t pos_main = result.find("Main Code");
assert(pos_math < pos_util);
assert(pos_util < pos_main);
std::cout << "Composition logic verified." << std::endl;
}
void test_asset_composition() {
std::cout << "Testing Asset-Based Shader Composition..." << std::endl;
// Use test assets
auto& sc = ShaderComposer::Get();
size_t snippet_a_size;
const char* snippet_a_code =
(const char*)GetAsset(AssetId::ASSET_SHADER_SNIPPET_A, &snippet_a_size);
assert(snippet_a_code != nullptr);
sc.RegisterSnippet("SNIPPET_A", std::string(snippet_a_code, snippet_a_size));
size_t snippet_b_size;
const char* snippet_b_code =
(const char*)GetAsset(AssetId::ASSET_SHADER_SNIPPET_B, &snippet_b_size);
sc.RegisterSnippet("SNIPPET_B", std::string(snippet_b_code, snippet_b_size));
std::string main_code =
"fn main() -> f32 { return snippet_a() + snippet_b(); }";
std::string result = sc.Compose({"SNIPPET_A", "SNIPPET_B"}, main_code);
assert(result.find("fn snippet_a()") != std::string::npos);
assert(result.find("fn snippet_b()") != std::string::npos);
assert(result.find("fn main()") != std::string::npos);
size_t pos_a = result.find("snippet_a");
size_t pos_b = result.find("snippet_b");
size_t pos_main = result.find("main");
assert(pos_a < pos_b);
assert(pos_b < pos_main);
std::cout << "Asset-based composition logic verified." << std::endl;
}
void test_recursive_composition() {
std::cout << "Testing Recursive Shader Composition..." << std::endl;
auto& sc = ShaderComposer::Get();
sc.RegisterSnippet("base", "fn base() {}");
sc.RegisterSnippet("mid", "#include \"base\"\nfn mid() { base(); }");
sc.RegisterSnippet(
"top",
"#include \"mid\"\n#include \"base\"\nfn top() { mid(); base(); }");
std::string main_code = "#include \"top\"\nfn main() { top(); }";
std::string result = sc.Compose({}, main_code);
// Verify each is included exactly once despite multiple includes
size_t count_base = 0;
size_t pos = result.find("fn base()");
while (pos != std::string::npos) {
count_base++;
pos = result.find("fn base()", pos + 1);
}
assert(count_base == 1);
assert(result.find("Included: top") != std::string::npos);
assert(result.find("Included: mid") != std::string::npos);
assert(result.find("Included: base") != std::string::npos);
std::cout << "Recursive composition logic verified." << std::endl;
}
void test_renderer_composition() {
std::cout << "Testing Renderer Shader Composition..." << std::endl;
auto& sc = ShaderComposer::Get();
sc.RegisterSnippet("common_uniforms",
"struct GlobalUniforms { view_proj: mat4x4<f32> };");
sc.RegisterSnippet("math/sdf_shapes", "fn sdSphere() {}");
sc.RegisterSnippet("render/scene_query",
"#include \"math/sdf_shapes\"\nfn map_scene() {}");
std::string main_code =
"#include \"common_uniforms\"\n#include \"render/scene_query\"\nfn "
"main() {}";
std::string result = sc.Compose({}, main_code);
assert(result.find("struct GlobalUniforms") != std::string::npos);
assert(result.find("fn sdSphere") != std::string::npos);
assert(result.find("fn map_scene") != std::string::npos);
std::cout << "Renderer composition logic verified." << std::endl;
}
int main() {
test_composition();
test_asset_composition();
test_recursive_composition();
test_renderer_composition();
std::cout << "--- ALL SHADER COMPOSER TESTS PASSED ---" << std::endl;
return 0;
}
|