Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions benches/benches/wgpu-benchmark/shader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ pub fn backends(ctx: BenchmarkContext) -> anyhow::Result<Vec<SubBenchResult>> {
version: naga::back::glsl::Version::new_gles(320),
writer_flags: naga::back::glsl::WriterFlags::empty(),
binding_map: Default::default(),
external_texture_binding_map: Default::default(),
zero_initialize_workgroup_memory: true,
};
for input in &inputs.inner {
Expand Down
14 changes: 12 additions & 2 deletions naga/src/back/glsl/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ bitflags::bitflags! {
const SHADER_BARYCENTRICS = 1 << 26;
/// Primitive index builtin
const PRIMITIVE_INDEX = 1 << 27;
/// External texture (using samplerExternalOES)
const EXTERNAL_TEXTURE = 1 << 28;
}
}

Expand Down Expand Up @@ -139,6 +141,7 @@ impl FeaturesManager {
check_feature!(TEXTURE_LEVELS, 130);
check_feature!(IMAGE_SIZE, 430, 310);
check_feature!(TEXTURE_SHADOW_LOD, 200, 300);
check_feature!(EXTERNAL_TEXTURE, 9999, 300);

// Return an error if there are missing features
if missing.is_empty() {
Expand Down Expand Up @@ -312,6 +315,11 @@ impl FeaturesManager {
}
}

if self.0.contains(Features::EXTERNAL_TEXTURE) && options.version.is_es() {
// https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external_essl3.txt
writeln!(out, "#extension GL_OES_EGL_image_external_essl3 : require")?;
}

Ok(())
}
}
Expand Down Expand Up @@ -444,9 +452,11 @@ impl<W> Writer<'_, W> {
}
_ => {}
},
ImageClass::External => {
self.features.request(Features::EXTERNAL_TEXTURE);
}
ImageClass::Sampled { multi: false, .. }
| ImageClass::Depth { multi: false }
| ImageClass::External => {}
| ImageClass::Depth { multi: false } => {}
}
}
_ => {}
Expand Down
3 changes: 3 additions & 0 deletions naga/src/back/glsl/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,9 @@ pub const RESERVED_KEYWORDS: &[&str] = &[
super::MODF_FUNCTION,
super::FREXP_FUNCTION,
super::FIRST_INSTANCE_BINDING,
super::SAMPLE_EXTERNAL_TEXTURE_FUNCTION,
super::IMAGE_LOAD_EXTERNAL_FUNCTION,
super::IMAGE_SIZE_EXTERNAL_FUNCTION,
];

/// The above set of reserved keywords, turned into a cached HashSet. This saves
Expand Down
57 changes: 57 additions & 0 deletions naga/src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ const CLAMPED_LOD_SUFFIX: &str = "_clamped_lod";

pub(crate) const MODF_FUNCTION: &str = "naga_modf";
pub(crate) const FREXP_FUNCTION: &str = "naga_frexp";
pub(crate) const SAMPLE_EXTERNAL_TEXTURE_FUNCTION: &str = "nagaSampleExternalTexture";
pub(crate) const IMAGE_LOAD_EXTERNAL_FUNCTION: &str = "nagaTextureLoadExternal";
pub(crate) const IMAGE_SIZE_EXTERNAL_FUNCTION: &str = "nagaTextureDimensionsExternal";

// Must match code in glsl_built_in
pub const FIRST_INSTANCE_BINDING: &str = "naga_vs_first_instance";
Expand Down Expand Up @@ -120,6 +123,48 @@ where
/// Mapping between resources and bindings.
pub type BindingMap = alloc::collections::BTreeMap<crate::ResourceBinding, u8>;

/// Binding targets for a single external texture.
///
/// Holds both the texture unit for the `samplerExternalOES` and the uniform
/// buffer binding point for the `NagaExternalTextureParams` UBO.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
pub struct ExternalTextureBindTarget {
/// The texture unit to bind the `samplerExternalOES` to.
pub texture: u8,
/// The uniform buffer binding point for `NagaExternalTextureParams`.
pub params: u8,
}

/// Mapping between resources and external texture bind targets.
pub type ExternalTextureBindingMap =
alloc::collections::BTreeMap<crate::ResourceBinding, ExternalTextureBindTarget>;

#[cfg(feature = "deserialize")]
#[derive(serde::Deserialize)]
struct ExternalTextureBindingMapSerialization {
resource_binding: crate::ResourceBinding,
bind_target: ExternalTextureBindTarget,
}

#[cfg(feature = "deserialize")]
fn deserialize_external_texture_binding_map<'de, D>(
deserializer: D,
) -> Result<ExternalTextureBindingMap, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::Deserialize;

let vec = Vec::<ExternalTextureBindingMapSerialization>::deserialize(deserializer)?;
let mut map = ExternalTextureBindingMap::default();
for item in vec {
map.insert(item.resource_binding, item.bind_target);
}
Ok(map)
}

impl crate::AtomicFunction {
const fn to_glsl(self) -> &'static str {
match self {
Expand Down Expand Up @@ -336,6 +381,16 @@ pub struct Options {
serde(deserialize_with = "deserialize_binding_map")
)]
pub binding_map: BindingMap,
/// Map of external texture resources to their bind targets.
///
/// For each external texture, specifies the texture unit for the
/// `samplerExternalOES` and the uniform buffer binding point for the
/// `NagaExternalTextureParams` UBO used for color space conversion.
#[cfg_attr(
feature = "deserialize",
serde(deserialize_with = "deserialize_external_texture_binding_map")
)]
pub external_texture_binding_map: ExternalTextureBindingMap,
/// Should workgroup variables be zero initialized (by polyfilling)?
pub zero_initialize_workgroup_memory: bool,
}
Expand All @@ -346,6 +401,7 @@ impl Default for Options {
version: Version::new_gles(310),
writer_flags: WriterFlags::ADJUST_COORDINATE_SPACE,
binding_map: BindingMap::default(),
external_texture_binding_map: ExternalTextureBindingMap::default(),
zero_initialize_workgroup_memory: true,
}
}
Expand Down Expand Up @@ -645,4 +701,5 @@ pub fn supported_capabilities() -> valid::Capabilities {
| Caps::DRAW_INDEX
| Caps::MEMORY_DECORATION_COHERENT
| Caps::MEMORY_DECORATION_VOLATILE
| Caps::TEXTURE_EXTERNAL
}
Loading