[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" => {
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(
&input,
&naga::front::glsl::Options {
entry_points,
stage: naga::ShaderStage::Vertex,
defines: Default::default(),
strip_unused_linkages: false,
},
)
.unwrap_or_else(|err| {
@@ -241,14 +238,11 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
}
"frag" => {
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(
&input,
&naga::front::glsl::Options {
entry_points,
stage: naga::ShaderStage::Fragment,
defines: Default::default(),
strip_unused_linkages: false,
},
)
.unwrap_or_else(|err| {
@@ -259,14 +253,11 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
}
"comp" => {
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(
&input,
&naga::front::glsl::Options {
entry_points,
stage: naga::ShaderStage::Compute,
defines: Default::default(),
strip_unused_linkages: false,
},
)
.unwrap_or_else(|err| {

View File

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

View File

@@ -2,8 +2,7 @@ use crate::{
proc::ensure_block_returns, Arena, BinaryOperator, Block, Constant, ConstantInner, EntryPoint,
Expression, Function, FunctionArgument, FunctionResult, Handle, ImageClass, ImageDimension,
ImageQuery, LocalVariable, MathFunction, Module, RelationalFunction, SampleLevel, ScalarKind,
ScalarValue, ShaderStage, Statement, StructMember, SwizzleComponent, Type, TypeInner,
VectorSize,
ScalarValue, Statement, StructMember, SwizzleComponent, Type, TypeInner, VectorSize,
};
use super::{ast::*, error::ErrorKind, SourceMetadata};
@@ -17,7 +16,7 @@ struct CoordComponents {
array_index: Option<Handle<Expression>>,
}
impl Program<'_> {
impl Program {
fn add_constant_value(&mut self, scalar_kind: ScalarKind, value: u64) -> Handle<Constant> {
let value = match scalar_kind {
ScalarKind::Uint => ScalarValue::Uint(value),
@@ -1031,65 +1030,65 @@ impl Program<'_> {
parameters: Vec<Handle<Type>>,
parameters_info: Vec<ParameterInfo>,
meta: SourceMetadata,
) -> Result<Handle<Function>, ErrorKind> {
) -> Result<(), ErrorKind> {
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);
self.entries.push((name, stage, handle));
self.function_arg_use.push(Vec::new());
handle
} else {
let void = function.result.is_none();
return if self.entry_point.replace(handle).is_some() {
Err(ErrorKind::SemanticError(meta, "main defined twice".into()))
} else {
Ok(())
};
}
let &mut Program {
ref mut lookup_function,
ref mut module,
..
} = self;
let void = function.result.is_none();
let declarations = lookup_function.entry(name).or_default();
let &mut Program {
ref mut lookup_function,
ref mut module,
..
} = self;
'outer: for decl in declarations.iter_mut() {
if parameters.len() != decl.parameters.len() {
continue;
}
let declarations = lookup_function.entry(name).or_default();
for (new_parameter, old_parameter) in parameters.iter().zip(decl.parameters.iter())
{
let new_inner = &module.types[*new_parameter].inner;
let old_inner = &module.types[*old_parameter].inner;
if new_inner != old_inner {
continue 'outer;
}
}
if decl.defined {
return Err(ErrorKind::SemanticError(
meta,
"Function already defined".into(),
));
}
decl.defined = true;
decl.parameters_info = parameters_info;
*self.module.functions.get_mut(decl.handle) = function;
return Ok(decl.handle);
'outer: for decl in declarations.iter_mut() {
if parameters.len() != decl.parameters.len() {
continue;
}
self.function_arg_use.push(Vec::new());
let handle = module.functions.append(function);
declarations.push(FunctionDeclaration {
parameters,
parameters_info,
handle,
defined: true,
void,
});
handle
})
for (new_parameter, old_parameter) in parameters.iter().zip(decl.parameters.iter()) {
let new_inner = &module.types[*new_parameter].inner;
let old_inner = &module.types[*old_parameter].inner;
if new_inner != old_inner {
continue 'outer;
}
}
if decl.defined {
return Err(ErrorKind::SemanticError(
meta,
"Function already defined".into(),
));
}
decl.defined = true;
decl.parameters_info = parameters_info;
*self.module.functions.get_mut(decl.handle) = function;
return Ok(());
}
let handle = module.functions.append(function);
declarations.push(FunctionDeclaration {
parameters,
parameters_info,
handle,
defined: true,
void,
});
Ok(())
}
pub fn add_prototype(
@@ -1131,7 +1130,6 @@ impl Program<'_> {
));
}
self.function_arg_use.push(Vec::new());
let handle = module.functions.append(function);
declarations.push(FunctionDeclaration {
parameters,
@@ -1144,198 +1142,101 @@ impl Program<'_> {
Ok(())
}
fn check_call_global(
&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)),
);
pub fn add_entry_point(&mut self, function: Handle<Function>) -> Result<(), ErrorKind> {
let mut arguments = Vec::new();
let mut expressions = Arena::new();
let mut body = Vec::new();
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 expressions = Arena::new();
let mut body = Vec::new();
let can_strip_stage_inputs =
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 {
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 idx = arguments.len() as u32;
arguments.push(FunctionArgument {
name: arg.name.clone(),
ty,
binding: Some(arg.binding.clone()),
});
let pointer = expressions.append(Expression::GlobalVariable(arg.handle));
let value = expressions.append(Expression::FunctionArgument(idx));
body.push(Statement::Store { pointer, value });
for arg in self.entry_args.iter() {
if arg.storage != StorageQualifier::Input {
continue;
}
body.push(Statement::Call {
function,
arguments: Vec::new(),
result: None,
let ty = self.module.global_variables[arg.handle].ty;
let idx = arguments.len() as u32;
arguments.push(FunctionArgument {
name: arg.name.clone(),
ty,
binding: Some(arg.binding.clone()),
});
let mut span = 0;
let mut members = Vec::new();
let mut components = Vec::new();
let pointer = expressions.append(Expression::GlobalVariable(arg.handle));
let value = expressions.append(Expression::FunctionArgument(idx));
for (i, arg) in self.entry_args.iter().enumerate() {
if arg.storage != StorageQualifier::Output {
continue;
}
body.push(Statement::Store { pointer, value });
}
let is_used = function_arg_use[function.index()]
.get(i)
.map_or(false, |u| u.contains(EntryArgUse::WRITE));
body.push(Statement::Call {
function,
arguments: Vec::new(),
result: None,
});
if can_strip_stage_outputs && !is_used {
continue;
}
let mut span = 0;
let mut members = Vec::new();
let mut components = Vec::new();
let ty = self.module.global_variables[arg.handle].ty;
members.push(StructMember {
name: arg.name.clone(),
ty,
binding: Some(arg.binding.clone()),
offset: span,
});
span += self.module.types[ty].inner.span(&self.module.constants);
let pointer = expressions.append(Expression::GlobalVariable(arg.handle));
let len = expressions.len();
let load = expressions.append(Expression::Load { pointer });
body.push(Statement::Emit(expressions.range_from(len)));
components.push(load)
for arg in self.entry_args.iter() {
if arg.storage != StorageQualifier::Output {
continue;
}
let (ty, value) = if !components.is_empty() {
let ty = self.module.types.append(Type {
name: None,
inner: TypeInner::Struct {
top_level: false,
members,
span,
},
});
let ty = self.module.global_variables[arg.handle].ty;
let len = expressions.len();
let res = expressions.append(Expression::Compose { ty, components });
body.push(Statement::Emit(expressions.range_from(len)));
members.push(StructMember {
name: arg.name.clone(),
ty,
binding: Some(arg.binding.clone()),
offset: span,
});
(Some(ty), Some(res))
} else {
(None, None)
};
span += self.module.types[ty].inner.span(&self.module.constants);
body.push(Statement::Return { value });
let pointer = expressions.append(Expression::GlobalVariable(arg.handle));
let len = expressions.len();
let load = expressions.append(Expression::Load { pointer });
body.push(Statement::Emit(expressions.range_from(len)));
components.push(load)
}
self.module.entry_points.push(EntryPoint {
name,
stage,
early_depth_test: Some(crate::EarlyDepthTest { conservative: None })
.filter(|_| self.early_fragment_tests && stage == crate::ShaderStage::Fragment),
workgroup_size: if let crate::ShaderStage::Compute = stage {
self.workgroup_size
} else {
[0; 3]
},
function: Function {
arguments,
expressions,
body,
result: ty.map(|ty| FunctionResult { ty, binding: None }),
..Default::default()
let (ty, value) = if !components.is_empty() {
let ty = self.module.types.append(Type {
name: None,
inner: TypeInner::Struct {
top_level: false,
members,
span,
},
});
}
let len = expressions.len();
let res = expressions.append(Expression::Compose { ty, components });
body.push(Statement::Emit(expressions.range_from(len)));
(Some(ty), Some(res))
} else {
(None, None)
};
body.push(Statement::Return { value });
self.module.entry_points.push(EntryPoint {
name: "main".to_string(),
stage: self.stage,
early_depth_test: Some(crate::EarlyDepthTest { conservative: None })
.filter(|_| self.early_fragment_tests),
workgroup_size: self.workgroup_size,
function: Function {
arguments,
expressions,
body,
result: ty.map(|ty| FunctionResult { ty, binding: None }),
..Default::default()
},
});
Ok(())
}
/// Helper function for texture calls, splits the vector argument into it's components

View File

@@ -20,15 +20,13 @@ mod token;
mod types;
mod variables;
#[derive(Default)]
pub struct Options {
pub entry_points: FastHashMap<String, ShaderStage>,
pub stage: ShaderStage,
pub defines: FastHashMap<String, String>,
pub strip_unused_linkages: bool,
}
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 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>;
pub struct Parser<'source, 'program, 'options> {
program: &'program mut Program<'options>,
pub struct Parser<'source, 'program> {
program: &'program mut Program,
lexer: Peekable<Lexer<'source>>,
}
impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
pub fn new(program: &'program mut Program<'options>, lexer: Lexer<'source>) -> Self {
impl<'source, 'program> Parser<'source, 'program> {
pub fn new(program: &'program mut Program, lexer: Lexer<'source>) -> Self {
Parser {
program,
lexer: lexer.peekable(),
@@ -81,7 +81,9 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
self.parse_external_declaration()?;
}
self.program.add_entry_points();
if let Some(handle) = self.program.entry_point {
self.program.add_entry_point(handle)?;
}
Ok(())
}
@@ -741,11 +743,9 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
self.parse_compound_statement(&mut context, &mut body)?;
let Context {
arg_use,
parameters_info,
..
parameters_info, ..
} = context;
let handle = self.program.add_function(
self.program.add_function(
Function {
name: Some(name.clone()),
result,
@@ -761,8 +761,6 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> {
meta,
)?;
self.program.function_arg_use[handle.index()] = arg_use;
Ok(true)
}
_ if external => Err(ErrorKind::InvalidToken(

View File

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

View File

@@ -31,7 +31,7 @@ pub enum GlobalOrConstant {
Constant(Handle<Constant>),
}
impl Program<'_> {
impl Program {
pub fn lookup_variable(
&mut self,
ctx: &mut Context,
@@ -45,7 +45,7 @@ impl Program<'_> {
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
.module
.types
@@ -64,7 +64,6 @@ impl Program<'_> {
name: None,
binding: Binding::BuiltIn(builtin),
handle,
prologue,
storage,
});
@@ -76,7 +75,6 @@ impl Program<'_> {
mutable,
},
));
ctx.arg_use.push(EntryArgUse::empty());
let expr = ctx.add_expression(Expression::GlobalVariable(handle), body);
ctx.lookup_global_var_exps.insert(
@@ -100,7 +98,6 @@ impl Program<'_> {
},
BuiltIn::Position,
true,
PrologueStage::empty(),
StorageQualifier::Output,
),
"gl_FragCoord" => add_builtin(
@@ -111,7 +108,6 @@ impl Program<'_> {
},
BuiltIn::Position,
false,
PrologueStage::FRAGMENT,
StorageQualifier::Input,
),
"gl_FragDepth" => add_builtin(
@@ -121,7 +117,6 @@ impl Program<'_> {
},
BuiltIn::FragDepth,
true,
PrologueStage::empty(),
StorageQualifier::Output,
),
"gl_VertexIndex" => add_builtin(
@@ -131,7 +126,6 @@ impl Program<'_> {
},
BuiltIn::VertexIndex,
false,
PrologueStage::VERTEX,
StorageQualifier::Input,
),
"gl_InstanceIndex" => add_builtin(
@@ -141,7 +135,6 @@ impl Program<'_> {
},
BuiltIn::InstanceIndex,
false,
PrologueStage::VERTEX,
StorageQualifier::Input,
),
"gl_GlobalInvocationID" => add_builtin(
@@ -152,7 +145,6 @@ impl Program<'_> {
},
BuiltIn::GlobalInvocationId,
false,
PrologueStage::COMPUTE,
StorageQualifier::Input,
),
"gl_FrontFacing" => add_builtin(
@@ -162,7 +154,6 @@ impl Program<'_> {
},
BuiltIn::FrontFacing,
false,
PrologueStage::FRAGMENT,
StorageQualifier::Input,
),
"gl_PrimitiveID" => add_builtin(
@@ -172,7 +163,6 @@ impl Program<'_> {
},
BuiltIn::PrimitiveIndex,
false,
PrologueStage::FRAGMENT,
StorageQualifier::Input,
),
_ => Ok(None),
@@ -427,11 +417,6 @@ impl Program<'_> {
if let Some(location) = location {
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| {
if let ScalarKind::Float = kind {
Interpolation::Perspective
@@ -457,7 +442,6 @@ impl Program<'_> {
sampling,
},
handle,
prologue,
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_Normal: vec3<f32>;
var<private> Vertex_Normal1: vec3<f32>;
var<private> Vertex_Uv1: vec2<f32>;
var<private> v_Uv: vec2<f32>;
[[group(0), binding(0)]]
@@ -46,11 +46,12 @@ fn main1() {
}
[[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_Normal1 = Vertex_Normal;
Vertex_Uv1 = Vertex_Uv;
main1();
let _e5: vec2<f32> = v_Uv;
let _e7: vec4<f32> = gl_Position;
return VertexOutput(_e5, _e7);
let _e7: vec2<f32> = v_Uv;
let _e9: vec4<f32> = gl_Position;
return VertexOutput(_e7, _e9);
}

View File

@@ -55,15 +55,6 @@ struct Parameters {
#[cfg(all(not(feature = "deserialize"), feature = "glsl-out"))]
#[serde(default)]
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"))]
#[serde(default)]
hlsl: naga::back::hlsl::Options,
@@ -530,50 +521,18 @@ fn convert_glsl_folder() {
// No needed to validate ron files
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);
let mut entry_points = naga::FastHashMap::default();
if is_params_used {
let params: Parameters = match fs::read_to_string(&params_path) {
Ok(string) => ron::de::from_str(&string).expect("Couldn't find param file"),
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,
"frag" => naga::ShaderStage::Fragment,
"comp" => naga::ShaderStage::Compute,
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,
stage: match entry.path().extension().and_then(|s| s.to_str()).unwrap() {
"vert" => naga::ShaderStage::Vertex,
"frag" => naga::ShaderStage::Fragment,
"comp" => naga::ShaderStage::Compute,
ext => panic!("Unknown extension for glsl file {}", ext),
},
defines: Default::default(),
strip_unused_linkages: strip_unused_linkages,
},
)
.unwrap();