Bevy: MismatchedDynamicOffsetCount error

Created on 12 Aug 2020  路  11Comments  路  Source: bevyengine/bevy

OS: macOS Catalina
bevy: master
rust: 1.45.2

To get familiar with bevy, I decided to try and mash together some examples, however spawning a TextComponent and a SpriteSheetComponents causes the program to crash. The backtrace makes it difficult to understand what is going on.

use bevy::prelude::*;

fn main() {
    App::build()
        .add_resource(WindowDescriptor {
            title: "Ironbound".to_string(),
            width: 1280,
            height: 720,
            vsync: true,
        })
        .add_default_plugins()
        .add_startup_system(setup_player.system())
        .add_startup_system(setup_ui.system())
        .add_system(animate_sprite_system.system())
        .run();
}

fn animate_sprite_system(
    texture_atlases: Res<Assets<TextureAtlas>>,
    mut query: Query<(&mut Timer, &mut TextureAtlasSprite, &Handle<TextureAtlas>)>,
) {
    for (mut timer, mut sprite, texture_atlas_handle) in &mut query.iter() {
        if timer.finished {
            sprite.index = (((sprite.index + 1) % 8) + 13) as u32;
            timer.reset();
        }
    }
}


fn setup_player(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    mut textures: ResMut<Assets<Texture>>,
    mut texture_atlases: ResMut<Assets<TextureAtlas>>,
) {
    let texture_handle = asset_server
        .load_sync(&mut textures, "assets/sprites/adventurer.png")
        .unwrap();
    let texture = textures.get(&texture_handle).unwrap();
    let texture_atlas = TextureAtlas::from_grid(texture_handle, texture.size, 13, 16);
    let texture_atlas_handle = texture_atlases.add(texture_atlas);

    commands
        .spawn(Camera2dComponents::default())
        .spawn(SpriteSheetComponents {
            ..Default::default()
        })
        .with(Timer::from_seconds(0.1));
}

fn setup_ui(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
) {
    commands
        // ui camera
        .spawn(UiCameraComponents::default())
        .spawn(TextComponents {
            text: Text {
                value: "Button".to_string(),
                font: asset_server.load("assets/fonts/m5x7.ttf").unwrap(),
                style: TextStyle {
                    font_size: 40.0,
                    color: Color::rgb(0.8, 0.8, 0.8),
                },
            },
            ..Default::default()
        });
}

Output:

RUST_BACKTRACE=1 cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.39s
    Running `target/debug/ironbound`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: MismatchedDynamicOffsetCount { actual: 0, expected: 2 }', /Users/arlyon/.cargo/registry/src/github.com-1ecc6299db9ec823/cart-tmp-wgc-0.1.0/src/command/render.rs:892:21
stack backtrace:
0: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
1: core::fmt::write
2: std::io::Write::write_fmt
3: std::panicking::default_hook::{{closure}}
4: std::panicking::default_hook
5: std::panicking::rust_panic_with_hook
6: rust_begin_unwind
7: core::panicking::panic_fmt
8: core::option::expect_none_failed
9: core::result::Result<T,E>::unwrap
10: cart_tmp_wgc::command::render::<impl cart_tmp_wgc::hub::Global<G>>::command_encoder_run_render_pass_impl
11: cart_tmp_wgc::command::render::<impl cart_tmp_wgc::hub::Global<G>>::command_encoder_run_render_pass
12: cart_tmp_wgpu::backend::direct::<impl cart_tmp_wgpu::Context for cart_tmp_wgc::hub::Global<cart_tmp_wgc::hub::IdentityManagerFactory>>::command_encoder_end_render_pass
13: <cart_tmp_wgpu::RenderPass as core::ops::drop::Drop>::drop
14: core::ptr::drop_in_place
15: core::ptr::drop_in_place
16: <bevy_wgpu::renderer::wgpu_render_context::WgpuRenderContext as bevy_render::renderer::render_context::RenderContext>::begin_pass
17: <bevy_render::render_graph::nodes::pass_node::PassNode<Q> as bevy_render::render_graph::node::Node>::update
18: bevy_wgpu::renderer::wgpu_render_graph_executor::WgpuRenderGraphExecutor::execute
19: bevy_wgpu::wgpu_renderer::WgpuRenderer::run_graph
20: bevy_wgpu::wgpu_renderer::WgpuRenderer::update
21: bevy_wgpu::wgpu_render_system::{{closure}}
22: <F as bevy_ecs::system::into_system::ThreadLocalSystemFn>::run
23: <F as bevy_ecs::system::into_system::IntoThreadLocalSystem>::thread_local_system::{{closure}}
24: <bevy_ecs::system::into_system::SystemFn<State,F,ThreadLocalF,Init,SetArchetypeAccess> as bevy_ecs::system::system::System>::run_thread_local
25: bevy_ecs::schedule::parallel_executor::ExecutorStage::run
26: bevy_ecs::schedule::parallel_executor::ParallelExecutor::run
27: bevy_app::app::App::update
28: bevy_winit::winit_runner::{{closure}}
29: <alloc::boxed::Box<F> as core::ops::function::FnMut<A>>::call_mut
30: <cart_tmp_winit::platform_impl::platform::app_state::EventLoopHandler<T> as cart_tmp_winit::platform_impl::platform::app_state::EventHandler>::handle_nonuser_event
31: cart_tmp_winit::platform_impl::platform::app_state::Handler::handle_nonuser_event
32: cart_tmp_winit::platform_impl::platform::app_state::AppState::cleared
33: cart_tmp_winit::platform_impl::platform::observer::control_flow_end_handler
34: __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
35: __CFRunLoopDoObservers
36: __CFRunLoopRun
37: CFRunLoopRunSpecific
38: RunCurrentEventLoopInMode
39: ReceiveNextEventCommon
40: _BlockUntilNextEventMatchingListInModeWithFilter
41: _DPSNextEvent
42: -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:]
43: -[NSApplication run]
44: <() as objc::message::MessageArguments>::invoke
45: objc::message::platform::send_unverified
46: cart_tmp_winit::platform_impl::platform::event_loop::EventLoop<T>::run_return
47: cart_tmp_winit::platform_impl::platform::event_loop::EventLoop<T>::run
48: cart_tmp_winit::event_loop::EventLoop<T>::run
49: bevy_winit::winit_runner
50: core::ops::function::Fn::call
51: <alloc::boxed::Box<F> as core::ops::function::Fn<A>>::call
52: bevy_app::app::App::run
53: bevy_app::app_builder::AppBuilder::run
54: ironbound::main
55: std::rt::lang_start::{{closure}}
56: std::rt::lang_start_internal
57: std::rt::lang_start
58: main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
bug crash rendering

