diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-11 11:58:24 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-11 11:58:24 +0100 |
| commit | 5ceb0256792053ee80841f2b5ac0dfae1fd4c6f8 (patch) | |
| tree | e24dafeca0d270437a39c8d91c7f5c037cf0d2f4 | |
| parent | 58c595810d0346f0c2b32dbc70b7385aee545e11 (diff) | |
fix: Complete auxiliary texture initialization fix
Root cause: After swapping init/resize order, effects with Renderer3D crashed
because resize() called before init() tried to use uninitialized GPU resources.
Changes:
- Add guards in FlashCubeEffect::resize() and Hybrid3DEffect::resize() to
check ctx_.device before calling renderer_.resize()
- Remove lazy initialization remnants from CircleMaskEffect and CNNEffect
- Register auxiliary textures directly in init() (width_/height_ already set)
- Remove ensure_texture() methods and texture_initialized_ flags
All 36 tests passing. Demo runs without crashes.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
39 files changed, 69 insertions, 30 deletions
@@ -0,0 +1,28 @@ + +thread '<unnamed>' (18683700) panicked at src/lib.rs:2426:38: +invalid device +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + +thread '<unnamed>' (18683700) panicked at library/core/src/panicking.rs:230:5: +panic in a function that cannot unwind +stack backtrace: + 0: 0x101ad75e0 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h5b9122f5e70f5951 + 1: 0x101af5194 - core::fmt::write::h6a8a2c9e4d999818 + 2: 0x101ad7854 - std::io::default_write_fmt::h89b6c507b2c6ffa7 + 3: 0x101ad6488 - std::panicking::default_hook::{{closure}}::h24b4617c01d6581d + 4: 0x101ad6370 - std::panicking::default_hook::h1955ee9a9845dfef + 5: 0x101ad6754 - std::panicking::panic_with_hook::h8aad6dd2389d8f59 + 6: 0x101ad6564 - std::panicking::panic_handler::{{closure}}::h3bd15449212d5b6e + 7: 0x101ad61e4 - std::sys::backtrace::__rust_end_short_backtrace::h3b25181b9f11fe05 + 8: 0x101ad5660 - __rustc[18f9140b322fd06e]::rust_begin_unwind + 9: 0x101b21f6c - core::panicking::panic_nounwind_fmt::h7a4dae3ab8fc5259 + 10: 0x101b21ed0 - core::panicking::panic_nounwind::h959d775d33fc4688 + 11: 0x101b22070 - core::panicking::panic_cannot_unwind::hda7331a7075802a1 + 12: 0x101786274 - _wgpuDeviceCreateTexture + 13: 0x10063ed9c - __ZN10Renderer3D6resizeEii + 14: 0x1006730c0 - __ZN15FlashCubeEffect6resizeEii + 15: 0x1006546c0 - __ZN8Sequence6resizeEii + 16: 0x1006556e0 - __ZN12MainSequence12add_sequenceENSt3__110shared_ptrI8SequenceEEfi + 17: 0x10062dc88 - __Z12LoadTimelineR12MainSequenceRK10GpuContext + 18: 0x10062b1e4 - _main +thread caused non-unwinding panic. aborting. @@ -0,0 +1,5 @@ +#!/bin/sh + +# ./training/train_cnn.py --layers 3 --kernel_sizes 3,3,3 --epochs 10000 --batch_size 16 --input training/input/ --target training/target_2/ --checkpoint-every 1000 +./training/train_cnn.py --export-only training/checkpoints/checkpoint_epoch_2000.pth +./training/train_cnn.py --export-only training/checkpoints/checkpoint_epoch_2000.pth --infer training/input/img_001.png --output test/toto.png diff --git a/src/gpu/effects/circle_mask_effect.cc b/src/gpu/effects/circle_mask_effect.cc index 08a9e33..f34ffb7 100644 --- a/src/gpu/effects/circle_mask_effect.cc +++ b/src/gpu/effects/circle_mask_effect.cc @@ -26,6 +26,9 @@ CircleMaskEffect::~CircleMaskEffect() { void CircleMaskEffect::init(MainSequence* demo) { demo_ = demo; + // Register auxiliary texture (width_/height_ set by resize() before init()) + demo_->register_auxiliary_texture("circle_mask", width_, height_); + compute_params_.init(ctx_.device); // Initialize uniforms BEFORE bind group creation @@ -152,20 +155,13 @@ void CircleMaskEffect::init(MainSequence* demo) { render_bind_group_ = wgpuDeviceCreateBindGroup(ctx_.device, &render_bg_desc); } -void CircleMaskEffect::ensure_texture() { - if (!texture_initialized_ && demo_) { - demo_->register_auxiliary_texture("circle_mask", width_, height_); - texture_initialized_ = true; - } -} - void CircleMaskEffect::resize(int width, int height) { if (width == width_ && height == height_) return; Effect::resize(width, height); - if (!demo_ || !texture_initialized_) + if (!demo_) return; // Resize auxiliary texture @@ -193,8 +189,6 @@ void CircleMaskEffect::resize(int width, int height) { void CircleMaskEffect::compute(WGPUCommandEncoder encoder, const CommonPostProcessUniforms& uniforms) { - ensure_texture(); - uniforms_.update(ctx_.queue, uniforms); const CircleMaskParams params = { diff --git a/src/gpu/effects/circle_mask_effect.h b/src/gpu/effects/circle_mask_effect.h index 91443d8..6ebaca1 100644 --- a/src/gpu/effects/circle_mask_effect.h +++ b/src/gpu/effects/circle_mask_effect.h @@ -29,11 +29,8 @@ class CircleMaskEffect : public Effect { static_assert(sizeof(CircleMaskParams) == 16, "CircleMaskParams must be 16 bytes for WGSL alignment"); - void ensure_texture(); - MainSequence* demo_ = nullptr; float radius_; - bool texture_initialized_ = false; WGPURenderPipeline compute_pipeline_ = nullptr; WGPUBindGroup compute_bind_group_ = nullptr; diff --git a/src/gpu/effects/cnn_effect.cc b/src/gpu/effects/cnn_effect.cc index 8673127..b2305b2 100644 --- a/src/gpu/effects/cnn_effect.cc +++ b/src/gpu/effects/cnn_effect.cc @@ -53,6 +53,11 @@ void CNNEffect::init(MainSequence* demo) { demo_ = demo; params_buffer_.init(ctx_.device); + // Register auxiliary texture for layer 0 (width_/height_ set by resize()) + if (layer_index_ == 0) { + demo_->register_auxiliary_texture("captured_frame", width_, height_); + } + // Initialize uniforms BEFORE any bind group creation uniforms_.update(ctx_.queue, get_common_uniforms()); @@ -60,13 +65,6 @@ void CNNEffect::init(MainSequence* demo) { params_buffer_.update(ctx_.queue, params); } -void CNNEffect::ensure_texture() { - if (!texture_initialized_ && layer_index_ == 0 && demo_) { - demo_->register_auxiliary_texture("captured_frame", width_, height_); - texture_initialized_ = true; - } -} - void CNNEffect::resize(int width, int height) { if (width == width_ && height == height_) return; @@ -74,7 +72,7 @@ void CNNEffect::resize(int width, int height) { PostProcessEffect::resize(width, height); // Only layer 0 owns the captured_frame texture - if (layer_index_ == 0 && demo_ && texture_initialized_) { + if (layer_index_ == 0 && demo_) { demo_->resize_auxiliary_texture("captured_frame", width, height); } } @@ -93,8 +91,6 @@ void CNNEffect::render(WGPURenderPassEncoder pass, } void CNNEffect::update_bind_group(WGPUTextureView input_view) { - ensure_texture(); - input_view_ = input_view; // Update common uniforms (CRITICAL for UV calculation!) diff --git a/src/gpu/effects/cnn_effect.h b/src/gpu/effects/cnn_effect.h index f79fac7..1c9f0f3 100644 --- a/src/gpu/effects/cnn_effect.h +++ b/src/gpu/effects/cnn_effect.h @@ -35,12 +35,9 @@ class CNNEffect : public PostProcessEffect { } private: - void ensure_texture(); - int layer_index_; int total_layers_; float blend_amount_; - bool texture_initialized_ = false; WGPUTextureView input_view_; WGPUTextureView original_view_; UniformBuffer<CNNLayerParams> params_buffer_; diff --git a/src/gpu/effects/flash_cube_effect.cc b/src/gpu/effects/flash_cube_effect.cc index ee25408..fe6b2a7 100644 --- a/src/gpu/effects/flash_cube_effect.cc +++ b/src/gpu/effects/flash_cube_effect.cc @@ -12,8 +12,14 @@ FlashCubeEffect::FlashCubeEffect(const GpuContext& ctx) : Effect(ctx) { } void FlashCubeEffect::resize(int width, int height) { - width_ = width; - height_ = height; + if (width == width_ && height == height_) + return; + + Effect::resize(width, height); + + if (!ctx_.device) + return; + renderer_.resize(width_, height_); } diff --git a/src/gpu/effects/hybrid_3d_effect.cc b/src/gpu/effects/hybrid_3d_effect.cc index d580471..61b3734 100644 --- a/src/gpu/effects/hybrid_3d_effect.cc +++ b/src/gpu/effects/hybrid_3d_effect.cc @@ -12,8 +12,14 @@ Hybrid3DEffect::Hybrid3DEffect(const GpuContext& ctx) : Effect(ctx) { } void Hybrid3DEffect::resize(int width, int height) { - width_ = width; - height_ = height; + if (width == width_ && height == height_) + return; + + Effect::resize(width, height); + + if (!ctx_.device) + return; + renderer_.resize(width_, height_); } diff --git a/test/toto.png b/test/toto.png Binary files differnew file mode 100644 index 0000000..de86e19 --- /dev/null +++ b/test/toto.png diff --git a/test_passthrough.wgsl b/test_passthrough.wgsl new file mode 100644 index 0000000..1e5f52a --- /dev/null +++ b/test_passthrough.wgsl @@ -0,0 +1,10 @@ +@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { + var pos = array<vec2<f32>, 3>( + vec2<f32>(-1.0, -1.0), vec2<f32>(3.0, -1.0), vec2<f32>(-1.0, 3.0) + ); + return vec4<f32>(pos[i], 0.0, 1.0); +} + +@fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { + return vec4<f32>(1.0, 0.0, 0.0, 1.0); // Solid red +} diff --git a/tmp/layer_0.png b/tmp/layer_0.png Binary files differnew file mode 100644 index 0000000..9e2e35c --- /dev/null +++ b/tmp/layer_0.png diff --git a/tmp/layer_1.png b/tmp/layer_1.png Binary files differnew file mode 100644 index 0000000..16b1a28 --- /dev/null +++ b/tmp/layer_1.png diff --git a/toto.png b/toto.png Binary files differnew file mode 100644 index 0000000..62aa745 --- /dev/null +++ b/toto.png diff --git a/training/output/ground_truth.png b/training/output/ground_truth.png Binary files differnew file mode 100644 index 0000000..afa06f6 --- /dev/null +++ b/training/output/ground_truth.png diff --git a/training/output/patch_final.png b/training/output/patch_final.png Binary files differnew file mode 100644 index 0000000..e38512b --- /dev/null +++ b/training/output/patch_final.png diff --git a/training/output/patch_gt.png b/training/output/patch_gt.png Binary files differnew file mode 100644 index 0000000..277175c --- /dev/null +++ b/training/output/patch_gt.png diff --git a/training/output/patch_tool.png b/training/output/patch_tool.png Binary files differnew file mode 100644 index 0000000..e38512b --- /dev/null +++ b/training/output/patch_tool.png diff --git a/training/output/patch_tool_fixed.png b/training/output/patch_tool_fixed.png Binary files differnew file mode 100644 index 0000000..e38512b --- /dev/null +++ b/training/output/patch_tool_fixed.png diff --git a/training/output/test_debug.png b/training/output/test_debug.png Binary files differnew file mode 100644 index 0000000..e38512b --- /dev/null +++ b/training/output/test_debug.png diff --git a/training/output/test_sync.png b/training/output/test_sync.png Binary files differnew file mode 100644 index 0000000..e38512b --- /dev/null +++ b/training/output/test_sync.png diff --git a/training/output/tool_output.png b/training/output/tool_output.png Binary files differnew file mode 100644 index 0000000..3fcec54 --- /dev/null +++ b/training/output/tool_output.png diff --git a/training/pass1_3x5x3.pth b/training/pass1_3x5x3.pth Binary files differnew file mode 100644 index 0000000..a7fa8e3 --- /dev/null +++ b/training/pass1_3x5x3.pth diff --git a/training/patch_32x32.png b/training/patch_32x32.png Binary files differnew file mode 100644 index 0000000..a665065 --- /dev/null +++ b/training/patch_32x32.png diff --git a/training/target_1/img_000.png b/training/target_1/img_000.png Binary files differnew file mode 100644 index 0000000..5a8ae80 --- /dev/null +++ b/training/target_1/img_000.png diff --git a/training/target_1/img_001.png b/training/target_1/img_001.png Binary files differnew file mode 100644 index 0000000..c4ac5d0 --- /dev/null +++ b/training/target_1/img_001.png diff --git a/training/target_1/img_002.png b/training/target_1/img_002.png Binary files differnew file mode 100644 index 0000000..e4bab4a --- /dev/null +++ b/training/target_1/img_002.png diff --git a/training/target_1/img_003.png b/training/target_1/img_003.png Binary files differnew file mode 100644 index 0000000..a98004a --- /dev/null +++ b/training/target_1/img_003.png diff --git a/training/target_1/img_004.png b/training/target_1/img_004.png Binary files differnew file mode 100644 index 0000000..c186d13 --- /dev/null +++ b/training/target_1/img_004.png diff --git a/training/target_1/img_005.png b/training/target_1/img_005.png Binary files differnew file mode 100644 index 0000000..95cfdd9 --- /dev/null +++ b/training/target_1/img_005.png diff --git a/training/target_1/img_006.png b/training/target_1/img_006.png Binary files differnew file mode 100644 index 0000000..d6bd187 --- /dev/null +++ b/training/target_1/img_006.png diff --git a/training/target_1/img_007.png b/training/target_1/img_007.png Binary files differnew file mode 100644 index 0000000..f4e3a9a --- /dev/null +++ b/training/target_1/img_007.png diff --git a/training/target_2/img_000.png b/training/target_2/img_000.png Binary files differnew file mode 100644 index 0000000..1d5aab9 --- /dev/null +++ b/training/target_2/img_000.png diff --git a/training/target_2/img_001.png b/training/target_2/img_001.png Binary files differnew file mode 100644 index 0000000..0eebab8 --- /dev/null +++ b/training/target_2/img_001.png diff --git a/training/target_2/img_002.png b/training/target_2/img_002.png Binary files differnew file mode 100644 index 0000000..827460c --- /dev/null +++ b/training/target_2/img_002.png diff --git a/training/target_2/img_003.png b/training/target_2/img_003.png Binary files differnew file mode 100644 index 0000000..988873c --- /dev/null +++ b/training/target_2/img_003.png diff --git a/training/target_2/img_004.png b/training/target_2/img_004.png Binary files differnew file mode 100644 index 0000000..5c3294f --- /dev/null +++ b/training/target_2/img_004.png diff --git a/training/target_2/img_005.png b/training/target_2/img_005.png Binary files differnew file mode 100644 index 0000000..b919c76 --- /dev/null +++ b/training/target_2/img_005.png diff --git a/training/target_2/img_006.png b/training/target_2/img_006.png Binary files differnew file mode 100644 index 0000000..8a43c33 --- /dev/null +++ b/training/target_2/img_006.png diff --git a/training/target_2/img_007.png b/training/target_2/img_007.png Binary files differnew file mode 100644 index 0000000..5cd33da --- /dev/null +++ b/training/target_2/img_007.png |
