[glsl-in] Add initial texture handling

This commit is contained in:
Pelle Johnsen
2020-11-01 13:46:21 +00:00
committed by Dzmitry Malyshau
parent 173bb0de42
commit 602367c062
4 changed files with 95 additions and 23 deletions

View File

@@ -138,6 +138,7 @@ impl Context {
pub struct ExpressionRule {
pub expression: Handle<Expression>,
pub statements: Vec<Statement>,
pub sampler: Option<Handle<Expression>>,
}
impl ExpressionRule {
@@ -145,6 +146,7 @@ impl ExpressionRule {
ExpressionRule {
expression,
statements: vec![],
sampler: None,
}
}
}
@@ -166,12 +168,11 @@ pub struct VarDeclaration {
#[derive(Debug)]
pub enum FunctionCallKind {
TypeConstructor(Handle<Type>),
Function(Handle<Expression>),
Function(String),
}
#[derive(Debug)]
pub struct FunctionCall {
pub kind: FunctionCallKind,
pub args: Vec<Handle<Expression>>,
pub statements: Vec<Statement>,
pub args: Vec<ExpressionRule>,
}

View File

@@ -7,7 +7,7 @@ pomelo! {
use super::super::{error::ErrorKind, token::*, ast::*};
use crate::{proc::Typifier, Arena, BinaryOperator, Binding, Block, Constant,
ConstantInner, EntryPoint, Expression, FallThrough, FastHashMap, Function, GlobalVariable, Handle, Interpolation,
LocalVariable, MemberOrigin, ScalarKind, Statement, StorageAccess,
LocalVariable, MemberOrigin, SampleLevel, ScalarKind, Statement, StorageAccess,
StorageClass, StructMember, Type, TypeInner};
}
%token #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] pub enum Token {};
@@ -230,7 +230,7 @@ pomelo! {
postfix_expression ::= postfix_expression(e) Dot Identifier(i) /* FieldSelection in spec */ {
//TODO: how will this work as l-value?
let expression = extra.field_selection(e.expression, &*i.1, i.0)?;
ExpressionRule { expression, statements: e.statements }
ExpressionRule { expression, statements: e.statements, sampler: None }
}
postfix_expression ::= postfix_expression(pe) IncOp {
//TODO
@@ -244,17 +244,49 @@ pomelo! {
integer_expression ::= expression;
function_call ::= function_call_or_method(fc) {
if let FunctionCallKind::TypeConstructor(ty) = fc.kind {
let h = extra.context.expressions.append(Expression::Compose{
ty,
components: fc.args,
});
ExpressionRule{
expression: h,
statements: fc.statements,
match fc.kind {
FunctionCallKind::TypeConstructor(ty) => {
let h = extra.context.expressions.append(Expression::Compose{
ty,
components: fc.args.iter().map(|a| a.expression).collect(),
});
ExpressionRule{
expression: h,
statements: fc.args.into_iter().map(|a| a.statements).flatten().collect(),
sampler: None
}
}
FunctionCallKind::Function(name) => {
match name.as_str() {
"sampler2D" => {
//TODO: check args len
ExpressionRule{
expression: fc.args[0].expression,
sampler: Some(fc.args[1].expression),
statements: fc.args.into_iter().map(|a| a.statements).flatten().collect(),
}
}
"texture" => {
//TODO: check args len
if let Some(sampler) = fc.args[0].sampler {
ExpressionRule{
expression: extra.context.expressions.append(Expression::ImageSample{
image: fc.args[0].expression,
sampler,
coordinate: fc.args[1].expression,
level: SampleLevel::Auto,
depth_ref: None,
}),
sampler: None,
statements: fc.args.into_iter().map(|a| a.statements).flatten().collect(),
}
} else {
return Err(ErrorKind::SemanticError("Bad call to texture"));
}
}
_ => { return Err(ErrorKind::NotImplemented("Function call")); }
}
}
} else {
return Err(ErrorKind::NotImplemented("Function call"));
}
}
function_call_or_method ::= function_call_generic;
@@ -269,26 +301,22 @@ pomelo! {
}
function_call_header_no_parameters ::= function_call_header;
function_call_header_with_parameters ::= function_call_header(mut h) assignment_expression(ae) {
h.args.push(ae.expression);
h.statements.extend(ae.statements);
h.args.push(ae);
h
}
function_call_header_with_parameters ::= function_call_header_with_parameters(mut h) Comma assignment_expression(ae) {
h.args.push(ae.expression);
h.statements.extend(ae.statements);
h.args.push(ae);
h
}
function_call_header ::= function_identifier(i) LeftParen {
FunctionCall {
kind: i,
args: vec![],
statements: vec![],
}
}
// Grammar Note: Constructors look like functions, but lexical analysis recognized most of them as
// keywords. They are now recognized through “type_specifier”.
// Methods (.length), subroutine array calls, and identifiers are recognized through postfix_expression.
function_identifier ::= type_specifier(t) {
if let Some(ty) = t {
FunctionCallKind::TypeConstructor(ty)
@@ -296,10 +324,19 @@ pomelo! {
return Err(ErrorKind::NotImplemented("bad type ctor"))
}
}
function_identifier ::= postfix_expression(e) {
FunctionCallKind::Function(e.expression)
//TODO
// Methods (.length), subroutine array calls, and identifiers are recognized through postfix_expression.
// function_identifier ::= postfix_expression(e) {
// FunctionCallKind::Function(e.expression)
// }
// Simplification of above
function_identifier ::= Identifier(i) {
FunctionCallKind::Function(i.1)
}
unary_expression ::= postfix_expression;
unary_expression ::= IncOp unary_expression {
@@ -452,6 +489,7 @@ pomelo! {
ExpressionRule{
expression: e.expression,
statements: ae.statements,
sampler: None,
}
}

View File

@@ -162,3 +162,21 @@ fn control_flow() {
)
.unwrap();
}
#[test]
fn textures() {
let _program = parse_program(
r#"
#version 450
layout(location = 0) in vec2 v_uv;
layout(location = 0) out vec4 o_color;
layout(set = 1, binding = 1) uniform texture2D tex;
layout(set = 1, binding = 2) uniform sampler tex_sampler;
void main() {
o_color = texture(sampler2D(tex, tex_sampler), v_uv);
}
"#,
ShaderStage::Fragment,
)
.unwrap();
}

View File

@@ -37,6 +37,21 @@ pub fn parse_type(type_name: &str) -> Option<Type> {
width: 4,
},
}),
"texture2D" => Some(Type {
name: None,
inner: TypeInner::Image {
dim: crate::ImageDimension::D2,
arrayed: false,
class: crate::ImageClass::Sampled {
kind: ScalarKind::Float,
multi: false,
},
},
}),
"sampler" => Some(Type {
name: None,
inner: TypeInner::Sampler { comparison: false },
}),
word => {
fn kind_width_parse(ty: &str) -> Option<(ScalarKind, u8)> {
Some(match ty {