All 11 comments

Worked a bit on the Text+SpriteSheetComponent crash.
This is linked to the fact that both uses the same SpriteSheetPipeline, but one is doing a Pipeline Specialization with no dynamic bindings, and the other with two dynamic bindings.
When both are run together, at some point the render either expect 0 dynamic and receive 2 , or expect 2 and receives 0.

Declaring Text draw pipeline specialization with same dynamic bindings as for spritesheet and making the shared buffer that text uses dynamic, allow to draw Text+SpriteSheet, but this does not seem to be a real fix, just a workaround.
This is what I have implemented in https://github.com/Bobox214/bevy/tree/tentative_134

Not sure what direction is the correct fix.
It seems through discord discussion that shared buffers isn't a good solution and some change to render is looked at.

In any case I think the full fix or update is beyond my current knowledge, so I'll let other look into it

@Bobox214 out of interest what OS are you on? I take it from your description that this is reproducible on more than just macOS?

I am on Linux, and I don鈥檛 think this OS specific.

Auto-closed due to the issue references in #247. This isn't resolved yet.

So I was able to "fix" the issue by creating another pipeline / render node / and component that mirrored a TextureAtlasSprite. It appears that once a pipeline is set with dynamic bindings, all components that are drawn on it must have dynamic bindings (@Bobox214's effort shows that as well).

You can have a look here, https://github.com/bevyengine/bevy/compare/master...insrcd:master (I also had to revert the changes from #135 because it was causing very strange redraw issues). Hope this information helps.

Also, my main dev environment is Windows 10, so it does not appear to be a platform specific issue.

Did #247 fix this for you?

I ran into this just now - so #247 doesn't fix it

@insrcd What are the shortcomings you see in your patch that motivated you to describe it as a 'fix' rather than a fix. It doesn't seem unreasonable to me to have the text be a separate pipeline from sprite sheets. The two are different enough in terms of how they're generally going to be used (I'd imagine text would use NEAREST filter mode vs LINEAR for sprites, etc)

@chrisburnor I don鈥檛 know enough about rendering to really know if what I did was correct or advisable. It was just the result of me deep diving i to the rendering pipeline code and finding the root cause. I鈥檒l gladly throw it up as a PR if people with more experience believe it is an approach that works.

It also undoes #247, and I wasn鈥檛 comfortable with undoing an accepted PR to get things to work for the specific thing I was doing.

I have been using my fork in the game I鈥檓 developing g with no issues (including despawning components).

@insrcd I'm also using your fix that I keep up to date with master here, works for me with no known issue...

Yea it does appear to still be an issue in 0.2.0+, I'll get a PR together.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gdox picture gdox  路  13Comments

cart picture cart  路  18Comments

aclysma picture aclysma  路  17Comments

cart picture cart  路  14Comments

coolit picture coolit  路  22Comments