[glsl-in] add support for array variables (#731)

* [glsl-in] add support for array variables

* clippy

* more clippy
This commit is contained in:
François
2021-04-19 19:37:25 +02:00
committed by GitHub
parent 9cd6fd9c20
commit 79bcfb1206
2 changed files with 78 additions and 5 deletions

View File

@@ -1,9 +1,9 @@
use super::{super::Typifier, constants::ConstantSolver, error::ErrorKind};
use crate::{
proc::ResolveContext, Arena, BinaryOperator, Binding, Constant, Expression, FastHashMap,
Function, FunctionArgument, GlobalVariable, Handle, Interpolation, LocalVariable, Module,
RelationalFunction, ResourceBinding, Sampling, ShaderStage, Statement, StorageClass, Type,
UnaryOperator,
proc::ResolveContext, Arena, ArraySize, BinaryOperator, Binding, Constant, Expression,
FastHashMap, Function, FunctionArgument, GlobalVariable, Handle, Interpolation, LocalVariable,
Module, RelationalFunction, ResourceBinding, Sampling, ShaderStage, Statement, StorageClass,
Type, UnaryOperator,
};
#[derive(Debug)]
@@ -144,6 +144,51 @@ impl<'a> Program<'a> {
.solve(root)
.map_err(|_| ErrorKind::SemanticError("Can't solve constant".into()))
}
pub fn type_size(&self, ty: Handle<Type>) -> Result<u8, ErrorKind> {
Ok(match self.module.types[ty].inner {
crate::TypeInner::Scalar { width, .. } => width,
crate::TypeInner::Vector { size, width, .. } => size as u8 * width,
crate::TypeInner::Matrix {
columns,
rows,
width,
} => columns as u8 * rows as u8 * width,
crate::TypeInner::Pointer { .. } => {
return Err(ErrorKind::NotImplemented("type size of pointer"))
}
crate::TypeInner::ValuePointer { .. } => {
return Err(ErrorKind::NotImplemented("type size of value pointer"))
}
crate::TypeInner::Array { size, stride, .. } => {
stride as u8
* match size {
ArraySize::Dynamic => {
return Err(ErrorKind::NotImplemented("type size of dynamic array"))
}
ArraySize::Constant(constant) => {
match self.module.constants[constant].inner {
crate::ConstantInner::Scalar { width, .. } => width,
crate::ConstantInner::Composite { .. } => {
return Err(ErrorKind::NotImplemented(
"type size of array with composite item size",
))
}
}
}
}
}
crate::TypeInner::Struct { .. } => {
return Err(ErrorKind::NotImplemented("type size of struct"))
}
crate::TypeInner::Image { .. } => {
return Err(ErrorKind::NotImplemented("type size of image"))
}
crate::TypeInner::Sampler { .. } => {
return Err(ErrorKind::NotImplemented("type size of sampler"))
}
})
}
}
#[derive(Debug)]

View File

@@ -6,7 +6,7 @@ pomelo! {
use super::super::{error::ErrorKind, token::*, ast::*};
use crate::{
BOOL_WIDTH,
Arena, BinaryOperator, Binding, Block, Constant,
Arena, ArraySize, BinaryOperator, Binding, Block, Constant,
ConstantInner, Expression,
Function, FunctionArgument, FunctionResult,
GlobalVariable, Handle, Interpolation,
@@ -592,6 +592,34 @@ pomelo! {
ty,
}
}
single_declaration ::= fully_specified_type(t) Identifier(i) LeftBracket additive_expression(exp) RightBracket {
let ty_item = t.1.ok_or_else(|| ErrorKind::SemanticError("Empty type for declaration".into()))?;
let array_size = if let Ok(constant) = extra.solve_constant(exp.expression) {
ArraySize::Constant(constant)
} else {
ArraySize::Dynamic
};
let item_size = extra.type_size(ty_item)?;
let ty = extra.module.types.fetch_or_append(Type {
inner: TypeInner::Array {
base: ty_item,
size: array_size,
stride: item_size as u32,
},
name: None,
});
VarDeclaration {
type_qualifiers: t.0,
ids_initializers: vec![(Some(i.1), None)],
ty,
}
}
// single_declaration ::= fully_specified_type Identifier array_specifier;
// single_declaration ::= fully_specified_type Identifier array_specifier Equal initializer;
single_declaration ::= fully_specified_type(t) Identifier(i) Equal initializer(init) {