Skip to content

Unbreak shadows by retaining work item buffers corresponding to ExtractedViews, not ViewTargets.#17039

Merged
alice-i-cecile merged 2 commits intobevyengine:mainfrom
pcwalton:delete-extracted-views
Dec 30, 2024
Merged

Unbreak shadows by retaining work item buffers corresponding to ExtractedViews, not ViewTargets.#17039
alice-i-cecile merged 2 commits intobevyengine:mainfrom
pcwalton:delete-extracted-views

Conversation

@pcwalton
Copy link
Contributor

@pcwalton pcwalton commented Dec 30, 2024

OK, so this is tricky. Every frame, delete_old_work_item_buffers deletes the mesh preprocessing index buffers (a.k.a. work item buffers) for views that don't have ViewTargets. This was always wrong for shadow map views, as shadow maps only have ExtractedView components, not ViewTargets. However, before #16836, the problem was masked, because uploading the mesh preprocessing index buffers for shadow views had already completed by the time delete_old_work_item_buffers ran. But PR #16836 moved delete_old_work_item_buffers from the ManageViews phase to PrepareResources, which runs before write_batched_instance_buffers uploads the work item buffers to the GPU.

This itself isn't wrong, but it exposed the bug, because now it's possible for work item buffers to get deleted before they're uploaded in write_batched_instance_buffers. This is actually intermittent! It's possible for the old work item buffers to get deleted, and then recreated in batch_and_prepare_binned_render_phase, which runs during PrepareResources as well, and under that system ordering, there will be no problem other than a little inefficiency arising from recreating the buffers every frame. But, if
delete_old_work_item_buffers runs after
batch_and_prepare_render_phase, then the work item buffers corresponding to shadow views will get deleted, and then the shadows will disappear.

The fact that this is racy is what made it look like #16922 solved the issue. In fact, it didn't: it just perturbed the ordering on the build bots enough that the issue stopped appearing. However, on my system, the shadows still don't appear with #16922.

This commit solves the problem by making delete_old_work_item_buffers look at ExtractedViews, not ViewTargets, preventing work item buffers corresponding to live shadow map views from being deleted.

`ExtractedView`s, not `ViewTarget`s.

OK, so this is tricky. Every frame, `delete_old_work_item_buffers`
deletes the mesh preprocessing index buffers (a.k.a. work item buffers)
for views that don't have `ViewTarget`s. This was always wrong for
shadow map views, as shadow maps only have `ExtractedView` components,
not `ViewTarget`s. However, before bevyengine#16836, the problem was masked,
because uploading the mesh preprocessing index buffers for shadow views
had already completed by the time `delete_old_work_item_buffers` ran.
But PR bevyengine#16836 moved `delete_old_work_item_buffers` from the
`ManageViews` phase to `PrepareResources`, which runs before
`write_batched_instance_buffers` uploads the work item buffers to the
GPU.

This itself isn't wrong, but it exposed the bug, because now it's
possible for work item buffers to get deleted before they're uploaded in
`write_batched_instance_buffers`. This is actually intermittent! It's
possible for the old work item buffers to get deleted, and then
*recreated* in `batch_and_prepare_binned_render_phase`, which runs
during `PrepareResources` as well, and under that system ordering, there
will be no problem other than a little inefficiency arising from
recreating the buffers every frame. But, if
`delete_old_work_item_buffers` runs *after*
`batch_and_prepare_render_phase`, then the work item buffers
corresponding to shadow views will get deleted, and then the shadows
will disappear.

The fact that this is racy is what made it look like bevyengine#16922 solved the
issue. In fact, it didn't solve the issue: it just perturbed the
ordering on the build bots enough that the issue stopped appearing.
However, on my system, the shadows still don't appear with bevyengine#16922.

This commit solves the problem by making `delete_old_work_item_buffers`
look at `ExtractedView`s, not `ViewTarget`s, preventing work item
buffers corresponding to live shadow map views from being deleted.
@pcwalton pcwalton added P-Regression Functionality that used to work but no longer does. Add a test for this! A-Rendering Drawing game state to the screen S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Dec 30, 2024
@alice-i-cecile alice-i-cecile added this to the 0.16 milestone Dec 30, 2024
Copy link
Contributor

@MalekiRe MalekiRe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A rendering PR I actually understand!
LGTM

