[glsl-in] Parse some more memory qualifiers

This commit is contained in:
João Capucho
2021-08-01 18:34:32 +01:00
committed by Dzmitry Malyshau
parent 08302b5078
commit bcfe1f6f28
5 changed files with 35 additions and 11 deletions

View File

@@ -8,7 +8,7 @@ use crate::{
proc::ResolveContext, Arena, BinaryOperator, Binding, Block, Constant, Expression, FastHashMap,
Function, FunctionArgument, GlobalVariable, Handle, Interpolation, LocalVariable, Module,
RelationalFunction, ResourceBinding, Sampling, ScalarKind, ScalarValue, ShaderStage, Statement,
StorageClass, Type, TypeInner, UnaryOperator, VectorSize,
StorageAccess, StorageClass, Type, TypeInner, UnaryOperator, VectorSize,
};
use core::convert::TryFrom;
use std::ops::Index;
@@ -1054,6 +1054,7 @@ pub enum TypeQualifier {
Layout(StructLayout),
Precision(Precision),
EarlyFragmentTests,
StorageAccess(StorageAccess),
}
#[derive(Debug, Clone)]

View File

@@ -3,7 +3,7 @@ use super::{
token::{SourceMetadata, Token, TokenValue},
types::parse_type,
};
use crate::FastHashMap;
use crate::{FastHashMap, StorageAccess};
use pp_rs::{
pp::Preprocessor,
token::{Punct, Token as PPToken, TokenValue as PPTokenValue},
@@ -76,6 +76,9 @@ impl<'a> Iterator for Lexer<'a> {
"highp" => TokenValue::PrecisionQualifier(Precision::High),
"mediump" => TokenValue::PrecisionQualifier(Precision::Medium),
"lowp" => TokenValue::PrecisionQualifier(Precision::Low),
"restrict" => TokenValue::Restrict,
"readonly" => TokenValue::StorageAccess(StorageAccess::LOAD),
"writeonly" => TokenValue::StorageAccess(StorageAccess::STORE),
// values
"true" => TokenValue::BoolConstant(true),
"false" => TokenValue::BoolConstant(false),

View File

@@ -18,7 +18,7 @@ use crate::{
StructMember, SwitchCase, Type, TypeInner, UnaryOperator,
};
use core::convert::TryFrom;
use std::{iter::Peekable, mem};
use std::iter::Peekable;
type Result<T> = std::result::Result<T, ErrorKind>;
@@ -216,6 +216,8 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
| TokenValue::Out
| TokenValue::Uniform
| TokenValue::Buffer
| TokenValue::Restrict
| TokenValue::StorageAccess(_)
| TokenValue::Layout => true,
_ => false,
})
@@ -249,6 +251,8 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
),
TokenValue::Sampling(s) => TypeQualifier::Sampling(s),
TokenValue::PrecisionQualifier(p) => TypeQualifier::Precision(p),
TokenValue::StorageAccess(access) => TypeQualifier::StorageAccess(access),
TokenValue::Restrict => continue,
_ => unreachable!(),
},
token.meta,
@@ -1601,9 +1605,15 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
}
}
let fall_through = body.iter().any(|s| {
mem::discriminant(s) == mem::discriminant(&Statement::Break)
});
let mut fall_through = true;
for (i, stmt) in body.iter().enumerate() {
if let Statement::Break = *stmt {
fall_through = false;
body.drain(i..);
break;
}
}
cases.push(SwitchCase {
value,
@@ -1625,7 +1635,14 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
loop {
match self.expect_peek()?.value {
TokenValue::Case | TokenValue::RightBrace => break,
_ => self.parse_statement(ctx, &mut &mut default)?,
_ => self.parse_statement(ctx, &mut default)?,
}
}
for (i, stmt) in default.iter().enumerate() {
if let Statement::Break = *stmt {
default.drain(i..);
break;
}
}
}

View File

@@ -56,6 +56,10 @@ pub enum TokenValue {
Uniform,
Buffer,
Const,
Restrict,
StorageAccess(crate::StorageAccess),
Interpolation(Interpolation),
Sampling(Sampling),
Precision,

View File

@@ -339,6 +339,7 @@ impl Program<'_> {
let mut sampling = None;
let mut layout = None;
let mut precision = None;
let mut access = StorageAccess::all();
for &(ref qualifier, meta) in qualifiers {
match *qualifier {
@@ -393,6 +394,7 @@ impl Program<'_> {
meta,
"Cannot use more than one precision qualifier per declaration"
),
TypeQualifier::StorageAccess(a) => access &= a,
_ => {
return Err(ErrorKind::SemanticError(
meta,
@@ -488,15 +490,12 @@ impl Program<'_> {
return Ok(GlobalOrConstant::Constant(init));
}
// TODO: Add support for qualifiers such as readonly, writeonly and readwrite
let class = match self.module.types[ty].inner {
TypeInner::Image { .. } => StorageClass::Handle,
TypeInner::Sampler { .. } => StorageClass::Handle,
_ => {
if let StorageQualifier::StorageClass(StorageClass::Storage { .. }) = storage {
StorageClass::Storage {
access: StorageAccess::all(),
}
StorageClass::Storage { access }
} else {
match storage {
StorageQualifier::StorageClass(class) => class,