Refactor implicit BGLs to support early tracing

This commit is contained in:
Dzmitry Malyshau 2021-03-03 16:48:23 -05:00
parent f7e1304c38
commit 7c1db12cdc
9 changed files with 310 additions and 295 deletions

1
Cargo.lock generated
View File

@ -956,7 +956,6 @@ dependencies = [
"log",
"num-traits",
"petgraph",
"serde",
"spirv_headers",
"thiserror",
]

View File

@ -254,10 +254,21 @@ impl GlobalPlay for wgc::hub::Global<IdentityPassThroughFactory> {
A::DestroyShaderModule(id) => {
self.shader_module_drop::<B>(id);
}
A::CreateComputePipeline(id, desc) => {
A::CreateComputePipeline {
id,
desc,
implicit_context,
} => {
self.device_maintain_ids::<B>(device).unwrap();
let implicit_ids =
implicit_context
.as_ref()
.map(|ic| wgc::device::ImplicitPipelineIds {
root_id: ic.root_id,
group_ids: &ic.group_ids,
});
let (_, _, error) =
self.device_create_compute_pipeline::<B>(device, &desc, id, None);
self.device_create_compute_pipeline::<B>(device, &desc, id, implicit_ids);
if let Some(e) = error {
panic!("{:?}", e);
}
@ -265,10 +276,21 @@ impl GlobalPlay for wgc::hub::Global<IdentityPassThroughFactory> {
A::DestroyComputePipeline(id) => {
self.compute_pipeline_drop::<B>(id);
}
A::CreateRenderPipeline(id, desc) => {
A::CreateRenderPipeline {
id,
desc,
implicit_context,
} => {
self.device_maintain_ids::<B>(device).unwrap();
let implicit_ids =
implicit_context
.as_ref()
.map(|ic| wgc::device::ImplicitPipelineIds {
root_id: ic.root_id,
group_ids: &ic.group_ids,
});
let (_, _, error) =
self.device_create_render_pipeline::<B>(device, &desc, id, None);
self.device_create_render_pipeline::<B>(device, &desc, id, implicit_ids);
if let Some(e) = error {
panic!("{:?}", e);
}

View File

@ -15,14 +15,17 @@
),
data: "empty.wgsl",
),
CreateComputePipeline(Id(0, 1, Empty), (
label: None,
layout: Some(Id(0, 1, Empty)),
stage: (
module: Id(0, 1, Empty),
entry_point: "main",
CreateComputePipeline(
id: Id(0, 1, Empty),
desc: (
label: None,
layout: Some(Id(0, 1, Empty)),
stage: (
module: Id(0, 1, Empty),
entry_point: "main",
),
),
)),
),
CreateBuffer(Id(0, 1, Empty), (
label: None,
size: 16,

View File

@ -1,167 +1,170 @@
(
features: (bits: 0x0),
expectations: [
// Ensuring that mapping zero-inits buffers.
(
name: "mapped_at_creation: false, with MAP_WRITE",
buffer: (index: 0, epoch: 1),
offset: 0,
data: Raw([0x00, 0x00, 0x00, 0x00]),
),
(
name: "mapped_at_creation: false, without MAP_WRITE",
buffer: (index: 1, epoch: 1),
offset: 0,
data: Raw([0x00, 0x00, 0x00, 0x00]),
),
(
name: "partially written buffer",
buffer: (index: 2, epoch: 1),
offset: 0,
data: Raw([0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0xBF,
0x00, 0x00, 0x80, 0xBF,
0x00, 0x00, 0x80, 0x3F,
0x00, 0x00, 0x80, 0x3F,
0x00, 0x00, 0x00, 0x00]),
),
// Ensuring that binding zero-inits buffers
// (by observing correct side effects of compute shader reading & writing values)
(
name: "buffer has correct values",
buffer: (index: 3, epoch: 1),
offset: 0,
data: Raw([0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00]),
)
],
actions: [
CreateBuffer(
Id(0, 1, Empty),
(
label: Some("mapped_at_creation: false, with MAP_WRITE"),
size: 16,
usage: (
bits: 131, // STORAGE + MAP_READ + MAP_WRITE
),
mapped_at_creation: false,
),
),
CreateBuffer(
Id(1, 1, Empty),
(
label: Some("mapped_at_creation: false, without MAP_WRITE"),
size: 16,
usage: (
bits: 129, // STORAGE + MAP_READ
),
mapped_at_creation: false,
),
),
CreateBuffer(
Id(2, 1, Empty),
(
label: Some("partially written"),
size: 24,
usage: (
bits: 9, // MAP_READ + COPY_DST
),
mapped_at_creation: false,
),
),
WriteBuffer(
id: Id(2, 1, Empty),
data: "data1.bin",
range: (
start: 4,
end: 20,
),
queued: true,
),
CreateShaderModule(
id: Id(0, 1, Empty),
desc: (
label: None,
flags: (bits: 3),
),
data: "buffer-zero-init-for-binding.wgsl",
),
CreateBuffer(Id(3, 1, Empty), (
label: Some("used in binding"),
size: 16,
usage: (
bits: 129, // STORAGE + MAP_READ
),
mapped_at_creation: false,
)),
CreateBindGroupLayout(Id(0, 1, Empty), (
label: None,
entries: [
(
binding: 0,
visibility: (
bits: 4,
),
ty: Buffer(
ty: Storage(
read_only: false,
),
has_dynamic_offset: false,
min_binding_size: Some(16),
),
count: None,
),
],
)),
CreateBindGroup(Id(0, 1, Empty), (
label: None,
layout: Id(0, 1, Empty),
entries: [
(
binding: 0,
resource: Buffer((
buffer_id: Id(3, 1, Empty),
offset: 0,
size: Some(16),
)),
),
],
)),
CreatePipelineLayout(Id(0, 1, Empty), (
label: None,
bind_group_layouts: [
Id(0, 1, Empty),
],
push_constant_ranges: [],
)),
CreateComputePipeline(Id(0, 1, Empty), (
label: None,
layout: Some(Id(0, 1, Empty)),
stage: (
module: Id(0, 1, Empty),
entry_point: "main",
),
)),
Submit(1, [
RunComputePass(
base: (
label: None,
commands: [
SetPipeline(Id(0, 1, Empty)),
SetBindGroup(
index: 0,
num_dynamic_offsets: 0,
bind_group_id: Id(0, 1, Empty),
),
Dispatch((4, 1, 1)),
],
dynamic_offsets: [],
string_data: [],
push_constant_data: [],
),
)
]),
]
)
(
features: (bits: 0x0),
expectations: [
// Ensuring that mapping zero-inits buffers.
(
name: "mapped_at_creation: false, with MAP_WRITE",
buffer: (index: 0, epoch: 1),
offset: 0,
data: Raw([0x00, 0x00, 0x00, 0x00]),
),
(
name: "mapped_at_creation: false, without MAP_WRITE",
buffer: (index: 1, epoch: 1),
offset: 0,
data: Raw([0x00, 0x00, 0x00, 0x00]),
),
(
name: "partially written buffer",
buffer: (index: 2, epoch: 1),
offset: 0,
data: Raw([0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0xBF,
0x00, 0x00, 0x80, 0xBF,
0x00, 0x00, 0x80, 0x3F,
0x00, 0x00, 0x80, 0x3F,
0x00, 0x00, 0x00, 0x00]),
),
// Ensuring that binding zero-inits buffers
// (by observing correct side effects of compute shader reading & writing values)
(
name: "buffer has correct values",
buffer: (index: 3, epoch: 1),
offset: 0,
data: Raw([0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00]),
)
],
actions: [
CreateBuffer(
Id(0, 1, Empty),
(
label: Some("mapped_at_creation: false, with MAP_WRITE"),
size: 16,
usage: (
bits: 131, // STORAGE + MAP_READ + MAP_WRITE
),
mapped_at_creation: false,
),
),
CreateBuffer(
Id(1, 1, Empty),
(
label: Some("mapped_at_creation: false, without MAP_WRITE"),
size: 16,
usage: (
bits: 129, // STORAGE + MAP_READ
),
mapped_at_creation: false,
),
),
CreateBuffer(
Id(2, 1, Empty),
(
label: Some("partially written"),
size: 24,
usage: (
bits: 9, // MAP_READ + COPY_DST
),
mapped_at_creation: false,
),
),
WriteBuffer(
id: Id(2, 1, Empty),
data: "data1.bin",
range: (
start: 4,
end: 20,
),
queued: true,
),
CreateShaderModule(
id: Id(0, 1, Empty),
desc: (
label: None,
flags: (bits: 3),
),
data: "buffer-zero-init-for-binding.wgsl",
),
CreateBuffer(Id(3, 1, Empty), (
label: Some("used in binding"),
size: 16,
usage: (
bits: 129, // STORAGE + MAP_READ
),
mapped_at_creation: false,
)),
CreateBindGroupLayout(Id(0, 1, Empty), (
label: None,
entries: [
(
binding: 0,
visibility: (
bits: 4,
),
ty: Buffer(
ty: Storage(
read_only: false,
),
has_dynamic_offset: false,
min_binding_size: Some(16),
),
count: None,
),
],
)),
CreateBindGroup(Id(0, 1, Empty), (
label: None,
layout: Id(0, 1, Empty),
entries: [
(
binding: 0,
resource: Buffer((
buffer_id: Id(3, 1, Empty),
offset: 0,
size: Some(16),
)),
),
],
)),
CreatePipelineLayout(Id(0, 1, Empty), (
label: None,
bind_group_layouts: [
Id(0, 1, Empty),
],
push_constant_ranges: [],
)),
CreateComputePipeline(
id: Id(0, 1, Empty),
desc: (
label: None,
layout: Some(Id(0, 1, Empty)),
stage: (
module: Id(0, 1, Empty),
entry_point: "main",
),
),
),
Submit(1, [
RunComputePass(
base: (
label: None,
commands: [
SetPipeline(Id(0, 1, Empty)),
SetBindGroup(
index: 0,
num_dynamic_offsets: 0,
bind_group_id: Id(0, 1, Empty),
),
Dispatch((4, 1, 1)),
],
dynamic_offsets: [],
string_data: [],
push_constant_data: [],
),
)
]),
]
)

View File

@ -53,28 +53,31 @@
bind_group_layouts: [],
push_constant_ranges: [],
)),
CreateRenderPipeline(Id(0, 1, Empty), (
label: None,
layout: Some(Id(0, 1, Empty)),
vertex: (
stage: (
module: Id(0, 1, Empty),
entry_point: "vs_main",
),
buffers: [],
),
fragment: Some((
stage: (
module: Id(0, 1, Empty),
entry_point: "fs_main",
),
targets: [
(
format: Rgba8Unorm,
CreateRenderPipeline(
id: Id(0, 1, Empty),
desc: (
label: None,
layout: Some(Id(0, 1, Empty)),
vertex: (
stage: (
module: Id(0, 1, Empty),
entry_point: "vs_main",
),
],
)),
)),
buffers: [],
),
fragment: Some((
stage: (
module: Id(0, 1, Empty),
entry_point: "fs_main",
),
targets: [
(
format: Rgba8Unorm,
),
],
)),
),
),
Submit(1, [
RunRenderPass(
base: (

View File

@ -16,9 +16,9 @@ default = []
# Enable SPIRV-Cross
cross = ["gfx-backend-metal/cross", "gfx-backend-gl/cross"]
# Enable API tracing
trace = ["ron", "serde", "wgt/trace", "naga/serialize"]
trace = ["ron", "serde", "wgt/trace", "arrayvec/serde"]
# Enable API replaying
replay = ["serde", "wgt/replay", "naga/deserialize"]
replay = ["serde", "wgt/replay", "arrayvec/serde"]
# Enable serializable compute/render passes, and bundle encoders.
serial-pass = ["serde", "wgt/serde", "arrayvec/serde"]

View File

@ -49,8 +49,6 @@ pub mod queue;
pub mod trace;
use smallvec::SmallVec;
#[cfg(feature = "trace")]
use trace::{Action, Trace};
pub const MAX_COLOR_TARGETS: usize = 4;
pub const MAX_MIP_LEVELS: u32 = 16;
@ -290,7 +288,7 @@ pub struct Device<B: hal::Backend> {
// to borrow Device immutably, such as `write_buffer`, `write_texture`, and `buffer_unmap`.
pending_writes: queue::PendingWrites<B>,
#[cfg(feature = "trace")]
pub(crate) trace: Option<Mutex<Trace>>,
pub(crate) trace: Option<Mutex<trace::Trace>>,
}
#[derive(Clone, Debug, Error)]
@ -359,9 +357,9 @@ impl<B: GfxBackend> Device<B> {
life_tracker: Mutex::new(life::LifetimeTracker::new()),
temp_suspected: life::SuspectedResources::default(),
#[cfg(feature = "trace")]
trace: trace_path.and_then(|path| match Trace::new(path) {
trace: trace_path.and_then(|path| match trace::Trace::new(path) {
Ok(mut trace) => {
trace.add(Action::Init {
trace.add(trace::Action::Init {
desc: desc.clone(),
backend: B::VARIANT,
});
@ -1787,14 +1785,13 @@ impl<B: GfxBackend> Device<B> {
//TODO: refactor this. It's the only method of `Device` that registers new objects
// (the pipeline layout).
fn derive_pipeline_layout<G: GlobalIdentityHandlerFactory>(
fn derive_pipeline_layout(
&self,
self_id: id::DeviceId,
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
implicit_context: Option<ImplicitPipelineContext>,
mut derived_group_layouts: ArrayVec<[binding_model::BindEntryMap; MAX_BIND_GROUPS]>,
bgl_guard: &mut Storage<binding_model::BindGroupLayout<B>, id::BindGroupLayoutId>,
pipeline_layout_guard: &mut Storage<binding_model::PipelineLayout<B>, id::PipelineLayoutId>,
hub: &Hub<B, G>,
) -> Result<
(id::PipelineLayoutId, pipeline::ImplicitBindGroupCount),
pipeline::ImplicitLayoutError,
@ -1808,10 +1805,9 @@ impl<B: GfxBackend> Device<B> {
{
derived_group_layouts.pop();
}
let ids = implicit_pipeline_ids
.as_ref()
.ok_or(pipeline::ImplicitLayoutError::MissingIds(0))?;
if ids.group_ids.len() < derived_group_layouts.len() {
let mut ids = implicit_context.ok_or(pipeline::ImplicitLayoutError::MissingIds(0))?;
let group_count = derived_group_layouts.len();
if ids.group_ids.len() < group_count {
tracing::error!(
"Not enough bind group IDs ({}) specified for the implicit layout ({})",
ids.group_ids.len(),
@ -1822,66 +1818,33 @@ impl<B: GfxBackend> Device<B> {
));
}
let mut derived_group_layout_ids =
ArrayVec::<[id::BindGroupLayoutId; MAX_BIND_GROUPS]>::new();
for (bgl_id, map) in ids.group_ids.iter().zip(derived_group_layouts) {
let processed_id = match Device::deduplicate_bind_group_layout(self_id, &map, bgl_guard)
{
Some(dedup_id) => dedup_id,
for (bgl_id, map) in ids.group_ids.iter_mut().zip(derived_group_layouts) {
match Device::deduplicate_bind_group_layout(self_id, &map, bgl_guard) {
Some(dedup_id) => {
*bgl_id = dedup_id;
}
None => {
#[cfg(feature = "trace")]
let bgl_desc = binding_model::BindGroupLayoutDescriptor {
label: None,
entries: if self.trace.is_some() {
Cow::Owned(map.values().cloned().collect())
} else {
Cow::Borrowed(&[])
},
};
let bgl = self.create_bind_group_layout(self_id, None, map)?;
let out_id = hub.bind_group_layouts.register_identity_locked(
bgl_id.clone(),
bgl,
bgl_guard,
);
#[cfg(feature = "trace")]
if let Some(ref trace) = self.trace {
trace
.lock()
.add(trace::Action::CreateBindGroupLayout(out_id.0, bgl_desc));
}
out_id.0
bgl_guard.insert(*bgl_id, bgl);
}
};
derived_group_layout_ids.push(processed_id);
}
let layout_desc = binding_model::PipelineLayoutDescriptor {
label: None,
bind_group_layouts: Cow::Borrowed(&derived_group_layout_ids),
bind_group_layouts: Cow::Borrowed(&ids.group_ids[..group_count]),
push_constant_ranges: Cow::Borrowed(&[]), //TODO?
};
let layout = self.create_pipeline_layout(self_id, &layout_desc, bgl_guard)?;
let layout_id = hub.pipeline_layouts.register_identity_locked(
ids.root_id.clone(),
layout,
pipeline_layout_guard,
);
#[cfg(feature = "trace")]
if let Some(ref trace) = self.trace {
trace.lock().add(trace::Action::CreatePipelineLayout(
layout_id.0,
layout_desc,
));
}
Ok((layout_id.0, derived_bind_group_count))
pipeline_layout_guard.insert(ids.root_id, layout);
Ok((ids.root_id, derived_bind_group_count))
}
fn create_compute_pipeline<G: GlobalIdentityHandlerFactory>(
&self,
self_id: id::DeviceId,
desc: &pipeline::ComputePipelineDescriptor,
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
implicit_context: Option<ImplicitPipelineContext>,
hub: &Hub<B, G>,
token: &mut Token<Self>,
) -> Result<
@ -1951,11 +1914,10 @@ impl<B: GfxBackend> Device<B> {
Some(id) => (id, 0),
None => self.derive_pipeline_layout(
self_id,
implicit_pipeline_ids,
implicit_context,
derived_group_layouts,
&mut *bgl_guard,
&mut *pipeline_layout_guard,
&hub,
)?,
};
let layout = pipeline_layout_guard
@ -1999,7 +1961,7 @@ impl<B: GfxBackend> Device<B> {
&self,
self_id: id::DeviceId,
desc: &pipeline::RenderPipelineDescriptor,
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
implicit_context: Option<ImplicitPipelineContext>,
hub: &Hub<B, G>,
token: &mut Token<Self>,
) -> Result<
@ -2367,11 +2329,10 @@ impl<B: GfxBackend> Device<B> {
Some(id) => (id, 0),
None => self.derive_pipeline_layout(
self_id,
implicit_pipeline_ids,
implicit_context,
derived_group_layouts,
&mut *bgl_guard,
&mut *pipeline_layout_guard,
&hub,
)?,
};
let layout = pipeline_layout_guard
@ -2582,11 +2543,32 @@ impl DeviceError {
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct ImplicitPipelineContext {
pub root_id: id::PipelineLayoutId,
pub group_ids: ArrayVec<[id::BindGroupLayoutId; MAX_BIND_GROUPS]>,
}
pub struct ImplicitPipelineIds<'a, G: GlobalIdentityHandlerFactory> {
pub root_id: Input<G, id::PipelineLayoutId>,
pub group_ids: &'a [Input<G, id::BindGroupLayoutId>],
}
impl<G: GlobalIdentityHandlerFactory> ImplicitPipelineIds<'_, G> {
fn prepare<B: hal::Backend>(self, hub: &Hub<B, G>) -> ImplicitPipelineContext {
ImplicitPipelineContext {
root_id: hub.pipeline_layouts.prepare(self.root_id).into_id(),
group_ids: self
.group_ids
.iter()
.map(|id_in| hub.bind_group_layouts.prepare(id_in.clone()).into_id())
.collect(),
}
}
}
impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn adapter_get_swap_chain_preferred_format<B: GfxBackend>(
&self,
@ -3621,11 +3603,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pipeline::ShaderModuleSource::Wgsl(ref code) => {
trace.make_binary("wgsl", code.as_bytes())
}
pipeline::ShaderModuleSource::Naga(ref module) => {
let config = ron::ser::PrettyConfig::new();
let mut ron = Vec::new();
ron::ser::to_writer_pretty(&mut ron, &module, config).unwrap();
trace.make_binary("ron", &ron)
pipeline::ShaderModuleSource::Naga(_) => {
// we don't want to enable Naga serialization just for this alone
trace.make_binary("ron", &[])
}
}
}
@ -4019,6 +3999,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let mut token = Token::root();
let fid = hub.render_pipelines.prepare(id_in);
let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(&hub));
let (device_guard, mut token) = hub.devices.read(&mut token);
let error = loop {
let device = match device_guard.get(device_id) {
@ -4027,13 +4009,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
};
#[cfg(feature = "trace")]
if let Some(ref trace) = device.trace {
trace
.lock()
.add(trace::Action::CreateRenderPipeline(fid.id(), desc.clone()));
trace.lock().add(trace::Action::CreateRenderPipeline {
id: fid.id(),
desc: desc.clone(),
implicit_context: implicit_context.clone(),
});
}
let (pipeline, derived_bind_group_count, _layout_id) = match device
.create_render_pipeline(device_id, desc, implicit_pipeline_ids, &hub, &mut token)
.create_render_pipeline(device_id, desc, implicit_context, &hub, &mut token)
{
Ok(pair) => pair,
Err(e) => break e,
@ -4142,6 +4126,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let mut token = Token::root();
let fid = hub.compute_pipelines.prepare(id_in);
let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(&hub));
let (device_guard, mut token) = hub.devices.read(&mut token);
let error = loop {
let device = match device_guard.get(device_id) {
@ -4150,13 +4136,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
};
#[cfg(feature = "trace")]
if let Some(ref trace) = device.trace {
trace
.lock()
.add(trace::Action::CreateComputePipeline(fid.id(), desc.clone()));
trace.lock().add(trace::Action::CreateComputePipeline {
id: fid.id(),
desc: desc.clone(),
implicit_context: implicit_context.clone(),
});
}
let (pipeline, derived_bind_group_count, _layout_id) = match device
.create_compute_pipeline(device_id, desc, implicit_pipeline_ids, &hub, &mut token)
.create_compute_pipeline(device_id, desc, implicit_context, &hub, &mut token)
{
Ok(pair) => pair,
Err(e) => break e,
@ -4353,7 +4341,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
if let Some(ref trace) = device.trace {
trace
.lock()
.add(Action::CreateSwapChain(sc_id, desc.clone()));
.add(trace::Action::CreateSwapChain(sc_id, desc.clone()));
}
let swap_chain = swap_chain::SwapChain {

View File

@ -75,15 +75,19 @@ pub enum Action<'a> {
data: FileName,
},
DestroyShaderModule(id::ShaderModuleId),
CreateComputePipeline(
id::ComputePipelineId,
crate::pipeline::ComputePipelineDescriptor<'a>,
),
CreateComputePipeline {
id: id::ComputePipelineId,
desc: crate::pipeline::ComputePipelineDescriptor<'a>,
#[cfg_attr(feature = "replay", serde(default))]
implicit_context: Option<super::ImplicitPipelineContext>,
},
DestroyComputePipeline(id::ComputePipelineId),
CreateRenderPipeline(
id::RenderPipelineId,
crate::pipeline::RenderPipelineDescriptor<'a>,
),
CreateRenderPipeline {
id: id::RenderPipelineId,
desc: crate::pipeline::RenderPipelineDescriptor<'a>,
#[cfg_attr(feature = "replay", serde(default))]
implicit_context: Option<super::ImplicitPipelineContext>,
},
DestroyRenderPipeline(id::RenderPipelineId),
CreateRenderBundle {
id: id::RenderBundleId,

View File

@ -451,6 +451,10 @@ impl<I: TypedId + Copy, T> FutureId<'_, I, T> {
self.id
}
pub fn into_id(self) -> I {
self.id
}
pub fn assign<'a, A: Access<T>>(self, value: T, _: &'a mut Token<A>) -> Valid<I> {
self.data.write().insert(self.id, value);
Valid(self.id)
@ -497,17 +501,6 @@ impl<T: Resource, I: TypedId + Copy, F: IdentityHandlerFactory<I>> Registry<T, I
self.prepare(id_in).assign(value, token)
}
pub(crate) fn register_identity_locked(
&self,
id_in: <F::Filter as IdentityHandler<I>>::Input,
value: T,
guard: &mut Storage<T, I>,
) -> Valid<I> {
let id = self.identity.process(id_in, self.backend);
guard.insert(id, value);
Valid(id)
}
//TODO: consider remove this once everything uses `prepare`
pub(crate) fn register_error<A: Access<T>>(
&self,