[glsl-new] handle gl_Position builtin (#114)

* [glsl-new] handle gl_Position builtin

- Also fix width of vec4 type

* [glsl-new] add shader stage as arg to program ctor
This commit is contained in:
Pelle Johnsen
2020-07-23 17:52:10 +02:00
committed by GitHub
parent ccab9f7c38
commit 3884921f4e
4 changed files with 60 additions and 21 deletions

View File

@@ -1,28 +1,30 @@
use crate::{Arena, Constant, FastHashMap, Function, Handle, Type};
use crate::{Arena, Constant, FastHashMap, Function, GlobalVariable, Handle, ShaderStage, Type};
#[derive(Debug)]
pub struct Program {
pub version: u16,
pub profile: Profile,
pub ext_decls: Vec<ExtDecl>,
pub shader_stage: ShaderStage,
pub lookup_function: FastHashMap<String, Handle<Function>>,
pub functions: Arena<Function>,
pub lookup_type: FastHashMap<String, Handle<Type>>,
pub types: Arena<Type>,
pub constants: Arena<Constant>,
pub global_variables: Arena<GlobalVariable>,
}
impl Program {
pub fn new() -> Program {
pub fn new(shader_stage: ShaderStage) -> Program {
Program {
version: 0,
profile: Profile::Core,
ext_decls: vec![],
shader_stage,
lookup_function: FastHashMap::default(),
functions: Arena::<Function>::new(),
lookup_type: FastHashMap::default(),
types: Arena::<Type>::new(),
constants: Arena::<Constant>::new(),
global_variables: Arena::<GlobalVariable>::new(),
}
}
}
@@ -31,8 +33,3 @@ impl Program {
pub enum Profile {
Core,
}
#[derive(Debug)]
pub enum ExtDecl {
// FunctionDecl,
}

View File

@@ -18,7 +18,7 @@ mod token;
pub fn parse_str(source: &str, entry: String, stage: ShaderStage) -> Result<Module, ParseError> {
log::debug!("------ GLSL-pomelo ------");
let mut program = Program::new();
let mut program = Program::new(stage);
let lex = Lexer::new(source);
let mut parser = parser::Parser::new(&mut program);
@@ -31,6 +31,7 @@ pub fn parse_str(source: &str, entry: String, stage: ShaderStage) -> Result<Modu
module.functions = program.functions;
module.types = program.types;
module.constants = program.constants;
module.global_variables = program.global_variables;
// find entry point
if let Some(entry_handle) = program.lookup_function.get(&entry) {

View File

@@ -6,8 +6,9 @@ pomelo! {
//%verbose;
%include {
use super::super::{error::ErrorKind, token::*, ast::*};
use crate::{Arena, Constant, ConstantInner, Expression, Function, Handle,
LocalVariable, ScalarKind, Type, TypeInner, VectorSize};
use crate::{Arena, Binding, BuiltIn, Constant, ConstantInner, Expression,
Function, GlobalVariable, Handle, LocalVariable, ScalarKind,
ShaderStage, StorageClass, Type, TypeInner, VectorSize};
}
%token #[derive(Debug)] pub enum Token {};
%parser pub struct Parser<'a> {};
@@ -72,7 +73,31 @@ pomelo! {
};
// expression
variable_identifier ::= Identifier;
variable_identifier ::= Identifier(v) {
if v.1.as_str() == "gl_Position" &&
(extra.shader_stage == ShaderStage::Vertex ||
extra.shader_stage == ShaderStage::Fragment) {
extra.global_variables.fetch_or_append(
GlobalVariable {
name: Some(v.1),
class: match extra.shader_stage {
ShaderStage::Vertex => StorageClass::Output,
ShaderStage::Fragment => StorageClass::Input,
_ => StorageClass::Input,
},
binding: Some(Binding::BuiltIn(BuiltIn::Position)),
ty: extra.types.fetch_or_append(Type {
name: None,
inner: TypeInner::Vector {
size: VectorSize::Quad,
kind: ScalarKind::Float,
width: 4,
},
}),
},
);
}
}
primary_expression ::= variable_identifier;
primary_expression ::= IntConstant(i) {
@@ -237,7 +262,7 @@ pomelo! {
inner: TypeInner::Vector {
size: VectorSize::Quad,
kind: ScalarKind::Float,
width: 16,
width: 4,
}
})
}

View File

@@ -2,9 +2,10 @@ use super::ast::Program;
use super::error::ErrorKind;
use super::lex::Lexer;
use super::parser;
use crate::ShaderStage;
fn parse_program(source: &str) -> Result<Program, ErrorKind> {
let mut program = Program::new();
fn parse_program(source: &str, stage: ShaderStage) -> Result<Program, ErrorKind> {
let mut program = Program::new(stage);
let lex = Lexer::new(source);
let mut parser = parser::Parser::new(&mut program);
@@ -18,30 +19,45 @@ fn parse_program(source: &str) -> Result<Program, ErrorKind> {
#[test]
fn glsl_parser_version_invalid() {
assert_eq!(
format!("{:?}", parse_program("#version 99000").err().unwrap()),
format!(
"{:?}",
parse_program("#version 99000", ShaderStage::Vertex)
.err()
.unwrap()
),
"InvalidVersion(TokenMetadata { line: 0, chars: 9..14 }, 99000)"
);
assert_eq!(
format!("{:?}", parse_program("#version 449").err().unwrap()),
format!(
"{:?}",
parse_program("#version 449", ShaderStage::Vertex)
.err()
.unwrap()
),
"InvalidVersion(TokenMetadata { line: 0, chars: 9..12 }, 449)"
);
assert_eq!(
format!("{:?}", parse_program("#version 450 smart").err().unwrap()),
format!(
"{:?}",
parse_program("#version 450 smart", ShaderStage::Vertex)
.err()
.unwrap()
),
"InvalidProfile(TokenMetadata { line: 0, chars: 13..18 }, \"smart\")"
);
}
#[test]
fn glsl_parser_version_valid() {
let program = parse_program("#version 450\nvoid main() {}").unwrap();
let program = parse_program("#version 450\nvoid main() {}", ShaderStage::Vertex).unwrap();
assert_eq!(
format!("{:?}", (program.version, program.profile)),
"(450, Core)"
);
let program = parse_program("#version 450 core\nvoid main() {}").unwrap();
let program = parse_program("#version 450 core\nvoid main() {}", ShaderStage::Vertex).unwrap();
assert_eq!(
format!("{:?}", (program.version, program.profile)),
"(450, Core)"