From c0dfb247b68c2f1485583d6768562711badbc11b Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 18 Dec 2020 01:11:47 -0500 Subject: [PATCH] Sizing processor --- src/proc/mod.rs | 2 ++ src/proc/sizer.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++ src/proc/typifier.rs | 1 + 3 files changed, 68 insertions(+) create mode 100644 src/proc/sizer.rs diff --git a/src/proc/mod.rs b/src/proc/mod.rs index 74f814a077..ee0baeadaf 100644 --- a/src/proc/mod.rs +++ b/src/proc/mod.rs @@ -4,6 +4,7 @@ mod call_graph; mod interface; mod namer; +mod sizer; mod terminator; mod typifier; mod validator; @@ -12,6 +13,7 @@ mod validator; pub use call_graph::{CallGraph, CallGraphBuilder}; pub use interface::{Interface, Visitor}; pub use namer::{EntryPointIndex, NameKey, Namer}; +pub use sizer::Sizer; pub use terminator::ensure_block_returns; pub use typifier::{check_constant_type, ResolveContext, ResolveError, Typifier}; pub use validator::{ValidationError, Validator}; diff --git a/src/proc/sizer.rs b/src/proc/sizer.rs new file mode 100644 index 0000000000..a9c58f0912 --- /dev/null +++ b/src/proc/sizer.rs @@ -0,0 +1,65 @@ +use crate::arena::Arena; + +/// Helper processor that derives the sizes of all types. +#[derive(Debug)] +pub struct Sizer { + sizes: Vec, +} + +impl Sizer { + pub fn new(types: &Arena, constants: &Arena) -> Self { + use crate::TypeInner as Ti; + + let mut sizes = Vec::with_capacity(types.len()); + for (_, ty) in types.iter() { + sizes.push(match ty.inner { + Ti::Scalar { kind: _, width } => width as u32, + Ti::Vector { + size, + kind: _, + width, + } => (size as u8 * width) as u32, + Ti::Matrix { + columns, + rows, + width, + } => (columns as u8 * rows as u8 * width) as u32, + Ti::Pointer { .. } => 0, + Ti::Array { base, size, stride } => { + let count = match size { + crate::ArraySize::Constant(handle) => match constants[handle].inner { + crate::ConstantInner::Uint(value) => value as u32, + ref other => unreachable!("Unexpected array size {:?}", other), + }, + crate::ArraySize::Dynamic => 1, + }; + let stride = match stride { + Some(value) => value.get(), + None => sizes[base.index()], + }; + count * stride + } + Ti::Struct { + block: _, + ref members, + } => { + let mut total = 0; + for member in members { + total += match member.span { + Some(span) => span.get(), + None => sizes[member.ty.index()], + }; + } + total + } + Ti::Image { .. } | Ti::Sampler { .. } => 0, + }); + } + + Sizer { sizes } + } + + pub fn resolve(&self, handle: crate::Handle) -> u32 { + self.sizes[handle.index()] + } +} diff --git a/src/proc/typifier.rs b/src/proc/typifier.rs index c8ee18b1da..6862773c55 100644 --- a/src/proc/typifier.rs +++ b/src/proc/typifier.rs @@ -36,6 +36,7 @@ impl Clone for Resolution { } } +/// Helper processor that derives the types of all expressions. #[derive(Debug)] pub struct Typifier { resolutions: Vec,