diff options
Diffstat (limited to 'src/tests/gpu/test_sequence_v2_e2e.cc')
| -rw-r--r-- | src/tests/gpu/test_sequence_v2_e2e.cc | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/tests/gpu/test_sequence_v2_e2e.cc b/src/tests/gpu/test_sequence_v2_e2e.cc new file mode 100644 index 0000000..0c7c619 --- /dev/null +++ b/src/tests/gpu/test_sequence_v2_e2e.cc @@ -0,0 +1,114 @@ +// End-to-end test for Sequence v2 system +// Tests compiler output instantiation and execution + +#include "gpu/sequence_v2.h" +#include "gpu/effect_v2.h" +#include "effects/gaussian_blur_effect_v2.h" +#include "effects/heptagon_effect_v2.h" +#include "effects/passthrough_effect_v2.h" +#include "gpu/shaders.h" +#include "tests/common/webgpu_test_fixture.h" +#include <cassert> +#include <cstdio> + +// Manually transcribed generated sequence (simulates compiler output) +// Simple 2-effect chain to validate DAG execution +class SimpleTestSequence : public SequenceV2 { + public: + SimpleTestSequence(const GpuContext& ctx, int width, int height) + : SequenceV2(ctx, width, height) { + // Node declarations (including source/sink for testing) + nodes_.declare_node("source", NodeType::U8X4_NORM, width_, height_); + nodes_.declare_node("temp", NodeType::U8X4_NORM, width_, height_); + nodes_.declare_node("sink", NodeType::U8X4_NORM, width_, height_); + + // Effect DAG construction (2 effects: source->temp->sink) + effect_dag_.push_back({ + .effect = std::make_shared<PassthroughEffectV2>(ctx, + std::vector<std::string>{"source"}, + std::vector<std::string>{"temp"}), + .input_nodes = {"source"}, + .output_nodes = {"temp"}, + .execution_order = 0 + }); + effect_dag_.push_back({ + .effect = std::make_shared<PassthroughEffectV2>(ctx, + std::vector<std::string>{"temp"}, + std::vector<std::string>{"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; +} |
