[naga glsl-out] Split writes for memory/control barriers

This commit is contained in:
Phena Ildanach
2025-06-11 18:28:43 -05:00
committed by Teodor Tanasoaia
parent dd273fd7e2
commit 486a77d682
3 changed files with 21 additions and 13 deletions

View File

@@ -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(())
}

View File

@@ -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();

View File

@@ -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;