// End-to-end test for Sequence v2 system // Tests compiler output instantiation and execution #include "gpu/sequence.h" #include "gpu/effect.h" #include "effects/gaussian_blur_effect.h" #include "effects/heptagon_effect.h" #include "effects/passthrough_effect.h" #include "effects/shaders.h" #include "tests/common/webgpu_test_fixture.h" #include #include // Manually transcribed generated sequence (simulates compiler output) // Simple 2-effect chain to validate DAG execution class SimpleTestSequence : public Sequence { public: SimpleTestSequence(const GpuContext& ctx, int width, int height) : Sequence(ctx, width, height) { // Node declarations (source/sink already created by NodeRegistry) nodes_.declare_node("temp", NodeType::U8X4_NORM, width_, height_); // Effect DAG construction (2 effects: source->temp->sink) effect_dag_.push_back({ .effect = std::make_shared(ctx, std::vector{"source"}, std::vector{"temp"}), .input_nodes = {"source"}, .output_nodes = {"temp"}, .execution_order = 0 }); effect_dag_.push_back({ .effect = std::make_shared(ctx, std::vector{"temp"}, std::vector{"sink"}), .input_nodes = {"temp"}, .output_nodes = {"sink"}, .execution_order = 1 }); } }; // Test: Instantiate and run v2 sequence void test_sequence_v2_instantiation() { WebGPUTestFixture fixture; if (!fixture.init()) { fprintf(stderr, "Skipping test (no GPU)\n"); return; } // Initialize shader composer with snippets InitShaderComposer(); // Create sequence SimpleTestSequence seq(fixture.ctx(), 1280, 720); // Preprocess seq.preprocess(0.0f, 0.0f, 0.0f, 0.0f); // Create command encoder WGPUCommandEncoderDescriptor enc_desc = {}; WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(fixture.ctx().device, &enc_desc); // Execute DAG (should not crash) seq.render_effects(encoder); // Cleanup WGPUCommandBuffer cmd = wgpuCommandEncoderFinish(encoder, nullptr); wgpuCommandBufferRelease(cmd); wgpuCommandEncoderRelease(encoder); printf("PASS: Sequence v2 instantiation and execution\n"); } // Test: Verify DAG execution order void test_dag_execution_order() { WebGPUTestFixture fixture; if (!fixture.init()) { fprintf(stderr, "Skipping test (no GPU)\n"); return; } // Initialize shader composer with snippets InitShaderComposer(); SimpleTestSequence seq(fixture.ctx(), 1280, 720); // Verify effects are in correct order const auto& dag = seq.get_effect_dag(); assert(dag.size() == 2); assert(dag[0].execution_order == 0); assert(dag[1].execution_order == 1); // Verify node routing assert(dag[0].input_nodes[0] == "source"); assert(dag[0].output_nodes[0] == "temp"); assert(dag[1].input_nodes[0] == "temp"); assert(dag[1].output_nodes[0] == "sink"); printf("PASS: DAG execution order validated\n"); } int main() { printf("Running Sequence v2 end-to-end tests...\n"); test_sequence_v2_instantiation(); test_dag_execution_order(); printf("All Sequence v2 e2e tests passed!\n"); return 0; }