diff --git a/naga/src/back/glsl/mod.rs b/naga/src/back/glsl/mod.rs index 9301cbdb0..ef1621cfb 100644 --- a/naga/src/back/glsl/mod.rs +++ b/naga/src/back/glsl/mod.rs @@ -1968,7 +1968,7 @@ impl<'a, W: Write> Writer<'a, W> { } writeln!(self.out, "{level}}}")?; - self.write_barrier(crate::Barrier::WORK_GROUP, level)?; + self.write_control_barrier(crate::Barrier::WORK_GROUP, level)?; } Ok(()) @@ -2512,8 +2512,11 @@ impl<'a, W: Write> Writer<'a, W> { // keyword which ceases all further processing in a fragment shader, it's called OpKill // in spir-v that's why it's called `Statement::Kill` Statement::Kill => writeln!(self.out, "{level}discard;")?, - Statement::ControlBarrier(flags) | Statement::MemoryBarrier(flags) => { - self.write_barrier(flags, level)?; + Statement::ControlBarrier(flags) => { + self.write_control_barrier(flags, level)?; + } + Statement::MemoryBarrier(flags) => { + self.write_memory_barrier(flags, level)?; } // Stores in glsl are just variable assignments written as `pointer = value;` Statement::Store { pointer, value } => { @@ -2527,14 +2530,14 @@ impl<'a, W: Write> Writer<'a, W> { // GLSL doesn't have pointers, which means that this backend needs to ensure that // the actual "loading" is happening between the two barriers. // This is done in `Emit` by never emitting a variable name for pointer variables - self.write_barrier(crate::Barrier::WORK_GROUP, level)?; + self.write_control_barrier(crate::Barrier::WORK_GROUP, level)?; let result_name = Baked(result).to_string(); write!(self.out, "{level}")?; // Expressions cannot have side effects, so just writing the expression here is fine. self.write_named_expr(pointer, result_name, result, ctx)?; - self.write_barrier(crate::Barrier::WORK_GROUP, level)?; + self.write_control_barrier(crate::Barrier::WORK_GROUP, level)?; } // Stores a value into an image. Statement::ImageStore { @@ -4912,9 +4915,19 @@ impl<'a, W: Write> Writer<'a, W> { Ok(()) } - /// Issue a memory barrier. Please note that to ensure visibility, - /// OpenGL always requires a call to the `barrier()` function after a `memoryBarrier*()` - fn write_barrier(&mut self, flags: crate::Barrier, level: back::Level) -> BackendResult { + /// Issue a control barrier. + fn write_control_barrier( + &mut self, + flags: crate::Barrier, + level: back::Level, + ) -> BackendResult { + self.write_memory_barrier(flags, level)?; + writeln!(self.out, "{level}barrier();")?; + Ok(()) + } + + /// Issue a memory barrier. + fn write_memory_barrier(&mut self, flags: crate::Barrier, level: back::Level) -> BackendResult { if flags.contains(crate::Barrier::STORAGE) { writeln!(self.out, "{level}memoryBarrierBuffer();")?; } @@ -4927,7 +4940,6 @@ impl<'a, W: Write> Writer<'a, W> { if flags.contains(crate::Barrier::TEXTURE) { writeln!(self.out, "{level}memoryBarrierImage();")?; } - writeln!(self.out, "{level}barrier();")?; Ok(()) } diff --git a/naga/tests/out/glsl/spv-barrier.main.Compute.glsl b/naga/tests/out/glsl/spv-barrier.main.Compute.glsl index c97f12429..a5be41cf0 100644 --- a/naga/tests/out/glsl/spv-barrier.main.Compute.glsl +++ b/naga/tests/out/glsl/spv-barrier.main.Compute.glsl @@ -8,19 +8,16 @@ layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; void function() { memoryBarrierShared(); - barrier(); memoryBarrierShared(); barrier(); memoryBarrierBuffer(); memoryBarrierImage(); - barrier(); memoryBarrierBuffer(); memoryBarrierImage(); barrier(); memoryBarrierBuffer(); memoryBarrierShared(); memoryBarrierImage(); - barrier(); memoryBarrierBuffer(); memoryBarrierShared(); memoryBarrierImage(); diff --git a/naga/tests/out/glsl/spv-subgroup-barrier.main.Compute.glsl b/naga/tests/out/glsl/spv-subgroup-barrier.main.Compute.glsl index d551d5b1c..ae9619867 100644 --- a/naga/tests/out/glsl/spv-subgroup-barrier.main.Compute.glsl +++ b/naga/tests/out/glsl/spv-subgroup-barrier.main.Compute.glsl @@ -8,7 +8,6 @@ layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; void function() { subgroupMemoryBarrier(); - barrier(); subgroupMemoryBarrier(); barrier(); return;