Skip to content

Commit

Permalink
glsl-out: Add support for push constant emulation
Browse files Browse the repository at this point in the history
  • Loading branch information
JCapucho committed Jan 15, 2022
1 parent a89e248 commit 0c2f100
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 13 deletions.
9 changes: 8 additions & 1 deletion src/back/glsl/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,21 @@ impl<'a, W> Writer<'a, W> {
}
}

let mut push_constant_used = false;

for (handle, global) in self.module.global_variables.iter() {
if ep_info[handle].is_empty() {
continue;
}
match global.class {
StorageClass::WorkGroup => self.features.request(Features::COMPUTE_SHADER),
StorageClass::Storage { .. } => self.features.request(Features::BUFFER_STORAGE),
StorageClass::PushConstant => return Err(Error::PushConstantNotSupported),
StorageClass::PushConstant => {
if push_constant_used {
return Err(Error::MultiplePushConstants);
}
push_constant_used = true;
}
_ => {}
}
}
Expand Down
41 changes: 29 additions & 12 deletions src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ impl crate::AtomicFunction {
impl crate::StorageClass {
fn is_buffer(&self) -> bool {
match *self {
crate::StorageClass::Uniform | crate::StorageClass::Storage { .. } => true,
crate::StorageClass::PushConstant
| crate::StorageClass::Uniform
| crate::StorageClass::Storage { .. } => true,
_ => false,
}
}
Expand All @@ -96,6 +98,7 @@ impl crate::StorageClass {
match *self {
crate::StorageClass::WorkGroup
| crate::StorageClass::Uniform
| crate::StorageClass::PushConstant
| crate::StorageClass::Storage { .. } => false,
_ => true,
}
Expand Down Expand Up @@ -227,6 +230,8 @@ pub struct Options {
pub writer_flags: WriterFlags,
/// Map of resources association to binding locations.
pub binding_map: BindingMap,
/// The binding to give the push constant buffer if it's present
pub push_constant_binding: u32,
}

impl Default for Options {
Expand All @@ -235,6 +240,7 @@ impl Default for Options {
version: Version::Embedded(310),
writer_flags: WriterFlags::ADJUST_COORDINATE_SPACE,
binding_map: BindingMap::default(),
push_constant_binding: 0,
}
}
}
Expand All @@ -257,6 +263,7 @@ pub struct PipelineOptions {
pub struct ReflectionInfo {
pub texture_mapping: crate::FastHashMap<String, TextureMapping>,
pub uniforms: crate::FastHashMap<Handle<crate::GlobalVariable>, String>,
pub push_constant: Option<String>,
}

/// Structure that connects a texture to a sampler or not
Expand Down Expand Up @@ -348,10 +355,10 @@ pub enum Error {
/// Contains the missing [`Features`](Features)
#[error("The selected version doesn't support {0:?}")]
MissingFeatures(Features),
/// [`StorageClass::PushConstant`](crate::StorageClass::PushConstant) was used and isn't
/// supported in the glsl backend
#[error("Push constants aren't supported")]
PushConstantNotSupported,
/// [`StorageClass::PushConstant`](crate::StorageClass::PushConstant) was used more than
/// once in the entry point which isn't supported
#[error("Multiple push constants aren't supported")]
MultiplePushConstants,
/// The specified [`Version`](Version) isn't supported
#[error("The specified version isn't supported")]
VersionNotSupported,
Expand Down Expand Up @@ -887,7 +894,13 @@ impl<'a, W: Write> Writer<'a, W> {
global: &crate::GlobalVariable,
) -> BackendResult {
if self.options.version.supports_explicit_locations() {
if let Some(ref br) = global.binding {
if let crate::StorageClass::PushConstant = global.class {
write!(
self.out,
"layout(std140, binding = {}) ",
self.options.push_constant_binding
)?
} else if let Some(ref br) = global.binding {
match self.options.binding_map.get(br) {
Some(binding) => {
let layout = match global.class {
Expand All @@ -898,7 +911,9 @@ impl<'a, W: Write> Writer<'a, W> {
"std140, "
}
}
crate::StorageClass::Uniform => "std140, ",
crate::StorageClass::Uniform | crate::StorageClass::PushConstant => {
"std140, "
}
_ => "",
};
write!(self.out, "layout({}binding = {}) ", layout, binding)?
Expand Down Expand Up @@ -2852,15 +2867,12 @@ impl<'a, W: Write> Writer<'a, W> {
}

/// Helper method used to produce the reflection info that's returned to the user
///
/// It takes an iterator of [`Function`](crate::Function) references instead of
/// [`Handle`](crate::arena::Handle) because [`EntryPoint`](crate::EntryPoint) isn't in any
/// [`Arena`](crate::arena::Arena) and we need to traverse it
fn collect_reflection_info(&self) -> Result<ReflectionInfo, Error> {
use std::collections::hash_map::Entry;
let info = self.info.get_entry_point(self.entry_point_idx as usize);
let mut texture_mapping = crate::FastHashMap::default();
let mut uniforms = crate::FastHashMap::default();
let mut push_constant = None;

for sampling in info.sampling_set.iter() {
let tex_name = self.reflection_names_globals[&sampling.image].clone();
Expand Down Expand Up @@ -2891,6 +2903,10 @@ impl<'a, W: Write> Writer<'a, W> {
let name = self.reflection_names_globals[&handle].clone();
uniforms.insert(handle, name);
}
crate::StorageClass::PushConstant => {
let name = self.reflection_names_globals[&handle].clone();
push_constant = Some(name)
}
_ => (),
},
crate::TypeInner::Image { .. } => {
Expand All @@ -2914,6 +2930,7 @@ impl<'a, W: Write> Writer<'a, W> {
Ok(ReflectionInfo {
texture_mapping,
uniforms,
push_constant,
})
}
}
Expand Down Expand Up @@ -3021,7 +3038,7 @@ fn glsl_storage_class(class: crate::StorageClass) -> Option<&'static str> {
Sc::Uniform => Some("uniform"),
Sc::Handle => Some("uniform"),
Sc::WorkGroup => Some("shared"),
Sc::PushConstant => None,
Sc::PushConstant => Some("uniform"),
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/in/functions-webgl.param.ron
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
version: Embedded(300),
writer_flags: (bits: 0),
binding_map: {},
push_constant_binding: 0,
),
)
1 change: 1 addition & 0 deletions tests/in/interpolate.param.ron
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
version: Desktop(400),
writer_flags: (bits: 0),
binding_map: {},
push_constant_binding: 0,
),
)
1 change: 1 addition & 0 deletions tests/in/quad.param.ron
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
version: Embedded(300),
writer_flags: (bits: 0),
binding_map: {},
push_constant_binding: 0,
),
)
1 change: 1 addition & 0 deletions tests/in/skybox.param.ron
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
(group: 0, binding: 0): 0,
(group: 0, binding: 1): 0,
},
push_constant_binding: 0,
),
hlsl: (
shader_model: V5_1,
Expand Down

0 comments on commit 0c2f100

Please sign in to comment.