summaryrefslogtreecommitdiffstats
path: root/third_party/rust/naga/src/back/glsl/features.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/naga/src/back/glsl/features.rs')
-rw-r--r--third_party/rust/naga/src/back/glsl/features.rs53
1 files changed, 51 insertions, 2 deletions
diff --git a/third_party/rust/naga/src/back/glsl/features.rs b/third_party/rust/naga/src/back/glsl/features.rs
index e7de05f695..99c128c6d9 100644
--- a/third_party/rust/naga/src/back/glsl/features.rs
+++ b/third_party/rust/naga/src/back/glsl/features.rs
@@ -1,8 +1,8 @@
use super::{BackendResult, Error, Version, Writer};
use crate::{
back::glsl::{Options, WriterFlags},
- AddressSpace, Binding, Expression, Handle, ImageClass, ImageDimension, Interpolation, Sampling,
- Scalar, ScalarKind, ShaderStage, StorageFormat, Type, TypeInner,
+ AddressSpace, Binding, Expression, Handle, ImageClass, ImageDimension, Interpolation,
+ SampleLevel, Sampling, Scalar, ScalarKind, ShaderStage, StorageFormat, Type, TypeInner,
};
use std::fmt::Write;
@@ -48,6 +48,8 @@ bitflags::bitflags! {
///
/// We can always support this, either through the language or a polyfill
const INSTANCE_INDEX = 1 << 22;
+ /// Sample specific LODs of cube / array shadow textures
+ const TEXTURE_SHADOW_LOD = 1 << 23;
}
}
@@ -125,6 +127,7 @@ impl FeaturesManager {
check_feature!(TEXTURE_SAMPLES, 150);
check_feature!(TEXTURE_LEVELS, 130);
check_feature!(IMAGE_SIZE, 430, 310);
+ check_feature!(TEXTURE_SHADOW_LOD, 200, 300);
// Return an error if there are missing features
if missing.is_empty() {
@@ -251,6 +254,11 @@ impl FeaturesManager {
}
}
+ if self.0.contains(Features::TEXTURE_SHADOW_LOD) {
+ // https://registry.khronos.org/OpenGL/extensions/EXT/EXT_texture_shadow_lod.txt
+ writeln!(out, "#extension GL_EXT_texture_shadow_lod : require")?;
+ }
+
Ok(())
}
}
@@ -469,6 +477,47 @@ impl<'a, W> Writer<'a, W> {
}
}
}
+ Expression::ImageSample { image, level, offset, .. } => {
+ if let TypeInner::Image {
+ dim,
+ arrayed,
+ class: ImageClass::Depth { .. },
+ } = *info[image].ty.inner_with(&module.types) {
+ let lod = matches!(level, SampleLevel::Zero | SampleLevel::Exact(_));
+ let bias = matches!(level, SampleLevel::Bias(_));
+ let auto = matches!(level, SampleLevel::Auto);
+ let cube = dim == ImageDimension::Cube;
+ let array2d = dim == ImageDimension::D2 && arrayed;
+ let gles = self.options.version.is_es();
+
+ // We have a workaround of using `textureGrad` instead of `textureLod` if the LOD is zero,
+ // so we don't *need* this extension for those cases.
+ // But if we're explicitly allowed to use the extension (`WriterFlags::TEXTURE_SHADOW_LOD`),
+ // we always use it instead of the workaround.
+ let grad_workaround_applicable = (array2d || (cube && !arrayed)) && level == SampleLevel::Zero;
+ let prefer_grad_workaround = grad_workaround_applicable && !self.options.writer_flags.contains(WriterFlags::TEXTURE_SHADOW_LOD);
+
+ let mut ext_used = false;
+
+ // float texture(sampler2DArrayShadow sampler, vec4 P [, float bias])
+ // float texture(samplerCubeArrayShadow sampler, vec4 P, float compare [, float bias])
+ ext_used |= (array2d || cube && arrayed) && bias;
+
+ // The non `bias` version of this was standardized in GL 4.3, but never in GLES.
+ // float textureOffset(sampler2DArrayShadow sampler, vec4 P, ivec2 offset [, float bias])
+ ext_used |= array2d && (bias || (gles && auto)) && offset.is_some();
+
+ // float textureLod(sampler2DArrayShadow sampler, vec4 P, float lod)
+ // float textureLodOffset(sampler2DArrayShadow sampler, vec4 P, float lod, ivec2 offset)
+ // float textureLod(samplerCubeShadow sampler, vec4 P, float lod)
+ // float textureLod(samplerCubeArrayShadow sampler, vec4 P, float compare, float lod)
+ ext_used |= (cube || array2d) && lod && !prefer_grad_workaround;
+
+ if ext_used {
+ features.request(Features::TEXTURE_SHADOW_LOD);
+ }
+ }
+ }
_ => {}
}
}