Skip to content

Conversation

andyleiserson
Copy link
Contributor

@andyleiserson andyleiserson commented Oct 2, 2025

On top of #8288.

This resolves the duplicate storage of Id and Arc versions of commands when tracing that was introduced by encode-on-finish. It now stores the Arc version only, and uses the pointers from the Arcs as object IDs when tracing. It also overhauls the trace player to play back traces in this format.

This fixes tracing of compute and render passes when encoded using the standard APIs. Tracing of render bundles is still broken.

Testing
TBD. Existing player tests, manual tests, and it would be nice to have an automated test of recording a trace but I don't think we do right now.

Squash or Rebase? TBD, probably rebase.

Checklist

  • Run cargo fmt.
  • Run taplo format.
  • Run cargo clippy --tests. If applicable, add:
    • --target wasm32-unknown-unknown
  • Run cargo xtask test to run tests.
  • If this contains user-facing changes, add a CHANGELOG.md entry.

@andyleiserson
Copy link
Contributor Author

This does have all my latest local changes, but there's still a little work to do to fix the CI failures, and I want to revisit the way that polling and user_closures are handled.

// this check can't go in the body of `create_bind_group_layout` since the closure might not get called
if let Err(e) = device.check_is_valid() {
break 'error e.into();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can remove this check since create_bind_group_layout now contains it as well.

Ok(submit_index)
}

pub fn get_mapped_range(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_mapped_range on the global is not calling this method.

hashbrown.workspace = true
indexmap.workspace = true
log.workspace = true
macro_rules_attribute.workspace = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can gate this dependency behind the serde feature.

Comment on lines +161 to +164
// Unfortunately, because `Arc::as_ptr` returns a pointer to the
// contained data, and `Arc` stores reference counts before the data,
// we are adding an offset to the pointer here.
Self(Arc::as_ptr(arc) as usize, PhantomData)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of date comment?

Comment on lines -232 to -240
#[cfg_attr(not(any(feature = "serde", feature = "replay")), allow(dead_code))]
//#[cfg_attr(not(any(feature = "serde", feature = "replay")), allow(dead_code))]
color: u32,
len: usize,
},

PopDebugGroup,

InsertDebugMarker {
#[cfg_attr(not(any(feature = "serde", feature = "replay")), allow(dead_code))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like we kept those guards for the render pass, but not here.

Comment on lines +432 to +444
fn resolve_buffer_id(
&self,
id: wgc::id::PointerId<wgc::id::markers::Buffer>,
) -> Arc<wgc::resource::Buffer> {
self.buffers.get(&id).expect("invalid buffer").clone()
}

pub fn get_buffer(
&self,
id: wgc::id::PointerId<wgc::id::markers::Buffer>,
) -> Arc<wgc::resource::Buffer> {
self.resolve_buffer_id(id)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need both functions?

Comment on lines +157 to +161
let external_texture = self
.external_textures
.remove(&id)
.expect("invalid external texture");
external_texture.destroy();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the free functions should remove the resource from the map since the spec says it's ok to call destroy multiple times.

@teoxoy
Copy link
Member

teoxoy commented Oct 13, 2025

I wanted to mention that the main difference I noticed between this approach and the previous is that we now effectively only record commands after successful validation. I find that this somewhat limits the usefulness of recording and replaying traces since they won't record invalid commands.

I've mostly used the record/replay functionality to debug overly restrictive or wrong validation in Firefox which will no longer be possible with this PR.

We should probably talk about this at the maintainers meeting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants