bevy icon indicating copy to clipboard operation
bevy copied to clipboard

Avoid reading the entire asset into memory during asset processing.

Open andriyDev opened this issue 1 month ago • 2 comments

Objective

  • When processing assets, we first read the whole asset into memory, then process the asset from that in-memory representation. This means that large assets may just not fit into memory causing much bigger issues (e.g., switching over to slow virtual memory).

Solution

  • Read the asset twice during processing: 1) once to determine the asset hash, 2) once to actually process the asset.

This means the processing code itself doesn't need to read the whole asset into memory at any point, meaning we can now process much bigger assets.

However, there are some risks. Asset sources which can't read chunks of an asset - which need to read the whole asset into memory anyway - now have to do so twice (not at the same time though). An example of this kind of asset source is the default Wasm source, or the HTTP asset source. In practice, I don't think this is a big issue - processing is likely to be happening on local assets anyway - it seems unlikely that users will want to download large assets from an HTTP asset source multiple times (which needs to happen any time you start the app, even ignoring this PR).

Testing

  • The processing tests all still pass.

andriyDev avatar Nov 24 '25 02:11 andriyDev

Nice step towards https://zeux.io/2025/09/30/billions-of-triangles-in-minutes/ !

Some questions:

  • What is the hash used for? And the duplicate reads is only for asset processing, and won't have any effect on release versions of games loading already-processed assets, right?
  • We still don't have a way to read a certain slice of bytes from the asset, right? E.g. parsing a GLTF file to find meshes in them, then reading the meshes one at a time from other parts of the file

JMS55 avatar Nov 24 '25 03:11 JMS55

@JMS55 Yup haha, I think you posted this a while ago in the Discord and it's been rattling around in my brain as something we simply can't do with Bevy today. I intend to fix that!

  • The hash is used when the processor initializes to determine whether an asset is up-to-date.
  • You are correct, the duplicate reads only matter during asset processing. This has no effect for loading already-processed assets.
  • Sorta. Currently Reader only requires AsyncRead and AsyncSeekForward. In theory, you could write a glTF loader that cleverly seeked in such a way that they never go backwards. That would be very painful though. So what I've been working on is to allow the loader to request features from the asset source. So a glTF loader could request the "seek from start" feature, and then its reader could do whatever seeks it needs - much simpler to work with. We'll see how it pans out!

andriyDev avatar Nov 24 '25 06:11 andriyDev