Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async resource loading refactor & Terrain improvements #223

Merged
merged 53 commits into from
Aug 31, 2024

Conversation

Duttenheim
Copy link
Contributor

Fixes a bunch of issues with the terrain and resource loading.

Resource loading is now deterministic when asynchronous. Resources are loaded in their own timeline without having to sync with the main thread until the resource loads are submitted to the queue. Before, this wasn't necessarily the case as resources would write to a shared state using mutexes and would use the immediate command buffers to submit transfer and handover operations.

Terrain tiles don't get stuck in an invalid state anymore, eliminating artefacts sometimes seen when the camera isn't moving rapidly (those may persist).

Terrain memory footprint has been reduced to 23% by using BC compression for the texture atlases. The low resolution fallback textures also deserves to be BC compressed, but it's significantly more tricky given that

This is needed for images where we want to support compute writing for formats which don't support it. The initial image create will disable the implicit texture view from setting up that flag, such that an explicit view with a storage-supported format can be used in its stead.

Another solution for this would be to permanently separate Texture and TextureView, and have the TextureView use explicit usage masks.
Resource loaders are now responsible for allocating their own command buffers for uploads, handovers and whatnot, and then adding them to a list for submission. This removes intermittent locks and should fix a bug where resource loaders don't appropriately wait for the right submission index to mark resources as finished.
This makes all of our resource loaders completely async, and with just a handover of their command buffers for execution.
Made the deferred command buffer deletion more explicit, by renaming it to DeferredDestroyCmdBuffer
The new system produces outputs from each loader thread which are then fed back to the main thread for further processing. Any partially completed jobs will be reissued with the bits that are left. No loader state is allowed to be changed in the job, eliminating any race conditions. The new system also provides a significantly more robust way of knowing when a resource is done.

The texture and mesh loaders have been significantly changed to record their own transfer commands in the threads. The submission of these commands is handed over to the main thread, and the subsequent cleanup of said commands happens on the threads at a later stage. This way we don't run into multiple threads accessing the command buffer pools. When the deletion happens, the output from the loader is that the resource is finished, thereby ending the streaming sequence.

TODO: LOD updates only run when a resource is finished loading. This prevents the loader from having to deal with multiple entries of the same resource out of order. This could be improved by guarding against unnecessary stream loads already on the main thread, with the loader output feeding back which LOD was successfully loaded last. It's not necessary to do so, but it might improve performance somewhat because resource loaders don't need to run on jobs which will produce no new output.
Previously, the graphics device would free up all upload slots each frame. With the new way we handle resources, which is fully async, these memory ranges will have to be freed up and flushed when we are actually done with them.

This change has the graphics device return the allocation to the user, which should then be managed by them to avoid upload memory getting permanently stuck. The texture loader and mesh loader take on this responsibility by retaining the allocation ranges when an upload is performed, and frees them up when the command buffer needing them is finished executing and is deleted.
@Duttenheim Duttenheim added category: graphics Graphics performance Performance improvements labels Aug 30, 2024
@Duttenheim Duttenheim self-assigned this Aug 30, 2024
@Duttenheim Duttenheim changed the title Terrain improvements Async resource loading refactor & Terrain improvements Aug 30, 2024
@Duttenheim Duttenheim added enhancement Improvements on already existing code category: concurrency Data/condition races fix Fixes a bug labels Aug 30, 2024
@Duttenheim Duttenheim merged commit ae4b535 into master Aug 31, 2024
4 checks passed
@Duttenheim Duttenheim deleted the terrain-improvements branch August 31, 2024 05:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: concurrency Data/condition races category: graphics Graphics enhancement Improvements on already existing code fix Fixes a bug performance Performance improvements
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant