[glsl-out] Reworked the backend

The backend now works in a similar way to the msl backend
Should require less loops, allocations and backtracking
Overall just better to work with it

Added a build script which reads a file with the glsl keywords and
generates a slice to be used in the Namer

Added a way to build a call graph
This commit is contained in:
Capucho
2020-11-21 18:45:05 +00:00
committed by Dzmitry Malyshau
parent 23b1e4dd76
commit dd5021234d
7 changed files with 1300 additions and 1475 deletions

View File

@@ -8,6 +8,7 @@ homepage = "https://github.com/gfx-rs/naga"
repository = "https://github.com/gfx-rs/naga"
keywords = ["shader", "SPIR-V"]
license = "MIT OR Apache-2.0"
build = "build.rs"
[dependencies]
bitflags = "1"
@@ -24,7 +25,7 @@ petgraph = { version ="0.5", optional = true }
default = []
glsl-in = ["pomelo"]
glsl-validate = []
glsl-out = []
glsl-out = ["petgraph"]
msl-out = []
serialize = ["serde"]
deserialize = ["serde"]

26
build.rs Normal file
View File

@@ -0,0 +1,26 @@
use std::{
env,
fs::{read_to_string, OpenOptions},
io::{Result, Write},
};
fn main() -> Result<()> {
println!("cargo:rerun-if-changed=glsl-keywords.txt");
let keywords = read_to_string("glsl-keywords.txt")?.replace('\n', " ");
let mut out = OpenOptions::new()
.write(true)
.truncate(true)
.create(true)
.open(format!("{}/glsl_keywords.rs", env::var("OUT_DIR").unwrap()))?;
writeln!(&mut out, "const RESERVED_KEYWORDS: &[&str] = &[")?;
for keyword in keywords.split(' ') {
writeln!(&mut out, "\"{}\",", keyword)?;
}
writeln!(&mut out, "];")?;
Ok(())
}

View File

@@ -216,14 +216,17 @@ fn main() {
),
};
let mut file = fs::OpenOptions::new()
let file = fs::OpenOptions::new()
.write(true)
.truncate(true)
.create(true)
.open(&args[2])
.unwrap();
glsl::write(&module, &mut file, options)
let mut writer = glsl::Writer::new(file, &module, &options).unwrap();
writer
.write()
.map_err(|e| {
fs::remove_file(&args[2]).unwrap();
e

20
glsl-keywords.txt Normal file
View File

@@ -0,0 +1,20 @@
attribute const uniform varying buffer shared coherent volatile restrict readonly writeonly
atomic_uint layout centroid flat smooth noperspective patch sample break continue do for while
switch case default if else subroutine in out inout float double int void bool true false invariant
precise discard return mat2 mat3 mat4 dmat2 dmat3 dmat4 mat2x2 mat2x3 mat2x4 dmat2x2 dmat2x3 dmat2x4
mat3x2 mat3x3 mat3x4 dmat3x2 dmat3x3 dmat3x4 mat4x2 mat4x3 mat4x4 dmat4x2 dmat4x3 dmat4x4 vec2 vec3
vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 dvec2 dvec3 dvec4 uint uvec2 uvec3 uvec4 lowp mediump highp
precision sampler1D sampler2D sampler3D samplerCube sampler1DShadow sampler2DShadow
samplerCubeShadow sampler1DArray sampler2DArray sampler1DArrayShadow sampler2DArrayShadow
isampler1D isampler2D isampler3D isamplerCube isampler1DArray isampler2DArray usampler1D usampler2D
usampler3D usamplerCube usampler1DArray usampler2DArray sampler2DRect sampler2DRectShadow isampler2D
Rect usampler2DRect samplerBuffer isamplerBuffer usamplerBuffer sampler2DMS isampler2DMS
usampler2DMS sampler2DMSArray isampler2DMSArray usampler2DMSArray samplerCubeArray
samplerCubeArrayShadow isamplerCubeArray usamplerCubeArray image1D iimage1D uimage1D image2D
iimage2D uimage2D image3D iimage3D uimage3D image2DRect iimage2DRect uimage2DRect imageCube
iimageCube uimageCube imageBuffer iimageBuffer uimageBuffer image1DArray iimage1DArray uimage1DArray
image2DArray iimage2DArray uimage2DArray imageCubeArray iimageCubeArray uimageCubeArray image2DMS
iimage2DMS uimage2DMS image2DMSArray iimage2DMSArray uimage2DMSArraystruct common partition active
asm class union enum typedef template this resource goto inline noinline public static extern
external interface long short half fixed unsigned superp input output hvec2 hvec3 hvec4 fvec2 fvec3
fvec4 sampler3DRect filter sizeof cast namespace using main

File diff suppressed because it is too large Load Diff

74
src/proc/call_graph.rs Normal file
View File

@@ -0,0 +1,74 @@
use crate::{
arena::{Arena, Handle},
proc::{Interface, Visitor},
Function,
};
use petgraph::{
graph::{DefaultIx, NodeIndex},
Graph,
};
pub type CallGraph = Graph<Handle<Function>, ()>;
pub struct CallGraphBuilder<'a> {
pub functions: &'a Arena<Function>,
}
impl<'a> CallGraphBuilder<'a> {
pub fn process(&self, func: &Function) -> CallGraph {
let mut graph = Graph::new();
let mut children = Vec::new();
let visitor = CallGraphVisitor {
children: &mut children,
};
let mut interface = Interface {
expressions: &func.expressions,
local_variables: &func.local_variables,
visitor,
};
interface.traverse(&func.body);
for handle in children {
let id = graph.add_node(handle);
self.collect(handle, id, &mut graph);
}
graph
}
fn collect(&self, handle: Handle<Function>, id: NodeIndex<DefaultIx>, graph: &mut CallGraph) {
let mut children = Vec::new();
let visitor = CallGraphVisitor {
children: &mut children,
};
let func = &self.functions[handle];
let mut interface = Interface {
expressions: &func.expressions,
local_variables: &func.local_variables,
visitor,
};
interface.traverse(&func.body);
for handle in children {
let child_id = graph.add_node(handle);
graph.add_edge(id, child_id, ());
self.collect(handle, child_id, graph);
}
}
}
struct CallGraphVisitor<'a> {
children: &'a mut Vec<Handle<Function>>,
}
impl<'a> Visitor for CallGraphVisitor<'a> {
fn visit_fun(&mut self, func: Handle<Function>) {
self.children.push(func)
}
}

View File

@@ -1,10 +1,14 @@
//! Module processing functionality.
#[cfg(feature = "petgraph")]
mod call_graph;
mod interface;
mod namer;
mod typifier;
mod validator;
#[cfg(feature = "petgraph")]
pub use call_graph::{CallGraph, CallGraphBuilder};
pub use interface::{Interface, Visitor};
pub use namer::{EntryPointIndex, NameKey, Namer};
pub use typifier::{check_constant_type, ResolveContext, ResolveError, Typifier};