From 5ceb0256792053ee80841f2b5ac0dfae1fd4c6f8 Mon Sep 17 00:00:00 2001 From: skal Date: Wed, 11 Feb 2026 11:58:24 +0100 Subject: 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 --- LOG.txt | 28 ++++++++++++++++++++++++++++ go.sh | 5 +++++ src/gpu/effects/circle_mask_effect.cc | 14 ++++---------- src/gpu/effects/circle_mask_effect.h | 3 --- src/gpu/effects/cnn_effect.cc | 16 ++++++---------- src/gpu/effects/cnn_effect.h | 3 --- src/gpu/effects/flash_cube_effect.cc | 10 ++++++++-- src/gpu/effects/hybrid_3d_effect.cc | 10 ++++++++-- test/toto.png | Bin 0 -> 27738 bytes test_passthrough.wgsl | 10 ++++++++++ tmp/layer_0.png | Bin 0 -> 239570 bytes tmp/layer_1.png | Bin 0 -> 71523 bytes toto.png | Bin 0 -> 24933 bytes training/output/ground_truth.png | Bin 0 -> 8547 bytes training/output/patch_final.png | Bin 0 -> 105 bytes training/output/patch_gt.png | Bin 0 -> 138 bytes training/output/patch_tool.png | Bin 0 -> 105 bytes training/output/patch_tool_fixed.png | Bin 0 -> 105 bytes training/output/test_debug.png | Bin 0 -> 105 bytes training/output/test_sync.png | Bin 0 -> 105 bytes training/output/tool_output.png | Bin 0 -> 8030 bytes training/pass1_3x5x3.pth | Bin 0 -> 20287 bytes training/patch_32x32.png | Bin 0 -> 5259 bytes training/target_1/img_000.png | Bin 0 -> 16088 bytes training/target_1/img_001.png | Bin 0 -> 7727 bytes training/target_1/img_002.png | Bin 0 -> 7366 bytes training/target_1/img_003.png | Bin 0 -> 7395 bytes training/target_1/img_004.png | Bin 0 -> 13073 bytes training/target_1/img_005.png | Bin 0 -> 5119 bytes training/target_1/img_006.png | Bin 0 -> 28013 bytes training/target_1/img_007.png | Bin 0 -> 21369 bytes training/target_2/img_000.png | Bin 0 -> 88375 bytes training/target_2/img_001.png | Bin 0 -> 67507 bytes training/target_2/img_002.png | Bin 0 -> 103073 bytes training/target_2/img_003.png | Bin 0 -> 101735 bytes training/target_2/img_004.png | Bin 0 -> 92212 bytes training/target_2/img_005.png | Bin 0 -> 89291 bytes training/target_2/img_006.png | Bin 0 -> 78047 bytes training/target_2/img_007.png | Bin 0 -> 54303 bytes 39 files changed, 69 insertions(+), 30 deletions(-) create mode 100644 LOG.txt create mode 100644 go.sh create mode 100644 test/toto.png create mode 100644 test_passthrough.wgsl create mode 100644 tmp/layer_0.png create mode 100644 tmp/layer_1.png create mode 100644 toto.png create mode 100644 training/output/ground_truth.png create mode 100644 training/output/patch_final.png create mode 100644 training/output/patch_gt.png create mode 100644 training/output/patch_tool.png create mode 100644 training/output/patch_tool_fixed.png create mode 100644 training/output/test_debug.png create mode 100644 training/output/test_sync.png create mode 100644 training/output/tool_output.png create mode 100644 training/pass1_3x5x3.pth create mode 100644 training/patch_32x32.png create mode 100644 training/target_1/img_000.png create mode 100644 training/target_1/img_001.png create mode 100644 training/target_1/img_002.png create mode 100644 training/target_1/img_003.png create mode 100644 training/target_1/img_004.png create mode 100644 training/target_1/img_005.png create mode 100644 training/target_1/img_006.png create mode 100644 training/target_1/img_007.png create mode 100644 training/target_2/img_000.png create mode 100644 training/target_2/img_001.png create mode 100644 training/target_2/img_002.png create mode 100644 training/target_2/img_003.png create mode 100644 training/target_2/img_004.png create mode 100644 training/target_2/img_005.png create mode 100644 training/target_2/img_006.png create mode 100644 training/target_2/img_007.png diff --git a/LOG.txt b/LOG.txt new file mode 100644 index 0000000..ad03d6a --- /dev/null +++ b/LOG.txt @@ -0,0 +1,28 @@ + +thread '' (18683700) panicked at src/lib.rs:2426:38: +invalid device +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + +thread '' (18683700) panicked at library/core/src/panicking.rs:230:5: +panic in a function that cannot unwind +stack backtrace: + 0: 0x101ad75e0 - ::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. diff --git a/go.sh b/go.sh new file mode 100644 index 0000000..1f2fc26 --- /dev/null +++ b/go.sh @@ -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 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 new file mode 100644 index 0000000..de86e19 Binary files /dev/null and b/test/toto.png differ 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 { + var pos = array, 3>( + vec2(-1.0, -1.0), vec2(3.0, -1.0), vec2(-1.0, 3.0) + ); + return vec4(pos[i], 0.0, 1.0); +} + +@fragment fn fs_main(@builtin(position) p: vec4) -> @location(0) vec4 { + return vec4(1.0, 0.0, 0.0, 1.0); // Solid red +} diff --git a/tmp/layer_0.png b/tmp/layer_0.png new file mode 100644 index 0000000..9e2e35c Binary files /dev/null and b/tmp/layer_0.png differ diff --git a/tmp/layer_1.png b/tmp/layer_1.png new file mode 100644 index 0000000..16b1a28 Binary files /dev/null and b/tmp/layer_1.png differ diff --git a/toto.png b/toto.png new file mode 100644 index 0000000..62aa745 Binary files /dev/null and b/toto.png differ diff --git a/training/output/ground_truth.png b/training/output/ground_truth.png new file mode 100644 index 0000000..afa06f6 Binary files /dev/null and b/training/output/ground_truth.png differ diff --git a/training/output/patch_final.png b/training/output/patch_final.png new file mode 100644 index 0000000..e38512b Binary files /dev/null and b/training/output/patch_final.png differ diff --git a/training/output/patch_gt.png b/training/output/patch_gt.png new file mode 100644 index 0000000..277175c Binary files /dev/null and b/training/output/patch_gt.png differ diff --git a/training/output/patch_tool.png b/training/output/patch_tool.png new file mode 100644 index 0000000..e38512b Binary files /dev/null and b/training/output/patch_tool.png differ diff --git a/training/output/patch_tool_fixed.png b/training/output/patch_tool_fixed.png new file mode 100644 index 0000000..e38512b Binary files /dev/null and b/training/output/patch_tool_fixed.png differ diff --git a/training/output/test_debug.png b/training/output/test_debug.png new file mode 100644 index 0000000..e38512b Binary files /dev/null and b/training/output/test_debug.png differ diff --git a/training/output/test_sync.png b/training/output/test_sync.png new file mode 100644 index 0000000..e38512b Binary files /dev/null and b/training/output/test_sync.png differ diff --git a/training/output/tool_output.png b/training/output/tool_output.png new file mode 100644 index 0000000..3fcec54 Binary files /dev/null and b/training/output/tool_output.png differ diff --git a/training/pass1_3x5x3.pth b/training/pass1_3x5x3.pth new file mode 100644 index 0000000..a7fa8e3 Binary files /dev/null and b/training/pass1_3x5x3.pth differ diff --git a/training/patch_32x32.png b/training/patch_32x32.png new file mode 100644 index 0000000..a665065 Binary files /dev/null and b/training/patch_32x32.png differ diff --git a/training/target_1/img_000.png b/training/target_1/img_000.png new file mode 100644 index 0000000..5a8ae80 Binary files /dev/null and b/training/target_1/img_000.png differ diff --git a/training/target_1/img_001.png b/training/target_1/img_001.png new file mode 100644 index 0000000..c4ac5d0 Binary files /dev/null and b/training/target_1/img_001.png differ diff --git a/training/target_1/img_002.png b/training/target_1/img_002.png new file mode 100644 index 0000000..e4bab4a Binary files /dev/null and b/training/target_1/img_002.png differ diff --git a/training/target_1/img_003.png b/training/target_1/img_003.png new file mode 100644 index 0000000..a98004a Binary files /dev/null and b/training/target_1/img_003.png differ diff --git a/training/target_1/img_004.png b/training/target_1/img_004.png new file mode 100644 index 0000000..c186d13 Binary files /dev/null and b/training/target_1/img_004.png differ diff --git a/training/target_1/img_005.png b/training/target_1/img_005.png new file mode 100644 index 0000000..95cfdd9 Binary files /dev/null and b/training/target_1/img_005.png differ diff --git a/training/target_1/img_006.png b/training/target_1/img_006.png new file mode 100644 index 0000000..d6bd187 Binary files /dev/null and b/training/target_1/img_006.png differ diff --git a/training/target_1/img_007.png b/training/target_1/img_007.png new file mode 100644 index 0000000..f4e3a9a Binary files /dev/null and b/training/target_1/img_007.png differ diff --git a/training/target_2/img_000.png b/training/target_2/img_000.png new file mode 100644 index 0000000..1d5aab9 Binary files /dev/null and b/training/target_2/img_000.png differ diff --git a/training/target_2/img_001.png b/training/target_2/img_001.png new file mode 100644 index 0000000..0eebab8 Binary files /dev/null and b/training/target_2/img_001.png differ diff --git a/training/target_2/img_002.png b/training/target_2/img_002.png new file mode 100644 index 0000000..827460c Binary files /dev/null and b/training/target_2/img_002.png differ diff --git a/training/target_2/img_003.png b/training/target_2/img_003.png new file mode 100644 index 0000000..988873c Binary files /dev/null and b/training/target_2/img_003.png differ diff --git a/training/target_2/img_004.png b/training/target_2/img_004.png new file mode 100644 index 0000000..5c3294f Binary files /dev/null and b/training/target_2/img_004.png differ diff --git a/training/target_2/img_005.png b/training/target_2/img_005.png new file mode 100644 index 0000000..b919c76 Binary files /dev/null and b/training/target_2/img_005.png differ diff --git a/training/target_2/img_006.png b/training/target_2/img_006.png new file mode 100644 index 0000000..8a43c33 Binary files /dev/null and b/training/target_2/img_006.png differ diff --git a/training/target_2/img_007.png b/training/target_2/img_007.png new file mode 100644 index 0000000..5cd33da Binary files /dev/null and b/training/target_2/img_007.png differ -- cgit v1.2.3