[ir] Move scalar kind into the Sampled image class variant

This commit is contained in:
Dzmitry Malyshau
2020-09-17 23:59:55 -04:00
committed by Dzmitry Malyshau
parent 7aff39784b
commit aa7005fdf3
8 changed files with 101 additions and 141 deletions

View File

@@ -268,7 +268,6 @@ pub fn write<'a>(
{
match module.types[global.ty].inner {
TypeInner::Image {
kind,
dim,
arrayed,
class,
@@ -300,22 +299,10 @@ pub fn write<'a>(
let name = namer(global.name.as_ref());
let comparison = if let Some(sampler) = mapping.1 {
if let TypeInner::Sampler { comparison } =
module.types[module.global_variables[*sampler].ty].inner
{
comparison
} else {
false
}
} else {
unreachable!()
};
writeln!(
out,
"uniform {} {};",
write_image_type(kind, dim, arrayed, class, comparison, features)?,
write_image_type(dim, arrayed, class, features)?,
name
)?;
@@ -814,34 +801,28 @@ fn write_expression<'a, 'b>(
let coordinate_expr =
write_expression(&builder.expressions[coordinate], module, builder)?;
let (kind, dim, arrayed, class) = match *builder.typifier.get(image, &module.types) {
let (dim, arrayed, class) = match *builder.typifier.get(image, &module.types) {
TypeInner::Image {
kind,
dim,
arrayed,
class,
} => (kind, dim, arrayed, class),
} => (dim, arrayed, class),
ref other => return Err(Error::Custom(format!("Cannot load {:?}", other))),
};
Cow::Owned(match class {
ImageClass::Sampled | ImageClass::Multisampled => {
let ms = match class {
crate::ImageClass::Multisampled => true,
_ => false,
};
ImageClass::Sampled { kind, multi } => {
//TODO: fix this
let sampler_constructor = format!(
"{}sampler{}{}{}({})",
map_scalar(kind, 4, builder.features)?.prefix,
ImageDimension(dim),
if ms { "MS" } else { "" },
if multi { "MS" } else { "" },
if arrayed { "Array" } else { "" },
image_expr,
);
if !ms {
if !multi {
format!("texelFetch({},{})", sampler_constructor, coordinate_expr)
} else {
let index_expr =
@@ -1188,11 +1169,9 @@ fn write_type<'a>(
}
fn write_image_type(
kind: ScalarKind,
dim: crate::ImageDimension,
arrayed: bool,
class: ImageClass,
comparison: bool,
features: SupportedFeatures,
) -> Result<String, Error> {
if arrayed
@@ -1204,16 +1183,33 @@ fn write_image_type(
)));
}
let (base, kind, ms, comparison) = match class {
ImageClass::Sampled { kind, multi: true } => {
if !features.contains(SupportedFeatures::MULTISAMPLED_TEXTURES) {
return Err(Error::Custom(String::from(
"Multi sampled textures aren't supported",
)));
}
if arrayed && !features.contains(SupportedFeatures::MULTISAMPLED_TEXTURE_ARRAYS) {
return Err(Error::Custom(String::from(
"Multi sampled texture arrays aren't supported",
)));
}
("sampler", kind, "MS", "")
}
ImageClass::Sampled { kind, multi: false } => ("sampler", kind, "", ""),
ImageClass::Depth => ("sampler", crate::ScalarKind::Float, "", "Shadow"),
ImageClass::Storage(format) => ("image", format.into(), "", ""),
};
Ok(format!(
"{}{}{}{}{}",
"{}{}{}{}{}{}",
map_scalar(kind, 4, features)?.prefix,
match class {
ImageClass::Storage(_) => "image",
_ => "sampler",
},
base,
ImageDimension(dim),
write_image_flags(arrayed, class, features)?,
if comparison { "Shadow" } else { "" }
ms,
if arrayed { "Array" } else { "" },
comparison
))
}
@@ -1271,33 +1267,6 @@ fn write_array_size(size: ArraySize) -> Result<String, Error> {
})
}
fn write_image_flags(
arrayed: bool,
class: ImageClass,
features: SupportedFeatures,
) -> Result<String, Error> {
let ms = match class {
ImageClass::Multisampled => {
if !features.contains(SupportedFeatures::MULTISAMPLED_TEXTURES) {
return Err(Error::Custom(String::from(
"Multi sampled textures aren't supported",
)));
}
if arrayed && !features.contains(SupportedFeatures::MULTISAMPLED_TEXTURE_ARRAYS) {
return Err(Error::Custom(String::from(
"Multi sampled texture arrays aren't supported",
)));
}
"MS"
}
_ => "",
};
let array = if arrayed { "Array" } else { "" };
Ok(format!("{}{}", ms, array))
}
struct ImageDimension(crate::ImageDimension);
impl fmt::Display for ImageDimension {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

View File

@@ -839,35 +839,30 @@ impl<W: Write> Writer<W> {
write!(self.out, "}}")?;
}
crate::TypeInner::Image {
kind,
dim,
arrayed,
class,
} => {
let base_name = scalar_kind_string(kind);
let dim_str = match dim {
crate::ImageDimension::D1 => "1d",
crate::ImageDimension::D2 => "2d",
crate::ImageDimension::D3 => "3d",
crate::ImageDimension::Cube => "Cube",
};
let texture_str = match class {
crate::ImageClass::Depth => "depth",
_ => "texture",
};
let msaa_str = match class {
crate::ImageClass::Multisampled => "_ms",
_ => "",
};
let array_str = if arrayed { "_array" } else { "" };
let access = match class {
crate::ImageClass::Storage(_) => {
let (texture_str, msaa_str, kind, access) = match class {
crate::ImageClass::Sampled { kind, multi } => {
("texture", if multi { "_ms" } else { "" }, kind, "sample")
}
crate::ImageClass::Depth => {
("depth", "", crate::ScalarKind::Float, "sample")
}
crate::ImageClass::Storage(format) => {
let (_, global) = module
.global_variables
.iter()
.find(|(_, var)| var.ty == handle)
.expect("Unable to find a global variable using the image type");
if global
let access = if global
.storage_access
.contains(crate::StorageAccess::LOAD | crate::StorageAccess::STORE)
{
@@ -878,10 +873,12 @@ impl<W: Write> Writer<W> {
"read"
} else {
return Err(Error::InvalidImageAccess(global.storage_access));
}
};
("texture", "", format.into(), access)
}
_ => "sample",
};
let base_name = scalar_kind_string(kind);
let array_str = if arrayed { "_array" } else { "" };
write!(
self.out,
"typedef {}{}{}{}<{}, access::{}> {}",

View File

@@ -179,11 +179,11 @@ pub(super) fn instruction_type_image(
});
instruction.add_operand(arrayed as u32);
instruction.add_operand(match image_class {
crate::ImageClass::Multisampled => 1,
crate::ImageClass::Sampled { multi: true, .. } => 1,
_ => 0,
});
instruction.add_operand(match image_class {
crate::ImageClass::Sampled => 1,
crate::ImageClass::Sampled { .. } => 1,
_ => 0,
});
@@ -800,7 +800,10 @@ mod tests {
1,
spirv::Dim::Dim3D,
true,
crate::ImageClass::Multisampled,
crate::ImageClass::Sampled {
kind: crate::ScalarKind::Float,
multi: true,
},
);
let mut output = vec![];

View File

@@ -490,19 +490,28 @@ impl Writer {
super::instructions::instruction_type_matrix(id, vector_id, columns)
}
crate::TypeInner::Image {
kind,
dim,
arrayed,
class,
} => {
let type_id = self.get_type_id(
arena,
LookupType::Local(LocalType::Vector {
let width = 4;
let local_type = match class {
crate::ImageClass::Sampled { kind, multi: _ } => LocalType::Vector {
size: crate::VectorSize::Quad,
kind,
width: 4,
}),
);
width,
},
crate::ImageClass::Depth => LocalType::Scalar {
kind: crate::ScalarKind::Float,
width,
},
crate::ImageClass::Storage(format) => LocalType::Vector {
size: crate::VectorSize::Quad,
kind: format.into(),
width,
},
};
let type_id = self.get_type_id(arena, LookupType::Local(local_type));
let dim = map_dim(dim);
self.try_add_capabilities(dim.required_capabilities());
super::instructions::instruction_type_image(id, type_id, dim, arrayed, class)

View File

@@ -899,10 +899,13 @@ impl<I: Iterator<Item = u32>> Parser<I> {
match type_arena[image_type_handle].inner {
//TODO: compare the result type
crate::TypeInner::Image {
kind: _,
dim,
arrayed,
class: crate::ImageClass::Sampled,
class:
crate::ImageClass::Sampled {
kind: _,
multi: false,
},
} => {
if !check_sample_coordinates(
&type_arena[coord_type_handle],
@@ -982,7 +985,6 @@ impl<I: Iterator<Item = u32>> Parser<I> {
match type_arena[image_type_handle].inner {
//TODO: compare the result type
crate::TypeInner::Image {
kind: _,
dim,
arrayed,
class: crate::ImageClass::Depth,
@@ -1473,10 +1475,6 @@ impl<I: Iterator<Item = u32>> Parser<I> {
};
*comparison = true;
}
crate::TypeInner::Image { ref mut class, .. } => {
assert_eq!(*class, crate::ImageClass::Sampled);
*class = crate::ImageClass::Multisampled;
}
_ => panic!("Unexpected comparison type {:?}", ty),
}
}
@@ -2034,17 +2032,17 @@ impl<I: Iterator<Item = u32>> Parser<I> {
let class = if format != 0 {
crate::ImageClass::Storage(map_image_format(format)?)
} else if is_msaa {
crate::ImageClass::Multisampled
} else {
crate::ImageClass::Sampled
crate::ImageClass::Sampled {
kind,
multi: is_msaa,
}
};
let decor = self.future_decor.remove(&id).unwrap_or_default();
let inner = crate::TypeInner::Image {
class,
kind,
dim: map_image_dim(dim)?,
arrayed: is_array,
};

View File

@@ -1207,95 +1207,83 @@ impl Parser {
Token::Word("texture_sampled_1d") => {
let (kind, _) = lexer.next_scalar_generic()?;
crate::TypeInner::Image {
kind,
dim: crate::ImageDimension::D1,
arrayed: false,
class: crate::ImageClass::Sampled,
class: crate::ImageClass::Sampled { kind, multi: false },
}
}
Token::Word("texture_sampled_1d_array") => {
let (kind, _) = lexer.next_scalar_generic()?;
crate::TypeInner::Image {
kind,
dim: crate::ImageDimension::D1,
arrayed: true,
class: crate::ImageClass::Sampled,
class: crate::ImageClass::Sampled { kind, multi: false },
}
}
Token::Word("texture_sampled_2d") => {
let (kind, _) = lexer.next_scalar_generic()?;
crate::TypeInner::Image {
kind,
dim: crate::ImageDimension::D2,
arrayed: false,
class: crate::ImageClass::Sampled,
class: crate::ImageClass::Sampled { kind, multi: false },
}
}
Token::Word("texture_sampled_2d_array") => {
let (kind, _) = lexer.next_scalar_generic()?;
crate::TypeInner::Image {
kind,
dim: crate::ImageDimension::D2,
arrayed: true,
class: crate::ImageClass::Sampled,
class: crate::ImageClass::Sampled { kind, multi: false },
}
}
Token::Word("texture_sampled_3d") => {
let (kind, _) = lexer.next_scalar_generic()?;
crate::TypeInner::Image {
kind,
dim: crate::ImageDimension::D3,
arrayed: false,
class: crate::ImageClass::Sampled,
class: crate::ImageClass::Sampled { kind, multi: false },
}
}
Token::Word("texture_sampled_cube") => {
let (kind, _) = lexer.next_scalar_generic()?;
crate::TypeInner::Image {
kind,
dim: crate::ImageDimension::Cube,
arrayed: false,
class: crate::ImageClass::Sampled,
class: crate::ImageClass::Sampled { kind, multi: false },
}
}
Token::Word("texture_sampled_cube_array") => {
let (kind, _) = lexer.next_scalar_generic()?;
crate::TypeInner::Image {
kind,
dim: crate::ImageDimension::Cube,
arrayed: true,
class: crate::ImageClass::Sampled,
class: crate::ImageClass::Sampled { kind, multi: false },
}
}
Token::Word("texture_multisampled_2d") => {
let (kind, _) = lexer.next_scalar_generic()?;
crate::TypeInner::Image {
kind,
dim: crate::ImageDimension::D2,
arrayed: false,
class: crate::ImageClass::Multisampled,
class: crate::ImageClass::Sampled { kind, multi: true },
}
}
Token::Word("texture_depth_2d") => crate::TypeInner::Image {
kind: crate::ScalarKind::Float,
dim: crate::ImageDimension::D2,
arrayed: false,
class: crate::ImageClass::Depth,
},
Token::Word("texture_depth_2d_array") => crate::TypeInner::Image {
kind: crate::ScalarKind::Float,
dim: crate::ImageDimension::D2,
arrayed: true,
class: crate::ImageClass::Depth,
},
Token::Word("texture_depth_cube") => crate::TypeInner::Image {
kind: crate::ScalarKind::Float,
dim: crate::ImageDimension::Cube,
arrayed: false,
class: crate::ImageClass::Depth,
},
Token::Word("texture_depth_cube_array") => crate::TypeInner::Image {
kind: crate::ScalarKind::Float,
dim: crate::ImageDimension::Cube,
arrayed: true,
class: crate::ImageClass::Depth,
@@ -1303,7 +1291,6 @@ impl Parser {
Token::Word("texture_ro_1d") => {
let format = lexer.next_format_generic()?;
crate::TypeInner::Image {
kind: format.into(),
dim: crate::ImageDimension::D1,
arrayed: false,
class: crate::ImageClass::Storage(format),
@@ -1312,7 +1299,6 @@ impl Parser {
Token::Word("texture_ro_1d_array") => {
let format = lexer.next_format_generic()?;
crate::TypeInner::Image {
kind: format.into(),
dim: crate::ImageDimension::D1,
arrayed: true,
class: crate::ImageClass::Storage(format),
@@ -1321,7 +1307,6 @@ impl Parser {
Token::Word("texture_ro_2d") => {
let format = lexer.next_format_generic()?;
crate::TypeInner::Image {
kind: format.into(),
dim: crate::ImageDimension::D2,
arrayed: false,
class: crate::ImageClass::Storage(format),
@@ -1330,7 +1315,6 @@ impl Parser {
Token::Word("texture_ro_2d_array") => {
let format = lexer.next_format_generic()?;
crate::TypeInner::Image {
kind: format.into(),
dim: crate::ImageDimension::D2,
arrayed: true,
class: crate::ImageClass::Storage(format),
@@ -1339,7 +1323,6 @@ impl Parser {
Token::Word("texture_ro_3d") => {
let format = lexer.next_format_generic()?;
crate::TypeInner::Image {
kind: format.into(),
dim: crate::ImageDimension::D3,
arrayed: false,
class: crate::ImageClass::Storage(format),
@@ -1348,7 +1331,6 @@ impl Parser {
Token::Word("texture_wo_1d") => {
let format = lexer.next_format_generic()?;
crate::TypeInner::Image {
kind: format.into(),
dim: crate::ImageDimension::D1,
arrayed: false,
class: crate::ImageClass::Storage(format),
@@ -1357,7 +1339,6 @@ impl Parser {
Token::Word("texture_wo_1d_array") => {
let format = lexer.next_format_generic()?;
crate::TypeInner::Image {
kind: format.into(),
dim: crate::ImageDimension::D1,
arrayed: true,
class: crate::ImageClass::Storage(format),
@@ -1366,7 +1347,6 @@ impl Parser {
Token::Word("texture_wo_2d") => {
let format = lexer.next_format_generic()?;
crate::TypeInner::Image {
kind: format.into(),
dim: crate::ImageDimension::D2,
arrayed: false,
class: crate::ImageClass::Storage(format),
@@ -1375,7 +1355,6 @@ impl Parser {
Token::Word("texture_wo_2d_array") => {
let format = lexer.next_format_generic()?;
crate::TypeInner::Image {
kind: format.into(),
dim: crate::ImageDimension::D2,
arrayed: true,
class: crate::ImageClass::Storage(format),
@@ -1384,7 +1363,6 @@ impl Parser {
Token::Word("texture_wo_3d") => {
let format = lexer.next_format_generic()?;
crate::TypeInner::Image {
kind: format.into(),
dim: crate::ImageDimension::D3,
arrayed: false,
class: crate::ImageClass::Storage(format),

View File

@@ -315,9 +315,12 @@ pub enum StorageFormat {
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
pub enum ImageClass {
/// Regular sampled image.
Sampled,
/// Multi-sampled image.
Multisampled,
Sampled {
/// Kind of values to sample.
kind: ScalarKind,
// Multi-sampled.
multi: bool,
},
/// Depth comparison image.
Depth,
/// Storage image.
@@ -370,7 +373,6 @@ pub enum TypeInner {
Struct { members: Vec<StructMember> },
/// Possibly multidimensional array of texels.
Image {
kind: ScalarKind,
dim: ImageDimension,
arrayed: bool,
class: ImageClass,

View File

@@ -136,18 +136,22 @@ impl Typifier {
crate::Expression::Load { .. } => unimplemented!(),
crate::Expression::ImageSample { image, .. }
| crate::Expression::ImageLoad { image, .. } => match *self.get(image, types) {
crate::TypeInner::Image {
kind,
class: crate::ImageClass::Depth,
..
} => Resolution::Value(crate::TypeInner::Scalar { kind, width: 4 }),
crate::TypeInner::Image { kind, .. } => {
Resolution::Value(crate::TypeInner::Vector {
crate::TypeInner::Image { class, .. } => Resolution::Value(match class {
crate::ImageClass::Depth => crate::TypeInner::Scalar {
kind: crate::ScalarKind::Float,
width: 4,
},
crate::ImageClass::Sampled { kind, multi: _ } => crate::TypeInner::Vector {
kind,
width: 4,
size: crate::VectorSize::Quad,
})
}
},
crate::ImageClass::Storage(format) => crate::TypeInner::Vector {
kind: format.into(),
width: 4,
size: crate::VectorSize::Quad,
},
}),
_ => unreachable!(),
},
crate::Expression::Unary { expr, .. } => self.resolutions[expr.index()].clone(),