From 3884921f4ece24a0660afd6fd49bbf4a4aba6a14 Mon Sep 17 00:00:00 2001 From: Pelle Johnsen Date: Thu, 23 Jul 2020 17:52:10 +0200 Subject: [PATCH] [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 --- src/front/glsl_new/ast.rs | 15 ++++++-------- src/front/glsl_new/mod.rs | 3 ++- src/front/glsl_new/parser.rs | 33 ++++++++++++++++++++++++++---- src/front/glsl_new/parser_tests.rs | 30 ++++++++++++++++++++------- 4 files changed, 60 insertions(+), 21 deletions(-) diff --git a/src/front/glsl_new/ast.rs b/src/front/glsl_new/ast.rs index 39b28e919b..fb6ab27d41 100644 --- a/src/front/glsl_new/ast.rs +++ b/src/front/glsl_new/ast.rs @@ -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, + pub shader_stage: ShaderStage, pub lookup_function: FastHashMap>, pub functions: Arena, pub lookup_type: FastHashMap>, pub types: Arena, pub constants: Arena, + pub global_variables: Arena, } 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::::new(), lookup_type: FastHashMap::default(), types: Arena::::new(), constants: Arena::::new(), + global_variables: Arena::::new(), } } } @@ -31,8 +33,3 @@ impl Program { pub enum Profile { Core, } - -#[derive(Debug)] -pub enum ExtDecl { - // FunctionDecl, -} diff --git a/src/front/glsl_new/mod.rs b/src/front/glsl_new/mod.rs index 44ad43b4bd..81e27bb3d1 100644 --- a/src/front/glsl_new/mod.rs +++ b/src/front/glsl_new/mod.rs @@ -18,7 +18,7 @@ mod token; pub fn parse_str(source: &str, entry: String, stage: ShaderStage) -> Result { 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 {}; @@ -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, } }) } diff --git a/src/front/glsl_new/parser_tests.rs b/src/front/glsl_new/parser_tests.rs index 9da4677c6c..017df8780e 100644 --- a/src/front/glsl_new/parser_tests.rs +++ b/src/front/glsl_new/parser_tests.rs @@ -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 { - let mut program = Program::new(); +fn parse_program(source: &str, stage: ShaderStage) -> Result { + 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 { #[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)"