[glsl-in] treat const globals as constants allow them in array size exprs

This commit is contained in:
Frizi 2021-06-15 12:09:35 +02:00 committed by Dzmitry Malyshau
parent 7c8fbb4377
commit e6d142f28f
4 changed files with 63 additions and 43 deletions

View File

@ -14,6 +14,7 @@ use crate::{
#[derive(Debug, Clone, Copy)]
pub enum GlobalLookupKind {
Variable(Handle<GlobalVariable>),
Constant(Handle<Constant>),
BlockSelect(Handle<GlobalVariable>, u32),
}
@ -279,6 +280,11 @@ impl<'function> Context<'function> {
}
})
}
GlobalLookupKind::Constant(v) => {
let res = (this.expressions.append(Expression::Constant(v)), false);
this.emit_start();
res
}
};
let var = VariableReference {
@ -485,7 +491,7 @@ impl<'function> Context<'function> {
let handle = match kind {
HirExprKind::Access { base, index } => {
let base = self.lower_expect(program, base, lhs, body)?.0;
let base = self.lower_expect(program, base, true, body)?.0;
let index = self.lower_expect(program, index, false, body)?.0;
let pointer = self.add_expression(Expression::Access { base, index }, body);

View File

@ -7,7 +7,7 @@ use super::{
error::ErrorKind,
lex::Lexer,
token::{SourceMetadata, Token, TokenValue},
variables::VarDeclaration,
variables::{GlobalOrConstant, VarDeclaration},
Program,
};
use crate::{
@ -115,13 +115,14 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
/// Parses an optional array_specifier returning `Ok(None)` if there is no
/// LeftBracket
fn parse_array_specifier(&mut self) -> Result<Option<ArraySize>> {
// TODO: expressions
if let Some(&TokenValue::LeftBracket) = self.lexer.peek().map(|t| &t.value) {
self.bump()?;
if self.bump_if(TokenValue::LeftBracket).is_some() {
if self.bump_if(TokenValue::RightBracket).is_some() {
return Ok(Some(ArraySize::Dynamic));
}
let (constant, _) = self.parse_constant_expression()?;
self.expect(TokenValue::RightBracket)?;
Ok(Some(ArraySize::Dynamic))
Ok(Some(ArraySize::Constant(constant)))
} else {
Ok(None)
}
@ -801,7 +802,7 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
};
meta = meta.union(&token.meta);
let handle = self.program.add_global_var(VarDeclaration {
let global = self.program.add_global_var(VarDeclaration {
qualifiers,
ty,
name,
@ -817,7 +818,12 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
self.program.global_variables.push((
k,
GlobalLookup {
kind: GlobalLookupKind::BlockSelect(handle, i),
kind: match global {
GlobalOrConstant::Global(handle) => {
GlobalLookupKind::BlockSelect(handle, i)
}
GlobalOrConstant::Constant(handle) => GlobalLookupKind::Constant(handle),
},
entry_arg: None,
mutable: true,
},
@ -832,13 +838,18 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
let mut span = 0;
loop {
// TODO: type_qualifier
if !self.peek_type_name() {
if let TokenValue::RightBrace = self.expect_peek()?.value {
break;
}
// TODO: type_qualifier
let ty = self.parse_type_non_void()?.0;
let name = self.expect_ident()?.0;
let array_specifier = self.parse_array_specifier()?;
let ty = self.maybe_array(ty, array_specifier);
self.expect(TokenValue::Semicolon)?;
members.push(StructMember {
@ -848,7 +859,7 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
offset: span,
});
span = self.program.module.types[ty]
span += self.program.module.types[ty]
.inner
.span(&self.program.module.constants);
}
@ -1691,10 +1702,12 @@ impl<'ctx, 'fun> DeclarationContext<'ctx, 'fun> {
match self.external {
true => {
let handle = program.add_global_var(decl)?;
Ok(self
.ctx
.add_expression(Expression::GlobalVariable(handle), self.body))
let global = program.add_global_var(decl)?;
let expr = match global {
GlobalOrConstant::Global(handle) => Expression::GlobalVariable(handle),
GlobalOrConstant::Constant(handle) => Expression::Constant(handle),
};
Ok(self.ctx.add_expression(expr, self.body))
}
false => program.add_local_var(self.ctx, self.body, decl),
}

View File

@ -16,6 +16,11 @@ pub struct VarDeclaration<'a> {
pub meta: SourceMetadata,
}
pub enum GlobalOrConstant {
Global(Handle<GlobalVariable>),
Constant(Handle<Constant>),
}
impl Program<'_> {
pub fn lookup_variable(
&mut self,
@ -232,7 +237,7 @@ impl Program<'_> {
init,
meta,
}: VarDeclaration,
) -> Result<Handle<GlobalVariable>, ErrorKind> {
) -> Result<GlobalOrConstant, ErrorKind> {
let mut storage = StorageQualifier::StorageClass(StorageClass::Private);
let mut interpolation = None;
let mut binding = None;
@ -384,29 +389,27 @@ impl Program<'_> {
));
}
return Ok(handle);
return Ok(GlobalOrConstant::Global(handle));
} else if let StorageQualifier::Const = storage {
let handle = self.module.global_variables.append(GlobalVariable {
name: name.clone(),
class: StorageClass::Private,
binding: None,
ty,
init,
storage_access: StorageAccess::empty(),
});
if let Some(init) = init {
if let Some(name) = name {
self.global_variables.push((
name,
GlobalLookup {
kind: GlobalLookupKind::Constant(init),
entry_arg: None,
mutable: false,
},
));
}
if let Some(name) = name {
self.global_variables.push((
name,
GlobalLookup {
kind: GlobalLookupKind::Variable(handle),
entry_arg: None,
mutable: false,
},
return Ok(GlobalOrConstant::Constant(init));
} else {
return Err(ErrorKind::SemanticError(
meta,
"const values must have an initializer".into(),
));
}
return Ok(handle);
}
let (class, storage_access) = match self.module.types[ty].inner {
@ -456,7 +459,7 @@ impl Program<'_> {
));
}
Ok(handle)
Ok(GlobalOrConstant::Global(handle))
}
pub fn add_local_var(

View File

@ -7,7 +7,6 @@ struct FragmentOutput {
[[location(0), interpolate(perspective)]] member2: vec4<f32>;
};
var<private> c_scale: f32 = 1.2000000476837158;
var<private> a_pos: vec2<f32>;
var<private> a_uv: vec2<f32>;
var<private> v_uv: vec2<f32>;
@ -16,11 +15,10 @@ var<private> v_uv1: vec2<f32>;
var<private> o_color: vec4<f32>;
fn vert_main() {
let _e1: f32 = c_scale;
let _e3: vec2<f32> = a_pos;
let _e5: vec2<f32> = a_uv;
v_uv = _e5;
gl_Position = vec4<f32>((_e1 * _e3), 0.0, 1.0);
let _e2: vec2<f32> = a_pos;
let _e4: vec2<f32> = a_uv;
v_uv = _e4;
gl_Position = vec4<f32>((1.2000000476837158 * _e2), 0.0, 1.0);
return;
}