Fix: Race condition when compute shader writes to texture. (#8527)

This commit is contained in:
Anton Kushakov 2025-11-16 18:29:41 +03:00 committed by GitHub
parent 07d4db5ab9
commit c78f944f2f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 15 additions and 5 deletions

View File

@ -163,6 +163,10 @@ By @SupaMaggie70Incorporated in [#8206](https://github.com/gfx-rs/wgpu/pull/8206
- Fixed a bug where the texture aspect was not passed through when calling `copy_texture_to_buffer` in WebGPU, causing the copy to fail for depth/stencil textures. By @Tim-Evans-Seequent in [#8445](https://github.com/gfx-rs/wgpu/pull/8445).
#### GLES
- Fix race when downloading texture from compute shader pass. By @SpeedCrash100 in [#8527](https://github.com/gfx-rs/wgpu/pull/8527)
#### hal
- `DropCallback`s are now called after dropping all other fields of their parent structs. By @jerzywilczek in [#8353](https://github.com/gfx-rs/wgpu/pull/8353)

View File

@ -311,11 +311,10 @@ impl crate::CommandEncoder for super::CommandEncoder {
let mut combined_usage = wgt::TextureUses::empty();
for bar in barriers {
// GLES only synchronizes storage -> anything explicitly
if !bar
.usage
.from
.contains(wgt::TextureUses::STORAGE_READ_WRITE)
{
// if shader writes to a texture then barriers should be placed
if !bar.usage.from.intersects(
wgt::TextureUses::STORAGE_READ_WRITE | wgt::TextureUses::STORAGE_WRITE_ONLY,
) {
continue;
}
// unlike buffers, there is no need for a concrete texture

View File

@ -1257,6 +1257,10 @@ impl super::Queue {
}
unsafe { gl.memory_barrier(flags) };
}
// because `STORAGE_WRITE_ONLY` and `STORAGE_READ_WRITE` are only states
// we can transit from due OpenGL memory barriers are used to make _subsequent_
// operations see changes from the _shader_ side. We filter out usage changes that are
// does not comes from the shader side in `transition_textures`
C::TextureBarrier(usage) => {
let mut flags = 0;
if usage.contains(wgt::TextureUses::RESOURCE) {
@ -1269,6 +1273,9 @@ impl super::Queue {
) {
flags |= glow::SHADER_IMAGE_ACCESS_BARRIER_BIT;
}
if usage.intersects(wgt::TextureUses::COPY_SRC) {
flags |= glow::PIXEL_BUFFER_BARRIER_BIT;
}
if usage.contains(wgt::TextureUses::COPY_DST) {
flags |= glow::TEXTURE_UPDATE_BARRIER_BIT;
}