#Very poor performance when drawing small 2d tilemaps.

1 messages · Page 1 of 1 (latest)

main crater
#

So I was experimenting with some Simplex noise map generation. I've created simple test map 128x128 tiles. For each point in the noise array I create a SpriteBundle just to render simple sprite.

if noise_data[x][y] >= 5.5 {
commands.spawn((SpriteBundle {
texture: asset_server.load("plus_button.png"),
transform: Transform {
translation: Vec3::new((x * TILE_SZE) as f32, (y * TILE_SZE) as f32, GROUND_LAYER),
..default()
},
..default()
},
Tile,
));
} else {
commands.spawn((SpriteBundle {
texture: asset_server.load("steak.png"),
transform: Transform {
translation: Vec3::new((x * TILE_SZE) as f32, (y * TILE_SZE) as f32, GROUND_LAYER),
..default()
},
..default()
},
Tile,
));
}

Map size of 128x128 tiles is 16384 sprites, which shouldn't be any issue at all for a multithreaded ecs engine like bevy but I'm getting like 35fps.
So I tested the same map generation in LibGdx which is singlethreaded java game framework. And I've created 256x256 map which is 65536 sprites and I get stable 144fps(monitor refresh rate) without issues.
What am I doing wrong in Bevy ? This doesn't seem right.

unkempt jewel
#

I'm no pro I actually just started, but I made one of the same mistakes you have here (may not be your main issue). Right now you're re-loading the same asset for each and every tile

#

You'd be better off loading it once and just re-using the handle each time

main crater
#

Well yes but that's only Startup system so it runs once before it starts rendering tiles so technically it shouldn't impact performance. Also there are only two textures

#

Also from what I understand when you call asset_server.load it load the texture and if you call it again it just returns handle to already loaded texture

unkempt jewel
#

Also from what I understand when you call asset_server.load it load the texture and if you call it again it just returns handle to already loaded texture

Hmm I guess I would have to check the source code, the tutorial I watched explicitely created an asset handler to avoid calling load on the same item repeatedly, but it may just have been out of date and not necessary in newer bevy versions.

main crater
#

From Bevy docs:
This queues the asset loading to happen in the background, and return a handle. The asset will take some time to become available. You cannot access the actual data immediately in the same system, but you can use the handle.

You can spawn entities like your 2D sprites, 3D models, and UI, using the handle, even before the asset has loaded. They will just "pop in" later, when the asset becomes ready.

Note that it is OK to call asset_server.load(…) as many times as you want, even if the asset is currently loading, or already loaded. It will just provide you with the same handle. Every time you call it, it will just check the status of the asset, begin loading it if needed, and give you a handle.

unkempt jewel
#

Huh interesting, well at least I learned something haha. Sorry I couldn't be of help.

fair wharf
#

do you compile bevy with optimizations?

main crater
#

Yes, everything that was in docs

fair wharf
#

that is weird, i can't spot anything in the code snippet you posted above though

agile path
main crater
#

Well I think it's just bevy rendering system. I've experimented a bit with SFML and EnTT and created the exact same tilemap. After setting map size to 128x128 tiles sfml struggled at around 40FPS. Meanwhile Libgdx is rendering tilemap 256x256 tiles without any lag with stable 144 fps which is my monitor refresh rate. The only differnce between Bevy, SFML and Libgdx I can think of is Sprite batching. Libgdx is the only one using Sprite batching by default. I'm kinda surprised Bevy doesn't use batching by default.

unkempt jewel
fair wharf
fair wharf
# fair wharf nope

spawn batch only effects the first frame, its just a faster way to spawn a large number of entities

#

bevy also automatically batches sprites

umbral prism
#
  • make sure you are running in release
  • use tracy to find out what is taking a long time, anything else is just speculation
main crater
#

Nobody is going to be using release to develop a game with how slow rust compile times are. Everytime you want to test a change in a game you are going to spend 10+ minutes to build in release mode ? Rendering is taking all that time in a frame. Not sure why is it so slow, I've spent 2 days reading through docs, I don't even have anything else in my code, it's literally generating simplex noise and spawning entities with 2 textures as shown in my code above. Bevy seems to have a lot of problems if you are using AMD gpu. Fullscreen doesn't work, bunch of erros in the console even with the simplest bevy app that's empty.

agile path
#

I'm not sure about the AMD gpu stuff, but if I do cargo run --release, it compiles in around 5 seconds, which is way faster than the normal debug, which is around 20 seconds. Also if you upload it to github or something, I can download and test it to see if it is the AMD gpu.

