diff --git a/naga/src/back/glsl/mod.rs b/naga/src/back/glsl/mod.rs index 4c5a9d8cbc..d39ae5153d 100644 --- a/naga/src/back/glsl/mod.rs +++ b/naga/src/back/glsl/mod.rs @@ -911,7 +911,7 @@ impl<'a, W: Write> Writer<'a, W> { TypeInner::Image { mut dim, arrayed, - class, + mut class, } => { // Gather the storage format if needed let storage_format_access = match self.module.types[global.ty].inner { @@ -959,6 +959,13 @@ impl<'a, W: Write> Writer<'a, W> { // The trailing space is important write!(self.out, "uniform ")?; + if self.needs_depth_fix(ep_info, handle, &class) { + class = crate::ImageClass::Sampled { + kind: crate::ScalarKind::Float, + multi: false, + }; + } + // write the type // // This is way we need the leading space because `write_image_type` doesn't add @@ -1034,6 +1041,30 @@ impl<'a, W: Write> Writer<'a, W> { self.collect_reflection_info() } + fn needs_depth_fix( + &mut self, + ep_info: &valid::FunctionInfo, + handle: Handle, + class: &crate::ImageClass, + ) -> bool { + if let crate::ImageClass::Depth { multi: false } = *class { + // if any sampler uses the comparison sampler, a fix is not needed. Otherwise, we need to actually sample a regular texture as far as glsl is concerned + !ep_info.sampling_set.iter().all(|key| { + let data = &self.module.global_variables[key.sampler]; + if key.image != handle { + return false; + } + + matches!( + self.module.types[data.ty].inner, + TypeInner::Sampler { comparison: true } + ) + }) + } else { + false + } + } + fn write_array_size( &mut self, base: Handle, @@ -3162,6 +3193,14 @@ impl<'a, W: Write> Writer<'a, W> { self.write_expr(expr, ctx)?; } + let needs_depth_fix = + if let Expression::GlobalVariable(global_handle) = ctx.expressions[image] { + let ep_info = self.info.get_entry_point(self.entry_point_idx as usize); + self.needs_depth_fix(ep_info, global_handle, &class) + } else { + false + }; + match level { // Auto needs no more arguments crate::SampleLevel::Auto => (), @@ -3180,7 +3219,16 @@ impl<'a, W: Write> Writer<'a, W> { // Exact and bias require another argument crate::SampleLevel::Exact(expr) => { write!(self.out, ", ")?; + + if needs_depth_fix { + write!(self.out, "float(")?; + } + self.write_expr(expr, ctx)?; + + if needs_depth_fix { + write!(self.out, ")")?; + } } crate::SampleLevel::Bias(_) => { // This needs to be done after the offset writing @@ -3226,7 +3274,12 @@ impl<'a, W: Write> Writer<'a, W> { } // End the function - write!(self.out, ")")? + write!(self.out, ")")?; + + if needs_depth_fix { + // parser thinks it will yield f32, but in reality it yields vec4f + write!(self.out, ".x")?; + } } Expression::ImageLoad { image,