@BenjaminBrienen
Copy link
Contributor

A rendering PR I actually understand!
LGTM

I know, right?! 😆

@BenjaminBrienen BenjaminBrienen added C-Bug An unexpected or incorrect behavior S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Dec 30, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Dec 30, 2024
Merged via the queue into bevyengine:main with commit fde7968 Dec 30, 2024
ecoskey pushed a commit to ecoskey/bevy that referenced this pull request Jan 6, 2025
…actedView`s, not `ViewTarget`s. (bevyengine#17039)

OK, so this is tricky. Every frame, `delete_old_work_item_buffers`
deletes the mesh preprocessing index buffers (a.k.a. work item buffers)
for views that don't have `ViewTarget`s. This was always wrong for
shadow map views, as shadow maps only have `ExtractedView` components,
not `ViewTarget`s. However, before bevyengine#16836, the problem was masked,
because uploading the mesh preprocessing index buffers for shadow views
had already completed by the time `delete_old_work_item_buffers` ran.
But PR bevyengine#16836 moved `delete_old_work_item_buffers` from the
`ManageViews` phase to `PrepareResources`, which runs before
`write_batched_instance_buffers` uploads the work item buffers to the
GPU.

This itself isn't wrong, but it exposed the bug, because now it's
possible for work item buffers to get deleted before they're uploaded in
`write_batched_instance_buffers`. This is actually intermittent! It's
possible for the old work item buffers to get deleted, and then
*recreated* in `batch_and_prepare_binned_render_phase`, which runs
during `PrepareResources` as well, and under that system ordering, there
will be no problem other than a little inefficiency arising from
recreating the buffers every frame. But, if
`delete_old_work_item_buffers` runs *after*
`batch_and_prepare_render_phase`, then the work item buffers
corresponding to shadow views will get deleted, and then the shadows
will disappear.

The fact that this is racy is what made it look like bevyengine#16922 solved the
issue. In fact, it didn't: it just perturbed the ordering on the build
bots enough that the issue stopped appearing. However, on my system, the
shadows still don't appear with bevyengine#16922.

This commit solves the problem by making `delete_old_work_item_buffers`
look at `ExtractedView`s, not `ViewTarget`s, preventing work item
buffers corresponding to live shadow map views from being deleted.
mrchantey pushed a commit to mrchantey/bevy that referenced this pull request Feb 4, 2025
…actedView`s, not `ViewTarget`s. (bevyengine#17039)

OK, so this is tricky. Every frame, `delete_old_work_item_buffers`
deletes the mesh preprocessing index buffers (a.k.a. work item buffers)
for views that don't have `ViewTarget`s. This was always wrong for
shadow map views, as shadow maps only have `ExtractedView` components,
not `ViewTarget`s. However, before bevyengine#16836, the problem was masked,
because uploading the mesh preprocessing index buffers for shadow views
had already completed by the time `delete_old_work_item_buffers` ran.
But PR bevyengine#16836 moved `delete_old_work_item_buffers` from the
`ManageViews` phase to `PrepareResources`, which runs before
`write_batched_instance_buffers` uploads the work item buffers to the
GPU.

This itself isn't wrong, but it exposed the bug, because now it's
possible for work item buffers to get deleted before they're uploaded in
`write_batched_instance_buffers`. This is actually intermittent! It's
possible for the old work item buffers to get deleted, and then
*recreated* in `batch_and_prepare_binned_render_phase`, which runs
during `PrepareResources` as well, and under that system ordering, there
will be no problem other than a little inefficiency arising from
recreating the buffers every frame. But, if
`delete_old_work_item_buffers` runs *after*
`batch_and_prepare_render_phase`, then the work item buffers
corresponding to shadow views will get deleted, and then the shadows
will disappear.

The fact that this is racy is what made it look like bevyengine#16922 solved the
issue. In fact, it didn't: it just perturbed the ordering on the build
bots enough that the issue stopped appearing. However, on my system, the
shadows still don't appear with bevyengine#16922.

This commit solves the problem by making `delete_old_work_item_buffers`
look at `ExtractedView`s, not `ViewTarget`s, preventing work item
buffers corresponding to live shadow map views from being deleted.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior P-Regression Functionality that used to work but no longer does. Add a test for this! S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants