From 0152fd0803446612ee7de627e3adfe3a3a649df1 Mon Sep 17 00:00:00 2001 From: VitalyR Date: Mon, 24 Jul 2023 19:11:31 +0800 Subject: [PATCH 1/3] update naga to 0.13.0 --- Cargo.toml | 4 +- src/derive.rs | 101 ++++++++++++++++++++++++++++++++++++++++-------- src/redirect.rs | 1 + 3 files changed, 87 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5741a96..f406263 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ prune = [] override_any = [] [dependencies] -naga = { version="0.12", features = ["wgsl-in", "wgsl-out", "glsl-in", "glsl-out", "clone", "span"] } +naga = { version="0.13", features = ["wgsl-in", "wgsl-out", "glsl-in", "glsl-out", "clone", "span"] } tracing = "0.1" regex = "1.5" regex-syntax = "0.6" @@ -29,6 +29,6 @@ once_cell = "1.17.0" indexmap = "1.9.3" [dev-dependencies] -wgpu = { version = "0.16", features=["naga"] } +wgpu = { version = "0.17", features=["naga"] } futures-lite = "1" tracing-subscriber = { version = "0.3", features = ["std", "fmt"] } diff --git a/src/derive.rs b/src/derive.rs index 12a1dae..7b5682a 100644 --- a/src/derive.rs +++ b/src/derive.rs @@ -1,7 +1,7 @@ use indexmap::IndexMap; use naga::{ - Arena, ArraySize, Block, Constant, ConstantInner, EntryPoint, Expression, Function, - FunctionArgument, FunctionResult, GlobalVariable, Handle, ImageQuery, LocalVariable, Module, + Arena, ArraySize, Block, Constant, EntryPoint, Expression, Function, FunctionArgument, + FunctionResult, GlobalVariable, Handle, ImageQuery, LocalVariable, Module, Override, SampleLevel, Span, Statement, StructMember, SwitchCase, Type, TypeInner, UniqueArena, }; use std::collections::HashMap; @@ -13,11 +13,13 @@ pub struct DerivedModule<'a> { type_map: HashMap, Handle>, const_map: HashMap, Handle>, + const_expression_map: HashMap, Handle>, global_map: HashMap, Handle>, function_map: HashMap>, types: UniqueArena, constants: Arena, + const_expressions: Arena, globals: Arena, functions: Arena, } @@ -104,7 +106,7 @@ impl<'a> DerivedModule<'a> { } TypeInner::Array { base, size, stride } => { let size = match size { - ArraySize::Constant(c) => ArraySize::Constant(self.import_const(c)), + c @ ArraySize::Constant(_) => *c, ArraySize::Dynamic => ArraySize::Dynamic, }; TypeInner::Array { @@ -115,7 +117,7 @@ impl<'a> DerivedModule<'a> { } TypeInner::BindingArray { base, size } => { let size = match size { - ArraySize::Constant(c) => ArraySize::Constant(self.import_const(c)), + c @ ArraySize::Constant(_) => *c, ArraySize::Dynamic => ArraySize::Dynamic, }; TypeInner::BindingArray { @@ -145,16 +147,14 @@ impl<'a> DerivedModule<'a> { let new_const = Constant { name: c.name.clone(), - specialization: c.specialization, - inner: match &c.inner { - ConstantInner::Scalar { .. } => c.inner.clone(), - ConstantInner::Composite { ty, components } => { - let components = components.iter().map(|c| self.import_const(c)).collect(); - ConstantInner::Composite { - ty: self.import_type(ty), - components, - } - } + r#override: c.r#override.clone(), + ty: self.import_type(&c.ty), + //TODO: infinite recursion? + init: if c.r#override == Override::None { + self.import_const_expression(&c.init) + } else { + // r#override doesn't do anything now + unreachable!() }, }; @@ -183,7 +183,7 @@ impl<'a> DerivedModule<'a> { space: gv.space, binding: gv.binding.clone(), ty: self.import_type(&gv.ty), - init: gv.init.map(|c| self.import_const(&c)), + init: gv.init.map(|c| self.import_const_expression(&c)), }; let span = self @@ -199,6 +199,63 @@ impl<'a> DerivedModule<'a> { new_h }) } + // remap a const expression from source context into our derived context + pub fn import_const_expression( + &mut self, + const_expression_handle: &Handle, + ) -> Handle { + self.const_expression_map + .get(const_expression_handle) + .copied() + .unwrap_or_else(|| { + let old_c = self + .shader + .as_ref() + .unwrap() + .const_expressions + .try_get(*const_expression_handle) + .unwrap(); + + let new_const = match old_c { + Expression::Constant(h_c) => { + let c = self + .shader + .as_ref() + .unwrap() + .constants + .try_get(*h_c) + .unwrap(); + + Constant { + name: c.name.clone(), + r#override: c.r#override.clone(), + ty: self.import_type(&c.ty), + init: self.import_const_expression(&c.init), + } + } + // TODO + // What should I do? + _ => todo!(), + }; + + let span = self + .shader + .as_ref() + .unwrap() + .const_expressions + .get_span(*const_expression_handle); + let new_constant_handle = self + .constants + .fetch_or_append(new_const, self.map_span(span)); + let new_const_expression = naga::Expression::Constant(new_constant_handle); + let new_const_expression_handle = self + .const_expressions + .append(new_const_expression, self.map_span(span)); + self.const_expression_map + .insert(*const_expression_handle, new_const_expression_handle); + new_const_expression_handle + }) + } // remap a block fn import_block( @@ -325,6 +382,12 @@ impl<'a> DerivedModule<'a> { value: map_expr!(value), result: map_expr!(result), }, + Statement::WorkGroupUniformLoad { pointer, result } => { + Statement::WorkGroupUniformLoad { + pointer: map_expr!(pointer), + result: map_expr!(result), + } + } Statement::Return { value } => Statement::Return { value: map_expr_opt!(value), }, @@ -406,6 +469,8 @@ impl<'a> DerivedModule<'a> { let mut is_external = false; let expr = old_expressions.try_get(h_expr).unwrap(); let expr = match expr { + Expression::Literal(_) => expr.clone(), + Expression::ZeroValue(zv) => Expression::ZeroValue(self.import_type(zv)), Expression::CallResult(f) => Expression::CallResult(self.map_function_handle(f)), Expression::Constant(c) => { is_external = true; @@ -434,7 +499,7 @@ impl<'a> DerivedModule<'a> { gather: *gather, coordinate: map_expr!(coordinate), array_index: map_expr_opt!(array_index), - offset: offset.map(|c| self.import_const(&c)), + offset: offset.map(|c| self.import_const_expression(&c)), level: match level { SampleLevel::Auto | SampleLevel::Zero => *level, SampleLevel::Exact(expr) => SampleLevel::Exact(map_expr!(expr)), @@ -549,6 +614,7 @@ impl<'a> DerivedModule<'a> { } Expression::AtomicResult { .. } => expr.clone(), + Expression::WorkGroupUniformLoadResult { .. } => expr.clone(), Expression::RayQueryProceedResult => expr.clone(), Expression::RayQueryGetIntersection { query, committed } => { Expression::RayQueryGetIntersection { @@ -591,7 +657,7 @@ impl<'a> DerivedModule<'a> { let new_local = LocalVariable { name: l.name.clone(), ty: self.import_type(&l.ty), - init: l.init.map(|c| self.import_const(&c)), + init: l.init.map(|c| self.import_const_expression(&c)), }; let span = func.local_variables.get_span(h_l); let new_h = local_variables.append(new_local, self.map_span(span)); @@ -688,6 +754,7 @@ impl<'a> From> for naga::Module { types: derived.types, constants: derived.constants, global_variables: derived.globals, + const_expressions: derived.const_expressions, functions: derived.functions, special_types: Default::default(), entry_points: Default::default(), diff --git a/src/redirect.rs b/src/redirect.rs index 32e6c5f..eca25bd 100644 --- a/src/redirect.rs +++ b/src/redirect.rs @@ -62,6 +62,7 @@ impl Redirector { | Statement::Break | Statement::Continue | Statement::Return { .. } + | Statement::WorkGroupUniformLoad { .. } | Statement::Kill | Statement::Barrier(_) | Statement::Store { .. } From eeb62e3a0baa1fcb20763be1563bd21e36849932 Mon Sep 17 00:00:00 2001 From: VitalyR Date: Tue, 25 Jul 2023 14:22:26 +0800 Subject: [PATCH 2/3] elide useless expr --- src/derive.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/derive.rs b/src/derive.rs index 7b5682a..37f3318 100644 --- a/src/derive.rs +++ b/src/derive.rs @@ -104,17 +104,11 @@ impl<'a> DerivedModule<'a> { span: *span, } } - TypeInner::Array { base, size, stride } => { - let size = match size { - c @ ArraySize::Constant(_) => *c, - ArraySize::Dynamic => ArraySize::Dynamic, - }; - TypeInner::Array { - base: self.import_type(base), - size, - stride: *stride, - } - } + TypeInner::Array { base, size, stride } => TypeInner::Array { + base: self.import_type(base), + size: *size, + stride: *stride, + }, TypeInner::BindingArray { base, size } => { let size = match size { c @ ArraySize::Constant(_) => *c, @@ -149,7 +143,7 @@ impl<'a> DerivedModule<'a> { name: c.name.clone(), r#override: c.r#override.clone(), ty: self.import_type(&c.ty), - //TODO: infinite recursion? + // TODO: infinite recursion? init: if c.r#override == Override::None { self.import_const_expression(&c.init) } else { From 46e7dedf73fa13489cd8b22a927755b75cd8e80f Mon Sep 17 00:00:00 2001 From: VitalyR Date: Thu, 27 Jul 2023 17:50:56 +0800 Subject: [PATCH 3/3] Use RefCell other than &mut T --- src/derive.rs | 438 ++++++++++++++++++++++++-------------------------- 1 file changed, 212 insertions(+), 226 deletions(-) diff --git a/src/derive.rs b/src/derive.rs index 37f3318..6097aca 100644 --- a/src/derive.rs +++ b/src/derive.rs @@ -1,9 +1,10 @@ use indexmap::IndexMap; use naga::{ - Arena, ArraySize, Block, Constant, EntryPoint, Expression, Function, FunctionArgument, - FunctionResult, GlobalVariable, Handle, ImageQuery, LocalVariable, Module, Override, - SampleLevel, Span, Statement, StructMember, SwitchCase, Type, TypeInner, UniqueArena, + Arena, Block, Constant, EntryPoint, Expression, Function, FunctionArgument, FunctionResult, + GlobalVariable, Handle, ImageQuery, LocalVariable, Module, SampleLevel, Span, Statement, + StructMember, SwitchCase, Type, TypeInner, UniqueArena, }; +use std::cell::RefCell; use std::collections::HashMap; #[derive(Debug, Default)] @@ -11,17 +12,17 @@ pub struct DerivedModule<'a> { shader: Option<&'a Module>, span_offset: usize, - type_map: HashMap, Handle>, - const_map: HashMap, Handle>, - const_expression_map: HashMap, Handle>, - global_map: HashMap, Handle>, - function_map: HashMap>, - - types: UniqueArena, - constants: Arena, - const_expressions: Arena, - globals: Arena, - functions: Arena, + type_map: RefCell, Handle>>, + const_map: RefCell, Handle>>, + const_expression_map: RefCell, Handle>>, + global_map: RefCell, Handle>>, + function_map: RefCell>>, + + types: RefCell>, + constants: RefCell>, + const_expressions: RefCell>, + globals: RefCell>, + functions: RefCell>, } impl<'a> DerivedModule<'a> { @@ -35,9 +36,10 @@ impl<'a> DerivedModule<'a> { // detach source context pub fn clear_shader_source(&mut self) { self.shader = None; - self.type_map.clear(); - self.const_map.clear(); - self.global_map.clear(); + self.type_map.borrow_mut().clear(); + self.const_map.borrow_mut().clear(); + self.const_expression_map.borrow_mut().clear(); + self.global_map.borrow_mut().clear(); } pub fn map_span(&self, span: Span) -> Span { @@ -52,212 +54,174 @@ impl<'a> DerivedModule<'a> { } // remap a type from source context into our derived context - pub fn import_type(&mut self, h_type: &Handle) -> Handle { + pub fn import_type(&self, h_type: &Handle) -> Handle { self.rename_type(h_type, None) } // remap a type from source context into our derived context, and rename it - pub fn rename_type(&mut self, h_type: &Handle, name: Option) -> Handle { - self.type_map.get(h_type).copied().unwrap_or_else(|| { - let ty = self - .shader - .as_ref() - .unwrap() - .types - .get_handle(*h_type) - .unwrap(); - - let name = match name { - Some(name) => Some(name), - None => ty.name.clone(), - }; + pub fn rename_type(&self, h_type: &Handle, name: Option) -> Handle { + self.type_map + .borrow() + .get(h_type) + .copied() + .unwrap_or_else(|| { + let ty = self + .shader + .as_ref() + .unwrap() + .types + .get_handle(*h_type) + .unwrap(); - let new_type = Type { - name, - inner: match &ty.inner { - TypeInner::Scalar { .. } - | TypeInner::Vector { .. } - | TypeInner::Matrix { .. } - | TypeInner::ValuePointer { .. } - | TypeInner::Image { .. } - | TypeInner::Sampler { .. } - | TypeInner::Atomic { .. } - | TypeInner::AccelerationStructure - | TypeInner::RayQuery => ty.inner.clone(), - - TypeInner::Pointer { base, space } => TypeInner::Pointer { - base: self.import_type(base), - space: *space, - }, - TypeInner::Struct { members, span } => { - let members = members - .iter() - .map(|m| StructMember { - name: m.name.clone(), - ty: self.import_type(&m.ty), - binding: m.binding.clone(), - offset: m.offset, - }) - .collect(); - TypeInner::Struct { - members, - span: *span, - } - } - TypeInner::Array { base, size, stride } => TypeInner::Array { - base: self.import_type(base), - size: *size, - stride: *stride, - }, - TypeInner::BindingArray { base, size } => { - let size = match size { - c @ ArraySize::Constant(_) => *c, - ArraySize::Dynamic => ArraySize::Dynamic, - }; - TypeInner::BindingArray { + let name = match name { + Some(name) => Some(name), + None => ty.name.clone(), + }; + + let new_type = Type { + name, + inner: match &ty.inner { + TypeInner::Scalar { .. } + | TypeInner::Vector { .. } + | TypeInner::Matrix { .. } + | TypeInner::ValuePointer { .. } + | TypeInner::Image { .. } + | TypeInner::Sampler { .. } + | TypeInner::Atomic { .. } + | TypeInner::AccelerationStructure + | TypeInner::RayQuery => ty.inner.clone(), + + TypeInner::Pointer { base, space } => TypeInner::Pointer { base: self.import_type(base), - size, + space: *space, + }, + TypeInner::Struct { members, span } => { + let members = members + .iter() + .map(|m| StructMember { + name: m.name.clone(), + ty: self.import_type(&m.ty), + binding: m.binding.clone(), + offset: m.offset, + }) + .collect(); + TypeInner::Struct { + members, + span: *span, + } } - } - }, - }; - let span = self.shader.as_ref().unwrap().types.get_span(*h_type); - let new_h = self.types.insert(new_type, self.map_span(span)); - self.type_map.insert(*h_type, new_h); - new_h - }) + TypeInner::Array { base, size, stride } => TypeInner::Array { + base: self.import_type(base), + size: *size, + stride: *stride, + }, + TypeInner::BindingArray { base, size } => TypeInner::BindingArray { + base: self.import_type(base), + size: *size, + }, + }, + }; + let span = self.shader.as_ref().unwrap().types.get_span(*h_type); + let new_h = self + .types + .borrow_mut() + .insert(new_type, self.map_span(span)); + self.type_map.borrow_mut().insert(*h_type, new_h); + new_h + }) } // remap a const from source context into our derived context - pub fn import_const(&mut self, h_const: &Handle) -> Handle { - self.const_map.get(h_const).copied().unwrap_or_else(|| { - let c = self - .shader - .as_ref() - .unwrap() - .constants - .try_get(*h_const) - .unwrap(); - - let new_const = Constant { - name: c.name.clone(), - r#override: c.r#override.clone(), - ty: self.import_type(&c.ty), - // TODO: infinite recursion? - init: if c.r#override == Override::None { - self.import_const_expression(&c.init) - } else { - // r#override doesn't do anything now - unreachable!() - }, - }; + pub fn import_const(&self, h_const: &Handle) -> Handle { + self.const_map + .borrow() + .get(h_const) + .copied() + .unwrap_or_else(|| { + let c = self + .shader + .as_ref() + .unwrap() + .constants + .try_get(*h_const) + .unwrap(); - let span = self.shader.as_ref().unwrap().constants.get_span(*h_const); - let new_h = self - .constants - .fetch_or_append(new_const, self.map_span(span)); - self.const_map.insert(*h_const, new_h); - new_h - }) + let new_const = Constant { + name: c.name.clone(), + r#override: c.r#override.clone(), + ty: self.import_type(&c.ty), + init: self.import_expression( + c.init, + self.shader.map_or(&Arena::new(), |s| &s.const_expressions), + &self.const_expression_map, + &self.const_expressions, + false, + ), + }; + + let span = self.shader.as_ref().unwrap().constants.get_span(*h_const); + let new_h = self + .constants + .borrow_mut() + .fetch_or_append(new_const, self.map_span(span)); + self.const_map.borrow_mut().insert(*h_const, new_h); + new_h + }) } // remap a global from source context into our derived context - pub fn import_global(&mut self, h_global: &Handle) -> Handle { - self.global_map.get(h_global).copied().unwrap_or_else(|| { - let gv = self - .shader - .as_ref() - .unwrap() - .global_variables - .try_get(*h_global) - .unwrap(); - - let new_global = GlobalVariable { - name: gv.name.clone(), - space: gv.space, - binding: gv.binding.clone(), - ty: self.import_type(&gv.ty), - init: gv.init.map(|c| self.import_const_expression(&c)), - }; - - let span = self - .shader - .as_ref() - .unwrap() - .global_variables - .get_span(*h_global); - let new_h = self - .globals - .fetch_or_append(new_global, self.map_span(span)); - self.global_map.insert(*h_global, new_h); - new_h - }) - } - // remap a const expression from source context into our derived context - pub fn import_const_expression( - &mut self, - const_expression_handle: &Handle, - ) -> Handle { - self.const_expression_map - .get(const_expression_handle) + pub fn import_global(&self, h_global: &Handle) -> Handle { + self.global_map + .borrow() + .get(h_global) .copied() .unwrap_or_else(|| { - let old_c = self + let gv = self .shader .as_ref() .unwrap() - .const_expressions - .try_get(*const_expression_handle) + .global_variables + .try_get(*h_global) .unwrap(); - let new_const = match old_c { - Expression::Constant(h_c) => { - let c = self - .shader - .as_ref() - .unwrap() - .constants - .try_get(*h_c) - .unwrap(); - - Constant { - name: c.name.clone(), - r#override: c.r#override.clone(), - ty: self.import_type(&c.ty), - init: self.import_const_expression(&c.init), - } - } - // TODO - // What should I do? - _ => todo!(), + let new_global = GlobalVariable { + name: gv.name.clone(), + space: gv.space, + binding: gv.binding.clone(), + ty: self.import_type(&gv.ty), + init: gv.init.map(|c| { + self.import_expression( + c, + self.shader.map_or(&Arena::new(), |s| &s.const_expressions), + &self.const_expression_map, + &self.const_expressions, + false, + ) + }), }; let span = self .shader .as_ref() .unwrap() - .const_expressions - .get_span(*const_expression_handle); - let new_constant_handle = self - .constants - .fetch_or_append(new_const, self.map_span(span)); - let new_const_expression = naga::Expression::Constant(new_constant_handle); - let new_const_expression_handle = self - .const_expressions - .append(new_const_expression, self.map_span(span)); - self.const_expression_map - .insert(*const_expression_handle, new_const_expression_handle); - new_const_expression_handle + .global_variables + .get_span(*h_global); + let new_h = self + .globals + .borrow_mut() + .fetch_or_append(new_global, self.map_span(span)); + self.global_map.borrow_mut().insert(*h_global, new_h); + new_h }) } // remap a block fn import_block( - &mut self, + &self, block: &Block, old_expressions: &Arena, - already_imported: &mut HashMap, Handle>, - new_expressions: &mut Arena, + already_imported: &RefCell, Handle>>, + new_expressions: &RefCell>, ) -> Block { macro_rules! map_expr { ($e:expr) => { @@ -342,13 +306,13 @@ impl<'a> DerivedModule<'a> { true, ); } - let old_length = new_expressions.len(); + let old_length = new_expressions.borrow().len(); // iterate again to add expressions that should be part of the emit statement for expr in exprs.clone() { map_expr!(&expr); } - Statement::Emit(new_expressions.range_from(old_length)) + Statement::Emit(new_expressions.borrow().range_from(old_length)) } Statement::Store { pointer, value } => Statement::Store { pointer: map_expr!(pointer), @@ -423,14 +387,14 @@ impl<'a> DerivedModule<'a> { } fn import_expression( - &mut self, + &self, h_expr: Handle, old_expressions: &Arena, - already_imported: &mut HashMap, Handle>, - new_expressions: &mut Arena, + already_imported: &RefCell, Handle>>, + new_expressions: &RefCell>, non_emitting_only: bool, // only brings items that should NOT be emitted into scope ) -> Handle { - if let Some(h_new) = already_imported.get(&h_expr) { + if let Some(h_new) = already_imported.borrow().get(&h_expr) { return *h_new; } @@ -493,7 +457,15 @@ impl<'a> DerivedModule<'a> { gather: *gather, coordinate: map_expr!(coordinate), array_index: map_expr_opt!(array_index), - offset: offset.map(|c| self.import_const_expression(&c)), + offset: offset.map(|c| { + self.import_expression( + c, + self.shader.map_or(&Arena::new(), |s| &s.const_expressions), + &self.const_expression_map, + &self.const_expressions, + false, + ) + }), level: match level { SampleLevel::Auto | SampleLevel::Zero => *level, SampleLevel::Exact(expr) => SampleLevel::Exact(map_expr!(expr)), @@ -620,9 +592,11 @@ impl<'a> DerivedModule<'a> { if !non_emitting_only || is_external { let span = old_expressions.get_span(h_expr); - let h_new = new_expressions.append(expr, self.map_span(span)); + let h_new = new_expressions + .borrow_mut() + .append(expr, self.map_span(span)); - already_imported.insert(h_expr, h_new); + already_imported.borrow_mut().insert(h_expr, h_new); h_new } else { h_expr @@ -630,7 +604,7 @@ impl<'a> DerivedModule<'a> { } // remap function global references (global vars, consts, types) into our derived context - pub fn localize_function(&mut self, func: &Function) -> Function { + pub fn localize_function(&self, func: &Function) -> Function { let arguments = func .arguments .iter() @@ -651,35 +625,43 @@ impl<'a> DerivedModule<'a> { let new_local = LocalVariable { name: l.name.clone(), ty: self.import_type(&l.ty), - init: l.init.map(|c| self.import_const_expression(&c)), + init: l.init.map(|c| { + self.import_expression( + c, + self.shader.map_or(&Arena::new(), |s| &s.const_expressions), + &self.const_expression_map, + &self.const_expressions, + false, + ) + }), }; let span = func.local_variables.get_span(h_l); let new_h = local_variables.append(new_local, self.map_span(span)); assert_eq!(h_l, new_h); } - let mut expressions = Arena::new(); - let mut expr_map = HashMap::new(); + let expressions = RefCell::new(Arena::new()); + let expr_map = RefCell::new(HashMap::new()); - let body = self.import_block( - &func.body, - &func.expressions, - &mut expr_map, - &mut expressions, - ); + let body = self.import_block(&func.body, &func.expressions, &expr_map, &expressions); let named_expressions = func .named_expressions .iter() - .flat_map(|(h_expr, name)| expr_map.get(h_expr).map(|new_h| (*new_h, name.clone()))) + .flat_map(|(h_expr, name)| { + expr_map + .borrow_mut() + .get(h_expr) + .map(|new_h| (*new_h, name.clone())) + }) .collect::>>(); Function { name: func.name.clone(), + expressions: expressions.into_inner(), arguments, result, local_variables, - expressions, named_expressions, body, } @@ -688,39 +670,43 @@ impl<'a> DerivedModule<'a> { // import a function defined in the source shader context. // func name may be already defined, the returned handle will refer to the new function. // the previously defined function will still be valid. - pub fn import_function(&mut self, func: &Function, span: Span) -> Handle { + pub fn import_function(&self, func: &Function, span: Span) -> Handle { let name = func.name.as_ref().unwrap().clone(); let mapped_func = self.localize_function(func); let new_span = self.map_span(span); - let new_h = self.functions.append(mapped_func, new_span); - self.function_map.insert(name, new_h); + let new_h = self.functions.borrow_mut().append(mapped_func, new_span); + self.function_map.borrow_mut().insert(name, new_h); new_h } // get the derived handle corresponding to the given source function handle // requires func to be named - pub fn map_function_handle(&mut self, h_func: &Handle) -> Handle { + pub fn map_function_handle(&self, h_func: &Handle) -> Handle { let functions = &self.shader.as_ref().unwrap().functions; let func = functions.try_get(*h_func).unwrap(); let name = func.name.as_ref().unwrap(); - self.function_map.get(name).copied().unwrap_or_else(|| { - let span = functions.get_span(*h_func); - self.import_function(func, span) - }) + self.function_map + .borrow() + .get(name) + .copied() + .unwrap_or_else(|| { + let span = functions.get_span(*h_func); + self.import_function(func, span) + }) } /// swap an already imported function for a new one. /// note span cannot be updated - pub fn import_function_if_new(&mut self, func: &Function, span: Span) -> Handle { + pub fn import_function_if_new(&self, func: &Function, span: Span) -> Handle { let name = func.name.as_ref().unwrap().clone(); - if let Some(h) = self.function_map.get(&name) { + if let Some(h) = self.function_map.borrow().get(&name) { return *h; } self.import_function(func, span) } - pub fn into_module_with_entrypoints(mut self) -> naga::Module { + pub fn into_module_with_entrypoints(self) -> naga::Module { let entry_points = self .shader .unwrap() @@ -745,11 +731,11 @@ impl<'a> DerivedModule<'a> { impl<'a> From> for naga::Module { fn from(derived: DerivedModule) -> Self { naga::Module { - types: derived.types, - constants: derived.constants, - global_variables: derived.globals, - const_expressions: derived.const_expressions, - functions: derived.functions, + types: derived.types.into_inner(), + constants: derived.constants.into_inner(), + global_variables: derived.globals.into_inner(), + const_expressions: derived.const_expressions.into_inner(), + functions: derived.functions.into_inner(), special_types: Default::default(), entry_points: Default::default(), }