[glsl-in] Remove support for multiple entry points

This commit is contained in:
João Capucho
2021-08-04 00:39:25 +01:00
committed by Dzmitry Malyshau
parent 6f476eeafe
commit 057dc3100d
11 changed files with 217 additions and 489 deletions

View File

@@ -223,14 +223,11 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
} }
"vert" => { "vert" => {
let input = fs::read_to_string(input_path)?; let input = fs::read_to_string(input_path)?;
let mut entry_points = naga::FastHashMap::default();
entry_points.insert("main".to_string(), naga::ShaderStage::Vertex);
naga::front::glsl::parse_str( naga::front::glsl::parse_str(
&input, &input,
&naga::front::glsl::Options { &naga::front::glsl::Options {
entry_points, stage: naga::ShaderStage::Vertex,
defines: Default::default(), defines: Default::default(),
strip_unused_linkages: false,
}, },
) )
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
@@ -241,14 +238,11 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
} }
"frag" => { "frag" => {
let input = fs::read_to_string(input_path)?; let input = fs::read_to_string(input_path)?;
let mut entry_points = naga::FastHashMap::default();
entry_points.insert("main".to_string(), naga::ShaderStage::Fragment);
naga::front::glsl::parse_str( naga::front::glsl::parse_str(
&input, &input,
&naga::front::glsl::Options { &naga::front::glsl::Options {
entry_points, stage: naga::ShaderStage::Fragment,
defines: Default::default(), defines: Default::default(),
strip_unused_linkages: false,
}, },
) )
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
@@ -259,14 +253,11 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
} }
"comp" => { "comp" => {
let input = fs::read_to_string(input_path)?; let input = fs::read_to_string(input_path)?;
let mut entry_points = naga::FastHashMap::default();
entry_points.insert("main".to_string(), naga::ShaderStage::Compute);
naga::front::glsl::parse_str( naga::front::glsl::parse_str(
&input, &input,
&naga::front::glsl::Options { &naga::front::glsl::Options {
entry_points, stage: naga::ShaderStage::Compute,
defines: Default::default(), defines: Default::default(),
strip_unused_linkages: false,
}, },
) )
.unwrap_or_else(|err| { .unwrap_or_else(|err| {

View File

@@ -47,46 +47,19 @@ pub struct FunctionDeclaration {
pub void: bool, pub void: bool,
} }
bitflags::bitflags! {
pub struct EntryArgUse: u32 {
const READ = 0x1;
const WRITE = 0x2;
}
}
bitflags::bitflags! {
pub struct PrologueStage: u32 {
const VERTEX = 0x1;
const FRAGMENT = 0x2;
const COMPUTE = 0x4;
}
}
impl From<ShaderStage> for PrologueStage {
fn from(stage: ShaderStage) -> Self {
match stage {
ShaderStage::Vertex => PrologueStage::VERTEX,
ShaderStage::Fragment => PrologueStage::FRAGMENT,
ShaderStage::Compute => PrologueStage::COMPUTE,
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct EntryArg { pub struct EntryArg {
pub name: Option<String>, pub name: Option<String>,
pub binding: Binding, pub binding: Binding,
pub handle: Handle<GlobalVariable>, pub handle: Handle<GlobalVariable>,
pub prologue: PrologueStage,
pub storage: StorageQualifier, pub storage: StorageQualifier,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Program<'a> { pub struct Program {
pub version: u16, pub version: u16,
pub profile: Profile, pub profile: Profile,
pub entry_points: &'a FastHashMap<String, ShaderStage>, pub stage: ShaderStage,
pub strip_unused_linkages: bool,
pub workgroup_size: [u32; 3], pub workgroup_size: [u32; 3],
pub early_fragment_tests: bool, pub early_fragment_tests: bool,
@@ -97,25 +70,19 @@ pub struct Program<'a> {
pub global_variables: Vec<(String, GlobalLookup)>, pub global_variables: Vec<(String, GlobalLookup)>,
pub entry_args: Vec<EntryArg>, pub entry_args: Vec<EntryArg>,
pub entries: Vec<(String, ShaderStage, Handle<Function>)>, pub entry_point: Option<Handle<Function>>,
// TODO: More efficient representation
pub function_arg_use: Vec<Vec<EntryArgUse>>,
pub module: Module, pub module: Module,
} }
impl<'a> Program<'a> { impl Program {
pub fn new( pub fn new(stage: ShaderStage) -> Program {
entry_points: &'a FastHashMap<String, ShaderStage>,
strip_unused_linkages: bool,
) -> Program<'a> {
Program { Program {
version: 0, version: 0,
profile: Profile::Core, profile: Profile::Core,
entry_points, stage,
strip_unused_linkages,
workgroup_size: [1; 3], workgroup_size: [if stage == ShaderStage::Compute { 1 } else { 0 }; 3],
early_fragment_tests: false, early_fragment_tests: false,
lookup_function: FastHashMap::default(), lookup_function: FastHashMap::default(),
@@ -123,8 +90,7 @@ impl<'a> Program<'a> {
global_variables: Vec::new(), global_variables: Vec::new(),
entry_args: Vec::new(), entry_args: Vec::new(),
entries: Vec::new(), entry_point: None,
function_arg_use: Vec::new(),
module: Module::default(), module: Module::default(),
} }
@@ -214,7 +180,6 @@ pub struct Context<'function> {
pub locals: &'function mut Arena<LocalVariable>, pub locals: &'function mut Arena<LocalVariable>,
pub arguments: &'function mut Vec<FunctionArgument>, pub arguments: &'function mut Vec<FunctionArgument>,
pub parameters_info: Vec<ParameterInfo>, pub parameters_info: Vec<ParameterInfo>,
pub arg_use: Vec<EntryArgUse>,
//TODO: Find less allocation heavy representation //TODO: Find less allocation heavy representation
pub scopes: Vec<FastHashMap<String, VariableReference>>, pub scopes: Vec<FastHashMap<String, VariableReference>>,
@@ -239,7 +204,6 @@ impl<'function> Context<'function> {
locals, locals,
arguments, arguments,
parameters_info: Vec::new(), parameters_info: Vec::new(),
arg_use: vec![EntryArgUse::empty(); program.entry_args.len()],
scopes: vec![FastHashMap::default()], scopes: vec![FastHashMap::default()],
lookup_global_var_exps: FastHashMap::with_capacity_and_hasher( lookup_global_var_exps: FastHashMap::with_capacity_and_hasher(
@@ -647,23 +611,13 @@ impl<'function> Context<'function> {
)); ));
} }
if let Some(idx) = var.entry_arg {
self.arg_use[idx] |= EntryArgUse::WRITE
}
var.expr var.expr
} else { } else if var.load {
if let Some(idx) = var.entry_arg {
self.arg_use[idx] |= EntryArgUse::READ
}
if var.load {
self.add_expression(Expression::Load { pointer: var.expr }, body) self.add_expression(Expression::Load { pointer: var.expr }, body)
} else { } else {
var.expr var.expr
} }
} }
}
HirExprKind::Call(call) if !lhs => { HirExprKind::Call(call) if !lhs => {
let maybe_expr = program let maybe_expr = program
.function_or_constructor_call(self, body, call.kind, &call.args, meta)?; .function_or_constructor_call(self, body, call.kind, &call.args, meta)?;

View File

@@ -2,8 +2,7 @@ use crate::{
proc::ensure_block_returns, Arena, BinaryOperator, Block, Constant, ConstantInner, EntryPoint, proc::ensure_block_returns, Arena, BinaryOperator, Block, Constant, ConstantInner, EntryPoint,
Expression, Function, FunctionArgument, FunctionResult, Handle, ImageClass, ImageDimension, Expression, Function, FunctionArgument, FunctionResult, Handle, ImageClass, ImageDimension,
ImageQuery, LocalVariable, MathFunction, Module, RelationalFunction, SampleLevel, ScalarKind, ImageQuery, LocalVariable, MathFunction, Module, RelationalFunction, SampleLevel, ScalarKind,
ScalarValue, ShaderStage, Statement, StructMember, SwizzleComponent, Type, TypeInner, ScalarValue, Statement, StructMember, SwizzleComponent, Type, TypeInner, VectorSize,
VectorSize,
}; };
use super::{ast::*, error::ErrorKind, SourceMetadata}; use super::{ast::*, error::ErrorKind, SourceMetadata};
@@ -17,7 +16,7 @@ struct CoordComponents {
array_index: Option<Handle<Expression>>, array_index: Option<Handle<Expression>>,
} }
impl Program<'_> { impl Program {
fn add_constant_value(&mut self, scalar_kind: ScalarKind, value: u64) -> Handle<Constant> { fn add_constant_value(&mut self, scalar_kind: ScalarKind, value: u64) -> Handle<Constant> {
let value = match scalar_kind { let value = match scalar_kind {
ScalarKind::Uint => ScalarValue::Uint(value), ScalarKind::Uint => ScalarValue::Uint(value),
@@ -1031,16 +1030,18 @@ impl Program<'_> {
parameters: Vec<Handle<Type>>, parameters: Vec<Handle<Type>>,
parameters_info: Vec<ParameterInfo>, parameters_info: Vec<ParameterInfo>,
meta: SourceMetadata, meta: SourceMetadata,
) -> Result<Handle<Function>, ErrorKind> { ) -> Result<(), ErrorKind> {
ensure_block_returns(&mut function.body); ensure_block_returns(&mut function.body);
let stage = self.entry_points.get(&name);
Ok(if let Some(&stage) = stage { if name.as_str() == "main" {
let handle = self.module.functions.append(function); let handle = self.module.functions.append(function);
self.entries.push((name, stage, handle)); return if self.entry_point.replace(handle).is_some() {
self.function_arg_use.push(Vec::new()); Err(ErrorKind::SemanticError(meta, "main defined twice".into()))
handle
} else { } else {
Ok(())
};
}
let void = function.result.is_none(); let void = function.result.is_none();
let &mut Program { let &mut Program {
@@ -1056,8 +1057,7 @@ impl Program<'_> {
continue; continue;
} }
for (new_parameter, old_parameter) in parameters.iter().zip(decl.parameters.iter()) for (new_parameter, old_parameter) in parameters.iter().zip(decl.parameters.iter()) {
{
let new_inner = &module.types[*new_parameter].inner; let new_inner = &module.types[*new_parameter].inner;
let old_inner = &module.types[*old_parameter].inner; let old_inner = &module.types[*old_parameter].inner;
@@ -1076,10 +1076,9 @@ impl Program<'_> {
decl.defined = true; decl.defined = true;
decl.parameters_info = parameters_info; decl.parameters_info = parameters_info;
*self.module.functions.get_mut(decl.handle) = function; *self.module.functions.get_mut(decl.handle) = function;
return Ok(decl.handle); return Ok(());
} }
self.function_arg_use.push(Vec::new());
let handle = module.functions.append(function); let handle = module.functions.append(function);
declarations.push(FunctionDeclaration { declarations.push(FunctionDeclaration {
parameters, parameters,
@@ -1088,8 +1087,8 @@ impl Program<'_> {
defined: true, defined: true,
void, void,
}); });
handle
}) Ok(())
} }
pub fn add_prototype( pub fn add_prototype(
@@ -1131,7 +1130,6 @@ impl Program<'_> {
)); ));
} }
self.function_arg_use.push(Vec::new());
let handle = module.functions.append(function); let handle = module.functions.append(function);
declarations.push(FunctionDeclaration { declarations.push(FunctionDeclaration {
parameters, parameters,
@@ -1144,102 +1142,16 @@ impl Program<'_> {
Ok(()) Ok(())
} }
fn check_call_global( pub fn add_entry_point(&mut self, function: Handle<Function>) -> Result<(), ErrorKind> {
&self,
caller: Handle<Function>,
function_arg_use: &mut [Vec<EntryArgUse>],
stmt: &Statement,
) {
match *stmt {
Statement::Block(ref block) => {
for stmt in block {
self.check_call_global(caller, function_arg_use, stmt)
}
}
Statement::If {
ref accept,
ref reject,
..
} => {
for stmt in accept.iter().chain(reject.iter()) {
self.check_call_global(caller, function_arg_use, stmt)
}
}
Statement::Switch {
ref cases,
ref default,
..
} => {
for stmt in cases
.iter()
.flat_map(|c| c.body.iter())
.chain(default.iter())
{
self.check_call_global(caller, function_arg_use, stmt)
}
}
Statement::Loop {
ref body,
ref continuing,
} => {
for stmt in body.iter().chain(continuing.iter()) {
self.check_call_global(caller, function_arg_use, stmt)
}
}
Statement::Call { function, .. } => {
let callee_len = function_arg_use[function.index()].len();
let caller_len = function_arg_use[caller.index()].len();
function_arg_use[caller.index()].extend(
std::iter::repeat(EntryArgUse::empty())
.take(callee_len.saturating_sub(caller_len)),
);
for i in 0..callee_len.min(caller_len) {
let callee_use = function_arg_use[function.index()][i];
function_arg_use[caller.index()][i] |= callee_use
}
}
_ => {}
}
}
pub fn add_entry_points(&mut self) {
let mut function_arg_use = Vec::new();
std::mem::swap(&mut self.function_arg_use, &mut function_arg_use);
for (handle, function) in self.module.functions.iter() {
for stmt in function.body.iter() {
self.check_call_global(handle, &mut function_arg_use, stmt)
}
}
for (name, stage, function) in self.entries.iter().cloned() {
let mut arguments = Vec::new(); let mut arguments = Vec::new();
let mut expressions = Arena::new(); let mut expressions = Arena::new();
let mut body = Vec::new(); let mut body = Vec::new();
let can_strip_stage_inputs = for arg in self.entry_args.iter() {
self.strip_unused_linkages || stage != ShaderStage::Fragment;
let can_strip_stage_outputs =
self.strip_unused_linkages || stage != ShaderStage::Vertex;
for (i, arg) in self.entry_args.iter().enumerate() {
if arg.storage != StorageQualifier::Input { if arg.storage != StorageQualifier::Input {
continue; continue;
} }
if !arg.prologue.contains(stage.into()) {
continue;
}
let is_used = function_arg_use[function.index()]
.get(i)
.map_or(false, |u| u.contains(EntryArgUse::READ));
if can_strip_stage_inputs && !is_used {
continue;
}
let ty = self.module.global_variables[arg.handle].ty; let ty = self.module.global_variables[arg.handle].ty;
let idx = arguments.len() as u32; let idx = arguments.len() as u32;
@@ -1265,19 +1177,11 @@ impl Program<'_> {
let mut members = Vec::new(); let mut members = Vec::new();
let mut components = Vec::new(); let mut components = Vec::new();
for (i, arg) in self.entry_args.iter().enumerate() { for arg in self.entry_args.iter() {
if arg.storage != StorageQualifier::Output { if arg.storage != StorageQualifier::Output {
continue; continue;
} }
let is_used = function_arg_use[function.index()]
.get(i)
.map_or(false, |u| u.contains(EntryArgUse::WRITE));
if can_strip_stage_outputs && !is_used {
continue;
}
let ty = self.module.global_variables[arg.handle].ty; let ty = self.module.global_variables[arg.handle].ty;
members.push(StructMember { members.push(StructMember {
@@ -1318,15 +1222,11 @@ impl Program<'_> {
body.push(Statement::Return { value }); body.push(Statement::Return { value });
self.module.entry_points.push(EntryPoint { self.module.entry_points.push(EntryPoint {
name, name: "main".to_string(),
stage, stage: self.stage,
early_depth_test: Some(crate::EarlyDepthTest { conservative: None }) early_depth_test: Some(crate::EarlyDepthTest { conservative: None })
.filter(|_| self.early_fragment_tests && stage == crate::ShaderStage::Fragment), .filter(|_| self.early_fragment_tests),
workgroup_size: if let crate::ShaderStage::Compute = stage { workgroup_size: self.workgroup_size,
self.workgroup_size
} else {
[0; 3]
},
function: Function { function: Function {
arguments, arguments,
expressions, expressions,
@@ -1335,7 +1235,8 @@ impl Program<'_> {
..Default::default() ..Default::default()
}, },
}); });
}
Ok(())
} }
/// Helper function for texture calls, splits the vector argument into it's components /// Helper function for texture calls, splits the vector argument into it's components

View File

@@ -20,15 +20,13 @@ mod token;
mod types; mod types;
mod variables; mod variables;
#[derive(Default)]
pub struct Options { pub struct Options {
pub entry_points: FastHashMap<String, ShaderStage>, pub stage: ShaderStage,
pub defines: FastHashMap<String, String>, pub defines: FastHashMap<String, String>,
pub strip_unused_linkages: bool,
} }
pub fn parse_str(source: &str, options: &Options) -> Result<Module, ParseError> { pub fn parse_str(source: &str, options: &Options) -> Result<Module, ParseError> {
let mut program = Program::new(&options.entry_points, options.strip_unused_linkages); let mut program = Program::new(options.stage);
let lex = lex::Lexer::new(source, &options.defines); let lex = lex::Lexer::new(source, &options.defines);
let mut parser = parser::Parser::new(&mut program, lex); let mut parser = parser::Parser::new(&mut program, lex);

View File

@@ -22,13 +22,13 @@ use std::iter::Peekable;
type Result<T> = std::result::Result<T, ErrorKind>; type Result<T> = std::result::Result<T, ErrorKind>;
pub struct Parser<'source, 'program, 'options> { pub struct Parser<'source, 'program> {
program: &'program mut Program<'options>, program: &'program mut Program,
lexer: Peekable<Lexer<'source>>, lexer: Peekable<Lexer<'source>>,
} }
impl<'source, 'program, 'options> Parser<'source, 'program, 'options> { impl<'source, 'program> Parser<'source, 'program> {
pub fn new(program: &'program mut Program<'options>, lexer: Lexer<'source>) -> Self { pub fn new(program: &'program mut Program, lexer: Lexer<'source>) -> Self {
Parser { Parser {
program, program,
lexer: lexer.peekable(), lexer: lexer.peekable(),
@@ -81,7 +81,9 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
self.parse_external_declaration()?; self.parse_external_declaration()?;
} }
self.program.add_entry_points(); if let Some(handle) = self.program.entry_point {
self.program.add_entry_point(handle)?;
}
Ok(()) Ok(())
} }
@@ -741,11 +743,9 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
self.parse_compound_statement(&mut context, &mut body)?; self.parse_compound_statement(&mut context, &mut body)?;
let Context { let Context {
arg_use, parameters_info, ..
parameters_info,
..
} = context; } = context;
let handle = self.program.add_function( self.program.add_function(
Function { Function {
name: Some(name.clone()), name: Some(name.clone()),
result, result,
@@ -761,8 +761,6 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
meta, meta,
)?; )?;
self.program.function_arg_use[handle.index()] = arg_use;
Ok(true) Ok(true)
} }
_ if external => Err(ErrorKind::InvalidToken( _ if external => Err(ErrorKind::InvalidToken(

View File

@@ -10,11 +10,8 @@ use crate::{
ShaderStage, ShaderStage,
}; };
fn parse_program<'a>( fn parse_program(source: &str, stage: ShaderStage) -> Result<Program, ErrorKind> {
source: &str, let mut program = Program::new(stage);
entry_points: &'a crate::FastHashMap<String, ShaderStage>,
) -> Result<Program<'a>, ErrorKind> {
let mut program = Program::new(entry_points, true);
let defines = crate::FastHashMap::default(); let defines = crate::FastHashMap::default();
let lex = Lexer::new(source, &defines); let lex = Lexer::new(source, &defines);
let mut parser = parser::Parser::new(&mut program, lex); let mut parser = parser::Parser::new(&mut program, lex);
@@ -25,30 +22,30 @@ fn parse_program<'a>(
#[test] #[test]
fn version() { fn version() {
let mut entry_points = crate::FastHashMap::default();
entry_points.insert("".to_string(), ShaderStage::Vertex);
// invalid versions // invalid versions
assert_eq!( assert_eq!(
parse_program("#version 99000", &entry_points) parse_program("#version 99000", ShaderStage::Vertex)
.err() .err()
.unwrap(), .unwrap(),
ErrorKind::InvalidVersion(SourceMetadata { start: 9, end: 14 }, 99000), ErrorKind::InvalidVersion(SourceMetadata { start: 9, end: 14 }, 99000),
); );
assert_eq!( assert_eq!(
parse_program("#version 449", &entry_points).err().unwrap(), parse_program("#version 449", ShaderStage::Vertex)
.err()
.unwrap(),
ErrorKind::InvalidVersion(SourceMetadata { start: 9, end: 12 }, 449) ErrorKind::InvalidVersion(SourceMetadata { start: 9, end: 12 }, 449)
); );
assert_eq!( assert_eq!(
parse_program("#version 450 smart", &entry_points) parse_program("#version 450 smart", ShaderStage::Vertex)
.err() .err()
.unwrap(), .unwrap(),
ErrorKind::InvalidProfile(SourceMetadata { start: 13, end: 18 }, "smart".into()) ErrorKind::InvalidProfile(SourceMetadata { start: 13, end: 18 }, "smart".into())
); );
assert_eq!( assert_eq!(
parse_program("#version 450\nvoid f(){} #version 450", &entry_points) parse_program("#version 450\nvoid f(){} #version 450", ShaderStage::Vertex)
.err() .err()
.unwrap(), .unwrap(),
ErrorKind::InvalidToken( ErrorKind::InvalidToken(
@@ -61,21 +58,18 @@ fn version() {
); );
// valid versions // valid versions
let program = parse_program(" # version 450\nvoid main() {}", &entry_points).unwrap(); let program = parse_program(" # version 450\nvoid main() {}", ShaderStage::Vertex).unwrap();
assert_eq!((program.version, program.profile), (450, Profile::Core)); assert_eq!((program.version, program.profile), (450, Profile::Core));
let program = parse_program("#version 450\nvoid main() {}", &entry_points).unwrap(); let program = parse_program("#version 450\nvoid main() {}", ShaderStage::Vertex).unwrap();
assert_eq!((program.version, program.profile), (450, Profile::Core)); assert_eq!((program.version, program.profile), (450, Profile::Core));
let program = parse_program("#version 450 core\nvoid main() {}", &entry_points).unwrap(); let program = parse_program("#version 450 core\nvoid main() {}", ShaderStage::Vertex).unwrap();
assert_eq!((program.version, program.profile), (450, Profile::Core)); assert_eq!((program.version, program.profile), (450, Profile::Core));
} }
#[test] #[test]
fn control_flow() { fn control_flow() {
let mut entry_points = crate::FastHashMap::default();
entry_points.insert("".to_string(), ShaderStage::Vertex);
let _program = parse_program( let _program = parse_program(
r#" r#"
# version 450 # version 450
@@ -87,7 +81,7 @@ fn control_flow() {
} }
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -100,7 +94,7 @@ fn control_flow() {
} }
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -122,7 +116,7 @@ fn control_flow() {
} }
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
let _program = parse_program( let _program = parse_program(
@@ -138,7 +132,7 @@ fn control_flow() {
} while(x >= 4) } while(x >= 4)
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -154,16 +148,13 @@ fn control_flow() {
return x; return x;
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
} }
#[test] #[test]
fn declarations() { fn declarations() {
let mut entry_points = crate::FastHashMap::default();
entry_points.insert("".to_string(), ShaderStage::Fragment);
let _program = parse_program( let _program = parse_program(
r#" r#"
#version 450 #version 450
@@ -174,7 +165,7 @@ fn declarations() {
layout(early_fragment_tests) in; layout(early_fragment_tests) in;
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -188,7 +179,7 @@ fn declarations() {
ivec4 atlas_offs; ivec4 atlas_offs;
}; };
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -202,7 +193,7 @@ fn declarations() {
ivec4 atlas_offs; ivec4 atlas_offs;
}; };
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -216,7 +207,7 @@ fn declarations() {
ivec4 atlas_offs; ivec4 atlas_offs;
}; };
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -234,7 +225,7 @@ fn declarations() {
block_var.load_time * block_var.model_offs; block_var.load_time * block_var.model_offs;
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -243,7 +234,7 @@ fn declarations() {
#version 450 #version 450
float vector = vec4(1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0); float vector = vec4(1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0);
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -252,16 +243,13 @@ fn declarations() {
#version 450 #version 450
precision highp float; precision highp float;
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
} }
#[test] #[test]
fn textures() { fn textures() {
let mut entry_points = crate::FastHashMap::default();
entry_points.insert("".to_string(), ShaderStage::Fragment);
let _program = parse_program( let _program = parse_program(
r#" r#"
#version 450 #version 450
@@ -274,16 +262,13 @@ fn textures() {
o_color.a = texture(sampler2D(tex, tex_sampler), v_uv, 2.0).a; o_color.a = texture(sampler2D(tex, tex_sampler), v_uv, 2.0).a;
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
} }
#[test] #[test]
fn functions() { fn functions() {
let mut entry_points = crate::FastHashMap::default();
entry_points.insert("".to_string(), ShaderStage::Vertex);
parse_program( parse_program(
r#" r#"
# version 450 # version 450
@@ -292,7 +277,7 @@ fn functions() {
void main() {} void main() {}
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -305,7 +290,7 @@ fn functions() {
void main() {} void main() {}
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -316,7 +301,7 @@ fn functions() {
void main() {} void main() {}
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -327,7 +312,7 @@ fn functions() {
return p.x; return p.x;
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -351,7 +336,7 @@ fn functions() {
return p.x; return p.x;
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -367,7 +352,7 @@ fn functions() {
return p.x; return p.x;
} }
"#, "#,
&entry_points ShaderStage::Vertex
) )
.err() .err()
.unwrap(), .unwrap(),
@@ -393,7 +378,7 @@ fn functions() {
callee(1u); callee(1u);
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -408,7 +393,7 @@ fn functions() {
textureLod(sampler2D(t_noise, s_noise), vec2(1.0), 0); textureLod(sampler2D(t_noise, s_noise), vec2(1.0), 0);
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -424,7 +409,7 @@ fn functions() {
fun(vec2(1.0), a); fun(vec2(1.0), a);
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
} }
@@ -433,9 +418,6 @@ fn functions() {
fn constants() { fn constants() {
use crate::{Constant, ConstantInner, ScalarValue}; use crate::{Constant, ConstantInner, ScalarValue};
let mut entry_points = crate::FastHashMap::default();
entry_points.insert("".to_string(), ShaderStage::Vertex);
let program = parse_program( let program = parse_program(
r#" r#"
# version 450 # version 450
@@ -443,7 +425,7 @@ fn constants() {
float global = a; float global = a;
const float b = a; const float b = a;
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -466,9 +448,6 @@ fn constants() {
#[test] #[test]
fn function_overloading() { fn function_overloading() {
let mut entry_points = crate::FastHashMap::default();
entry_points.insert("".to_string(), ShaderStage::Vertex);
parse_program( parse_program(
r#" r#"
# version 450 # version 450
@@ -485,16 +464,13 @@ fn function_overloading() {
vec3 v4 = saturate(vec4(0.5, 1.5, 2.5, 3.5)); vec3 v4 = saturate(vec4(0.5, 1.5, 2.5, 3.5));
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
} }
#[test] #[test]
fn implicit_conversions() { fn implicit_conversions() {
let mut entry_points = crate::FastHashMap::default();
entry_points.insert("".to_string(), ShaderStage::Vertex);
parse_program( parse_program(
r#" r#"
# version 450 # version 450
@@ -504,7 +480,7 @@ fn implicit_conversions() {
float c = 1 + 2.0; float c = 1 + 2.0;
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -519,7 +495,7 @@ fn implicit_conversions() {
test(1.0); test(1.0);
} }
"#, "#,
&entry_points ShaderStage::Vertex
) )
.err() .err()
.unwrap(), .unwrap(),
@@ -543,7 +519,7 @@ fn implicit_conversions() {
test(1); test(1);
} }
"#, "#,
&entry_points ShaderStage::Vertex
) )
.err() .err()
.unwrap(), .unwrap(),
@@ -559,9 +535,6 @@ fn implicit_conversions() {
#[test] #[test]
fn structs() { fn structs() {
let mut entry_points = crate::FastHashMap::default();
entry_points.insert("".to_string(), ShaderStage::Fragment);
parse_program( parse_program(
r#" r#"
# version 450 # version 450
@@ -569,7 +542,7 @@ fn structs() {
vec4 pos; vec4 pos;
} xx; } xx;
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap_err(); .unwrap_err();
@@ -580,7 +553,7 @@ fn structs() {
vec4 pos; vec4 pos;
}; };
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -592,7 +565,7 @@ fn structs() {
vec4 vecs[NUM_VECS]; vec4 vecs[NUM_VECS];
}; };
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -605,7 +578,7 @@ fn structs() {
return Hello( vec4(1.0) ); return Hello( vec4(1.0) );
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -614,7 +587,7 @@ fn structs() {
# version 450 # version 450
struct Test {}; struct Test {};
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap_err(); .unwrap_err();
@@ -625,16 +598,13 @@ fn structs() {
vec4 x; vec4 x;
}; };
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap_err(); .unwrap_err();
} }
#[test] #[test]
fn swizzles() { fn swizzles() {
let mut entry_points = crate::FastHashMap::default();
entry_points.insert("".to_string(), ShaderStage::Fragment);
parse_program( parse_program(
r#" r#"
# version 450 # version 450
@@ -645,7 +615,7 @@ fn swizzles() {
v.xyz.zxy.yx.xy = vec2(5.0, 1.0); v.xyz.zxy.yx.xy = vec2(5.0, 1.0);
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
@@ -657,7 +627,7 @@ fn swizzles() {
v.xx = vec2(5.0); v.xx = vec2(5.0);
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap_err(); .unwrap_err();
@@ -669,16 +639,13 @@ fn swizzles() {
v.w = 2.0; v.w = 2.0;
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap_err(); .unwrap_err();
} }
#[test] #[test]
fn vector_indexing() { fn vector_indexing() {
let mut entry_points = crate::FastHashMap::default();
entry_points.insert("".to_string(), ShaderStage::Fragment);
parse_program( parse_program(
r#" r#"
# version 450 # version 450
@@ -687,7 +654,7 @@ fn vector_indexing() {
return v[index] + 1.0; return v[index] + 1.0;
} }
"#, "#,
&entry_points, ShaderStage::Vertex,
) )
.unwrap(); .unwrap();
} }

View File

@@ -31,7 +31,7 @@ pub enum GlobalOrConstant {
Constant(Handle<Constant>), Constant(Handle<Constant>),
} }
impl Program<'_> { impl Program {
pub fn lookup_variable( pub fn lookup_variable(
&mut self, &mut self,
ctx: &mut Context, ctx: &mut Context,
@@ -45,7 +45,7 @@ impl Program<'_> {
return Ok(Some(global_var)); return Ok(Some(global_var));
} }
let mut add_builtin = |inner, builtin, mutable, prologue, storage| { let mut add_builtin = |inner, builtin, mutable, storage| {
let ty = self let ty = self
.module .module
.types .types
@@ -64,7 +64,6 @@ impl Program<'_> {
name: None, name: None,
binding: Binding::BuiltIn(builtin), binding: Binding::BuiltIn(builtin),
handle, handle,
prologue,
storage, storage,
}); });
@@ -76,7 +75,6 @@ impl Program<'_> {
mutable, mutable,
}, },
)); ));
ctx.arg_use.push(EntryArgUse::empty());
let expr = ctx.add_expression(Expression::GlobalVariable(handle), body); let expr = ctx.add_expression(Expression::GlobalVariable(handle), body);
ctx.lookup_global_var_exps.insert( ctx.lookup_global_var_exps.insert(
@@ -100,7 +98,6 @@ impl Program<'_> {
}, },
BuiltIn::Position, BuiltIn::Position,
true, true,
PrologueStage::empty(),
StorageQualifier::Output, StorageQualifier::Output,
), ),
"gl_FragCoord" => add_builtin( "gl_FragCoord" => add_builtin(
@@ -111,7 +108,6 @@ impl Program<'_> {
}, },
BuiltIn::Position, BuiltIn::Position,
false, false,
PrologueStage::FRAGMENT,
StorageQualifier::Input, StorageQualifier::Input,
), ),
"gl_FragDepth" => add_builtin( "gl_FragDepth" => add_builtin(
@@ -121,7 +117,6 @@ impl Program<'_> {
}, },
BuiltIn::FragDepth, BuiltIn::FragDepth,
true, true,
PrologueStage::empty(),
StorageQualifier::Output, StorageQualifier::Output,
), ),
"gl_VertexIndex" => add_builtin( "gl_VertexIndex" => add_builtin(
@@ -131,7 +126,6 @@ impl Program<'_> {
}, },
BuiltIn::VertexIndex, BuiltIn::VertexIndex,
false, false,
PrologueStage::VERTEX,
StorageQualifier::Input, StorageQualifier::Input,
), ),
"gl_InstanceIndex" => add_builtin( "gl_InstanceIndex" => add_builtin(
@@ -141,7 +135,6 @@ impl Program<'_> {
}, },
BuiltIn::InstanceIndex, BuiltIn::InstanceIndex,
false, false,
PrologueStage::VERTEX,
StorageQualifier::Input, StorageQualifier::Input,
), ),
"gl_GlobalInvocationID" => add_builtin( "gl_GlobalInvocationID" => add_builtin(
@@ -152,7 +145,6 @@ impl Program<'_> {
}, },
BuiltIn::GlobalInvocationId, BuiltIn::GlobalInvocationId,
false, false,
PrologueStage::COMPUTE,
StorageQualifier::Input, StorageQualifier::Input,
), ),
"gl_FrontFacing" => add_builtin( "gl_FrontFacing" => add_builtin(
@@ -162,7 +154,6 @@ impl Program<'_> {
}, },
BuiltIn::FrontFacing, BuiltIn::FrontFacing,
false, false,
PrologueStage::FRAGMENT,
StorageQualifier::Input, StorageQualifier::Input,
), ),
"gl_PrimitiveID" => add_builtin( "gl_PrimitiveID" => add_builtin(
@@ -172,7 +163,6 @@ impl Program<'_> {
}, },
BuiltIn::PrimitiveIndex, BuiltIn::PrimitiveIndex,
false, false,
PrologueStage::FRAGMENT,
StorageQualifier::Input, StorageQualifier::Input,
), ),
_ => Ok(None), _ => Ok(None),
@@ -427,11 +417,6 @@ impl Program<'_> {
if let Some(location) = location { if let Some(location) = location {
let input = storage == StorageQualifier::Input; let input = storage == StorageQualifier::Input;
let prologue = if input {
PrologueStage::all()
} else {
PrologueStage::empty()
};
let interpolation = self.module.types[ty].inner.scalar_kind().map(|kind| { let interpolation = self.module.types[ty].inner.scalar_kind().map(|kind| {
if let ScalarKind::Float = kind { if let ScalarKind::Float = kind {
Interpolation::Perspective Interpolation::Perspective
@@ -457,7 +442,6 @@ impl Program<'_> {
sampling, sampling,
}, },
handle, handle,
prologue,
storage, storage,
}); });

View File

@@ -1,19 +0,0 @@
#version 450
// vertex
void vert_main() {
gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
}
// fragment
layout(location = 0) out vec4 o_color;
void frag_main() {
o_color = vec4(1.0, 1.0, 1.0, 1.0);
}
//compute
// layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
void comp_main() {
if (gl_GlobalInvocationID.x > 1) {
return;
}
}

View File

@@ -1,6 +0,0 @@
(
spv_version: (1, 0),
glsl_vert_ep_name: Some("vert_main"),
glsl_frag_ep_name: Some("frag_main"),
glsl_comp_ep_name: Some("comp_main"),
)

View File

@@ -19,7 +19,7 @@ struct VertexOutput {
}; };
var<private> Vertex_Position1: vec3<f32>; var<private> Vertex_Position1: vec3<f32>;
var<private> Vertex_Normal: vec3<f32>; var<private> Vertex_Normal1: vec3<f32>;
var<private> Vertex_Uv1: vec2<f32>; var<private> Vertex_Uv1: vec2<f32>;
var<private> v_Uv: vec2<f32>; var<private> v_Uv: vec2<f32>;
[[group(0), binding(0)]] [[group(0), binding(0)]]
@@ -46,11 +46,12 @@ fn main1() {
} }
[[stage(vertex)]] [[stage(vertex)]]
fn main([[location(0)]] Vertex_Position: vec3<f32>, [[location(2)]] Vertex_Uv: vec2<f32>) -> VertexOutput { fn main([[location(0)]] Vertex_Position: vec3<f32>, [[location(1)]] Vertex_Normal: vec3<f32>, [[location(2)]] Vertex_Uv: vec2<f32>) -> VertexOutput {
Vertex_Position1 = Vertex_Position; Vertex_Position1 = Vertex_Position;
Vertex_Normal1 = Vertex_Normal;
Vertex_Uv1 = Vertex_Uv; Vertex_Uv1 = Vertex_Uv;
main1(); main1();
let _e5: vec2<f32> = v_Uv; let _e7: vec2<f32> = v_Uv;
let _e7: vec4<f32> = gl_Position; let _e9: vec4<f32> = gl_Position;
return VertexOutput(_e5, _e7); return VertexOutput(_e7, _e9);
} }

View File

@@ -55,15 +55,6 @@ struct Parameters {
#[cfg(all(not(feature = "deserialize"), feature = "glsl-out"))] #[cfg(all(not(feature = "deserialize"), feature = "glsl-out"))]
#[serde(default)] #[serde(default)]
glsl_custom: bool, glsl_custom: bool,
#[cfg_attr(not(feature = "glsl-out"), allow(dead_code))]
#[serde(default)]
glsl_vert_ep_name: Option<String>,
#[cfg_attr(not(feature = "glsl-out"), allow(dead_code))]
#[serde(default)]
glsl_frag_ep_name: Option<String>,
#[cfg_attr(not(feature = "glsl-out"), allow(dead_code))]
#[serde(default)]
glsl_comp_ep_name: Option<String>,
#[cfg(all(feature = "deserialize", feature = "hlsl-out"))] #[cfg(all(feature = "deserialize", feature = "hlsl-out"))]
#[serde(default)] #[serde(default)]
hlsl: naga::back::hlsl::Options, hlsl: naga::back::hlsl::Options,
@@ -530,50 +521,18 @@ fn convert_glsl_folder() {
// No needed to validate ron files // No needed to validate ron files
continue; continue;
} }
let params_path = format!(
"{}/{}/glsl/{}.params.ron",
root,
BASE_DIR_IN,
PathBuf::from(&file_name).with_extension("").display()
);
let is_params_used = PathBuf::from(&params_path).exists();
println!("Processing {}", file_name); println!("Processing {}", file_name);
let mut entry_points = naga::FastHashMap::default(); let module = naga::front::glsl::parse_str(
if is_params_used { &fs::read_to_string(entry.path()).expect("Couldn't find glsl file"),
let params: Parameters = match fs::read_to_string(&params_path) { &naga::front::glsl::Options {
Ok(string) => ron::de::from_str(&string).expect("Couldn't find param file"), stage: match entry.path().extension().and_then(|s| s.to_str()).unwrap() {
Err(_) => panic!("Can't parse glsl params ron file: {:?}", &params_path),
};
if let Some(vert) = params.glsl_vert_ep_name {
entry_points.insert(vert, naga::ShaderStage::Vertex);
};
if let Some(frag) = params.glsl_frag_ep_name {
entry_points.insert(frag, naga::ShaderStage::Fragment);
};
if let Some(comp) = params.glsl_comp_ep_name {
entry_points.insert(comp, naga::ShaderStage::Compute);
};
} else {
let stage = match entry.path().extension().and_then(|s| s.to_str()).unwrap() {
"vert" => naga::ShaderStage::Vertex, "vert" => naga::ShaderStage::Vertex,
"frag" => naga::ShaderStage::Fragment, "frag" => naga::ShaderStage::Fragment,
"comp" => naga::ShaderStage::Compute, "comp" => naga::ShaderStage::Compute,
ext => panic!("Unknown extension for glsl file {}", ext), ext => panic!("Unknown extension for glsl file {}", ext),
}; },
entry_points.insert("main".to_string(), stage);
}
let strip_unused_linkages = entry_points.len() > 1;
let module = naga::front::glsl::parse_str(
&fs::read_to_string(entry.path()).expect("Couldn't find glsl file"),
&naga::front::glsl::Options {
entry_points,
defines: Default::default(), defines: Default::default(),
strip_unused_linkages: strip_unused_linkages,
}, },
) )
.unwrap(); .unwrap();