mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Refactor the global usage code into a separate module, fix inheriting from the callees
This commit is contained in:
111
src/front/global_usage.rs
Normal file
111
src/front/global_usage.rs
Normal file
@@ -0,0 +1,111 @@
|
||||
use crate::{
|
||||
arena::{Arena, Handle},
|
||||
proc::{Interface, Visitor},
|
||||
};
|
||||
|
||||
struct GlobalUseVisitor<'a> {
|
||||
usage: &'a mut [crate::GlobalUse],
|
||||
functions: &'a Arena<crate::Function>,
|
||||
}
|
||||
|
||||
impl Visitor for GlobalUseVisitor<'_> {
|
||||
fn visit_expr(&mut self, expr: &crate::Expression) {
|
||||
if let crate::Expression::GlobalVariable(handle) = expr {
|
||||
self.usage[handle.index()] |= crate::GlobalUse::READ;
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_lhs_expr(&mut self, expr: &crate::Expression) {
|
||||
if let crate::Expression::GlobalVariable(handle) = expr {
|
||||
self.usage[handle.index()] |= crate::GlobalUse::WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_fun(&mut self, fun: Handle<crate::Function>) {
|
||||
for (mine, other) in self.usage.iter_mut().zip(&self.functions[fun].global_usage) {
|
||||
*mine |= *other;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Function {
|
||||
pub fn fill_global_use(&mut self, globals_num: usize, functions: &Arena<crate::Function>) {
|
||||
self.global_usage.clear();
|
||||
self.global_usage
|
||||
.resize(globals_num, crate::GlobalUse::empty());
|
||||
|
||||
let mut io = Interface {
|
||||
expressions: &self.expressions,
|
||||
local_variables: &self.local_variables,
|
||||
visitor: GlobalUseVisitor {
|
||||
usage: &mut self.global_usage,
|
||||
functions,
|
||||
},
|
||||
};
|
||||
io.traverse(&self.body);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_usage_scan() {
|
||||
let test_global = crate::GlobalVariable {
|
||||
name: None,
|
||||
class: crate::StorageClass::Uniform,
|
||||
binding: None,
|
||||
ty: Handle::new(std::num::NonZeroU32::new(1).unwrap()),
|
||||
init: None,
|
||||
interpolation: None,
|
||||
storage_access: crate::StorageAccess::empty(),
|
||||
};
|
||||
let mut test_globals = Arena::new();
|
||||
|
||||
let global_1 = test_globals.append(test_global.clone());
|
||||
let global_2 = test_globals.append(test_global.clone());
|
||||
let global_3 = test_globals.append(test_global.clone());
|
||||
let global_4 = test_globals.append(test_global);
|
||||
|
||||
let mut expressions = Arena::new();
|
||||
let global_1_expr = expressions.append(crate::Expression::GlobalVariable(global_1));
|
||||
let global_2_expr = expressions.append(crate::Expression::GlobalVariable(global_2));
|
||||
let global_3_expr = expressions.append(crate::Expression::GlobalVariable(global_3));
|
||||
let global_4_expr = expressions.append(crate::Expression::GlobalVariable(global_4));
|
||||
|
||||
let test_body = vec![
|
||||
crate::Statement::Return {
|
||||
value: Some(global_1_expr),
|
||||
},
|
||||
crate::Statement::Store {
|
||||
pointer: global_2_expr,
|
||||
value: global_1_expr,
|
||||
},
|
||||
crate::Statement::Store {
|
||||
pointer: expressions.append(crate::Expression::Access {
|
||||
base: global_3_expr,
|
||||
index: global_4_expr,
|
||||
}),
|
||||
value: global_1_expr,
|
||||
},
|
||||
];
|
||||
|
||||
let mut function = crate::Function {
|
||||
name: None,
|
||||
arguments: Vec::new(),
|
||||
return_type: None,
|
||||
local_variables: Arena::new(),
|
||||
expressions,
|
||||
global_usage: Vec::new(),
|
||||
body: test_body,
|
||||
};
|
||||
let other_functions = Arena::new();
|
||||
function.fill_global_use(test_globals.len(), &other_functions);
|
||||
|
||||
assert_eq!(
|
||||
&function.global_usage,
|
||||
&[
|
||||
crate::GlobalUse::READ,
|
||||
crate::GlobalUse::WRITE,
|
||||
crate::GlobalUse::WRITE,
|
||||
crate::GlobalUse::READ,
|
||||
],
|
||||
)
|
||||
}
|
||||
@@ -272,7 +272,7 @@ impl Program {
|
||||
self.context.typifier = Typifier::new();
|
||||
ensure_block_returns(&mut block);
|
||||
f.body = block;
|
||||
f.fill_global_use(&self.module.global_variables);
|
||||
f.fill_global_use(self.module.global_variables.len(), &self.module.functions);
|
||||
f
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
//! Parsers which load shaders into memory.
|
||||
|
||||
mod global_usage;
|
||||
|
||||
#[cfg(feature = "glsl-in")]
|
||||
pub mod glsl;
|
||||
#[cfg(feature = "spv-in")]
|
||||
|
||||
@@ -146,7 +146,7 @@ impl<I: Iterator<Item = u32>> super::Parser<I> {
|
||||
fun.body = flow_graph.to_naga()?;
|
||||
|
||||
// done
|
||||
fun.fill_global_use(&module.global_variables);
|
||||
fun.fill_global_use(module.global_variables.len(), &module.functions);
|
||||
|
||||
let dump_suffix = match self.lookup_entry_point.remove(&fun_id) {
|
||||
Some(ep) => {
|
||||
|
||||
@@ -1875,7 +1875,7 @@ impl Parser {
|
||||
// fixup the IR
|
||||
ensure_block_returns(&mut fun.body);
|
||||
// done
|
||||
fun.fill_global_use(&module.global_variables);
|
||||
fun.fill_global_use(module.global_variables.len(), &module.functions);
|
||||
self.scopes.pop();
|
||||
|
||||
Ok((fun, fun_name))
|
||||
|
||||
@@ -216,105 +216,3 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct GlobalUseVisitor<'a>(&'a mut [crate::GlobalUse]);
|
||||
|
||||
impl Visitor for GlobalUseVisitor<'_> {
|
||||
fn visit_expr(&mut self, expr: &crate::Expression) {
|
||||
if let crate::Expression::GlobalVariable(handle) = expr {
|
||||
self.0[handle.index()] |= crate::GlobalUse::READ;
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_lhs_expr(&mut self, expr: &crate::Expression) {
|
||||
if let crate::Expression::GlobalVariable(handle) = expr {
|
||||
self.0[handle.index()] |= crate::GlobalUse::WRITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Function {
|
||||
pub fn fill_global_use(&mut self, globals: &Arena<crate::GlobalVariable>) {
|
||||
self.global_usage.clear();
|
||||
self.global_usage
|
||||
.resize(globals.len(), crate::GlobalUse::empty());
|
||||
|
||||
let mut io = Interface {
|
||||
expressions: &self.expressions,
|
||||
local_variables: &self.local_variables,
|
||||
visitor: GlobalUseVisitor(&mut self.global_usage),
|
||||
};
|
||||
io.traverse(&self.body);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
Arena, Expression, GlobalUse, GlobalVariable, Handle, Statement, StorageAccess,
|
||||
StorageClass,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn global_use_scan() {
|
||||
let test_global = GlobalVariable {
|
||||
name: None,
|
||||
class: StorageClass::Uniform,
|
||||
binding: None,
|
||||
ty: Handle::new(std::num::NonZeroU32::new(1).unwrap()),
|
||||
init: None,
|
||||
interpolation: None,
|
||||
storage_access: StorageAccess::empty(),
|
||||
};
|
||||
let mut test_globals = Arena::new();
|
||||
|
||||
let global_1 = test_globals.append(test_global.clone());
|
||||
let global_2 = test_globals.append(test_global.clone());
|
||||
let global_3 = test_globals.append(test_global.clone());
|
||||
let global_4 = test_globals.append(test_global);
|
||||
|
||||
let mut expressions = Arena::new();
|
||||
let global_1_expr = expressions.append(Expression::GlobalVariable(global_1));
|
||||
let global_2_expr = expressions.append(Expression::GlobalVariable(global_2));
|
||||
let global_3_expr = expressions.append(Expression::GlobalVariable(global_3));
|
||||
let global_4_expr = expressions.append(Expression::GlobalVariable(global_4));
|
||||
|
||||
let test_body = vec![
|
||||
Statement::Return {
|
||||
value: Some(global_1_expr),
|
||||
},
|
||||
Statement::Store {
|
||||
pointer: global_2_expr,
|
||||
value: global_1_expr,
|
||||
},
|
||||
Statement::Store {
|
||||
pointer: expressions.append(Expression::Access {
|
||||
base: global_3_expr,
|
||||
index: global_4_expr,
|
||||
}),
|
||||
value: global_1_expr,
|
||||
},
|
||||
];
|
||||
|
||||
let mut function = crate::Function {
|
||||
name: None,
|
||||
arguments: Vec::new(),
|
||||
return_type: None,
|
||||
local_variables: Arena::new(),
|
||||
expressions,
|
||||
global_usage: Vec::new(),
|
||||
body: test_body,
|
||||
};
|
||||
function.fill_global_use(&test_globals);
|
||||
|
||||
assert_eq!(
|
||||
&function.global_usage,
|
||||
&[
|
||||
GlobalUse::READ,
|
||||
GlobalUse::WRITE,
|
||||
GlobalUse::WRITE,
|
||||
GlobalUse::READ,
|
||||
],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,9 @@ struct fs_mainOutput {
|
||||
fragment fs_mainOutput fs_main(
|
||||
fs_mainInput input [[stage_in]],
|
||||
constant Globals& u_globals [[buffer(0)]],
|
||||
constant Lights& s_lights [[buffer(1)]]
|
||||
constant Lights& s_lights [[buffer(1)]],
|
||||
type4 t_shadow [[texture(0)]],
|
||||
type5 sampler_shadow [[sampler(0)]]
|
||||
) {
|
||||
fs_mainOutput output;
|
||||
type10 color1 = type10(0.05, 0.05, 0.05);
|
||||
|
||||
@@ -799,10 +799,10 @@ expression: output
|
||||
return_type: None,
|
||||
global_usage: [
|
||||
(
|
||||
bits: 0,
|
||||
bits: 1,
|
||||
),
|
||||
(
|
||||
bits: 0,
|
||||
bits: 1,
|
||||
),
|
||||
(
|
||||
bits: 1,
|
||||
|
||||
Reference in New Issue
Block a user