fair wharf
#

i have no such problem on an amd igpu

main crater
#

Firs of all, this is how my Bevy console looks like fresh after installing Bevy, no code at all, just simplest possible app:

#

So I use this line:
env::set_var("WGPU_BACKEND", "vulkan");

I did test of course if this has any negative impact on performance but nope, it's the same with or without that line

#

Second of all, no matter what I try the fullscreen mode crashes the app with this error:

#

There are some serious problems from the very start and I suspect this might be cause for the super slow rendering performance

#

I've updated all my drivers, made sure vulkan drivers are up to date but it didn't change anything

main crater
fair wharf
#

reading that image is hard

#

and that is totally not supposed to show so many errors

main crater
#

And for the fullscreen crash error:
2024-05-08T09:56:05.077903Z INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Windows 11 Home", kernel: "22631", cpu: "AMD Ryzen 5 3600 6-Core Processor", core_count: "6", memory: "15.9 GiB" }
thread 'Compute Task Pool (0)' panicked at C:\Users\Astamor.cargo\registry\src\index.crates.io-6f17d22bba15001f\wgpu-0.19.3\src\backend\wgpu_core.rs:724:18:
Error in Surface::configure: Validation Error

Caused by:
Parent device is lost

note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
Encountered a panic in system bevy_render::view::window::create_surfaces!
thread 'Compute Task Pool (0)' panicked at C:\Users\Astamor.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_render-0.13.1\src\pipelined_rendering.rs:49:67:
called Result::unwrap() on an Err value: RecvError
error: process didn't exit successfully: target\debug\bevy-project.exe (exit code: 101)

fair wharf
#

huh, try checking your gpu driver for updates?

main crater
#

Did that already

fair wharf
#

what exact version of bevy do you use

main crater
#

I also did some googling and didn't find much, some people complaining that on amd cards Bevy is actin weird

main crater
fair wharf
main crater
#

Well the fullscreen crash isn't really big issue, I just used Borderless and it works, the problem still is bunch of errors in the console and super slow performance. The errors can be supressed but it worries me that when I invest months of time into a project and somewhere along the way those erros turn out to be problematic and cause unexpected problems

fair wharf
#

if either of the problems are around on 0.13.2 i would file a bug report

fair wharf
main crater
#

Well I will just wiat for 0.13.2 then and see what happens, is there any release date ?

fair wharf
#

like two weeks ago

#

over a month actually

main crater
#

Oh, ok, well, thank you for your time and effort

fair wharf
#

if cargo doesn't find 0.13.2 you need to run cargo update

main crater
#

Oh it did find 0.13.2, updating now

#

FullScreen still crashing

fair wharf
#

okay, thats bad

main crater
#

Still bunch of erros in the console

fair wharf
#

please make a bug report

main crater
#

And still between 28-35pfs

umbral prism
#

Can't really do anything about perf if you don't profile the application. Saying it's in "rendering" doesn't tell us much. A profile will help determine where the slowdown is happening.

#

What do the logs say about your hardware when you start the application? Should say what backend, driver, and HW info it sees. I see the systeminfo one above, but not the rendering one.

umbral prism
#

But that really depends on how the game has been structured and what code you touched.

#

But yeah, those crashes and errors are super suspect, I haven't seen that before. Usually that's a driver problem, but you said you updated.

agile path
#

I mean depending on how many errors there are, it could be because of the insane amount of prints, that the game is slowing down?

halcyon fog
#

The directx errors are a known issue with bevy's dependencies. I'm actually surprised it's using directx12, it should be defaulting to vulkan afaik. It'll be fixed in a future release at some point. The crash should not be happening and should be reported to bevy. If parent device is lost, something went wrong and your GPU crashed.

main crater
#

Sorry for late response. I've opened issue on Bevy github. I've also tried the winit window example, that produced no errors and wgpu hello_triangle example this caused bunch of vulkan errors. So I gues it's related to wgpu ?

main crater
#

Also I've used the Chrome tracing and it looks something like this, not sure what to make of it

umbral prism
#

what is this span, at the bottom:

#

It might (?) also be extraction. I think we are getting some improvements related to that in 0.14.

main crater
#

Problem solved. I mean one of the problems which was performance, it was because of that crate for world inspector egui. After removing it from the project Bevy now renders 256x256 map, which is 65000+ sprites with 144 fps(monitor refresh rate). Still, console errors and fullscreen crashing remain