mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[spv-out] Move cached expression table to BlockContext.
Since the table of cached expressions is only meaningful within a single function, it's really something that should only be accessed from `BlockContext`. However, to save heap allocations, it makes sense to retain it in the `Writer` between functions. But the `Writer` field should have a different name, to ensure people don't use it by accident.
This commit is contained in:
committed by
Dzmitry Malyshau
parent
a818b2e089
commit
562af28773
@@ -197,7 +197,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
// The chain rule: if this `Access...`'s `base` operand was
|
||||
// previously omitted, then omit this one, too.
|
||||
_ => self.writer.cached.ids[expr_handle.index()] == 0,
|
||||
_ => self.cached.ids[expr_handle.index()] == 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1150,7 +1150,7 @@ impl<'w> BlockContext<'w> {
|
||||
crate::Expression::ArrayLength(expr) => self.write_runtime_array_length(expr, block)?,
|
||||
};
|
||||
|
||||
self.writer.cached[expr_handle] = id;
|
||||
self.cached[expr_handle] = id;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1578,7 +1578,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let type_id = match result {
|
||||
Some(expr) => {
|
||||
self.writer.cached[expr] = id;
|
||||
self.cached[expr] = id;
|
||||
self.writer.lookup_function_call.insert(expr, id);
|
||||
let ty_handle = self.ir_module.functions[local_function]
|
||||
.result
|
||||
|
||||
@@ -268,6 +268,14 @@ enum Dimension {
|
||||
Matrix,
|
||||
}
|
||||
|
||||
/// A map from evaluated [`Expression`s] to their SPIR-V ids.
|
||||
///
|
||||
/// When we emit code to evaluate a given `Expression`, we record the
|
||||
/// SPIR-V id of its value here, under its `Handle<Expression>` index.
|
||||
///
|
||||
/// A `CachedExpressions` value can be indexed by a `Handle<Expression>` value.
|
||||
///
|
||||
/// [emit]: index.html#expression-evaluation-time-and-scope
|
||||
#[derive(Default)]
|
||||
struct CachedExpressions {
|
||||
ids: Vec<Word>,
|
||||
@@ -338,6 +346,9 @@ struct BlockContext<'w> {
|
||||
/// The [`back::spv::Function`] to which we are contributing SPIR-V instructions.
|
||||
function: &'w mut Function,
|
||||
|
||||
/// SPIR-V ids for expressions we've evaluated.
|
||||
cached: CachedExpressions,
|
||||
|
||||
/// The `Writer`'s temporary vector, for convenience.
|
||||
temp_list: Vec<Word>,
|
||||
}
|
||||
@@ -357,7 +368,7 @@ impl BlockContext<'_> {
|
||||
}
|
||||
|
||||
fn cached(&self, expression: Handle<crate::Expression>) -> Word {
|
||||
self.writer.cached[expression]
|
||||
self.cached[expression]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +397,11 @@ pub struct Writer {
|
||||
constant_ids: Vec<Word>,
|
||||
cached_constants: crate::FastHashMap<(crate::ScalarValue, crate::Bytes), Word>,
|
||||
global_variables: Vec<GlobalVariable>,
|
||||
cached: CachedExpressions,
|
||||
|
||||
// Cached expressions are only meaningful within a BlockContext, but we
|
||||
// retain the table here between functions to save heap allocations.
|
||||
saved_cached: CachedExpressions,
|
||||
|
||||
gl450_ext_inst_id: Word,
|
||||
// Just a temporary list of SPIR-V ids
|
||||
temp_list: Vec<Word>,
|
||||
|
||||
@@ -82,7 +82,7 @@ impl Writer {
|
||||
constant_ids: Vec::new(),
|
||||
cached_constants: crate::FastHashMap::default(),
|
||||
global_variables: Vec::new(),
|
||||
cached: CachedExpressions::default(),
|
||||
saved_cached: CachedExpressions::default(),
|
||||
gl450_ext_inst_id,
|
||||
temp_list: Vec::new(),
|
||||
})
|
||||
@@ -131,7 +131,7 @@ impl Writer {
|
||||
constant_ids: take(&mut self.constant_ids).recycle(),
|
||||
cached_constants: take(&mut self.cached_constants).recycle(),
|
||||
global_variables: take(&mut self.global_variables).recycle(),
|
||||
cached: take(&mut self.cached).recycle(),
|
||||
saved_cached: take(&mut self.saved_cached).recycle(),
|
||||
temp_list: take(&mut self.temp_list).recycle(),
|
||||
};
|
||||
|
||||
@@ -429,13 +429,16 @@ impl Writer {
|
||||
ir_function,
|
||||
fun_info: info,
|
||||
function: &mut function,
|
||||
// Re-use the cached expression table from prior functions.
|
||||
cached: std::mem::take(&mut self.saved_cached),
|
||||
|
||||
// Steal the Writer's temp list for a bit.
|
||||
temp_list: std::mem::take(&mut self.temp_list),
|
||||
writer: self,
|
||||
};
|
||||
|
||||
// fill up the pre-emitted expressions
|
||||
context.writer.cached.reset(ir_function.expressions.len());
|
||||
context.cached.reset(ir_function.expressions.len());
|
||||
for (handle, expr) in ir_function.expressions.iter() {
|
||||
if expr.needs_pre_emit() {
|
||||
context.cache_expression_value(handle, &mut prelude)?;
|
||||
@@ -449,8 +452,11 @@ impl Writer {
|
||||
context.write_block(main_id, &ir_function.body, None, LoopContext::default())?;
|
||||
|
||||
// Consume the `BlockContext`, ending its borrows and letting the
|
||||
// `Writer` steal back its temp_list.
|
||||
let BlockContext { temp_list, .. } = context;
|
||||
// `Writer` steal back its cached expression table and temp_list.
|
||||
let BlockContext {
|
||||
cached, temp_list, ..
|
||||
} = context;
|
||||
self.saved_cached = cached;
|
||||
self.temp_list = temp_list;
|
||||
|
||||
function.to_words(&mut self.logical_layout.function_definitions);
|
||||
|
||||
Reference in New Issue
Block a user