(WIP) Refactor asset loading - #22
Conversation
This shouldn't be necessary; waking it up on demand is what the passed-in semaphore is for. |
|
|
||
| pub fn transforms_mut(&mut self) -> &mut [na::Matrix4<f32>] { | ||
| &mut self.transforms | ||
| unsafe { self.transforms.as_mut() } |
There was a problem hiding this comment.
nit: best practice (which we're absolutely not following consistently in existing code) is to always include a comment on unsafe blocks explaining why the operations within are sound, with the possible exclusion of blindingly obvious cases. In this example, it would explain why there's no aliasing hazard.
There was a problem hiding this comment.
Thanks for the heads up. I'll look into this during my final polishing pass.
EDIT: Or now, now that I realize that what I'm looking for is concurrent writes by the GPU
EDIT2: I'll look into this later. It's still a bit tricky for me to fully understand its safety requirements.
| free_nodes: FreeNodeStack<NI>, | ||
| } | ||
|
|
||
| struct NodeMap<NI: NodeIndex>(Vec<Node<NI>>); |
There was a problem hiding this comment.
What was wrong with the stack? A slab is technically slightly more book-keeping.
There was a problem hiding this comment.
Hmm, maybe. I thought it was the ideal use case of a Slab, since it behaves as a key/value store for node indexes. I found the setup of the FreeNodeStack to be not ideal, especially since max_allocs is used to populate it.
I'll think more about this.
There was a problem hiding this comment.
I didn't review this change closely enough to have an informed opinion about how it interacts with the other logic, since you recommended focusing elsewhere. If naturally providing a stable key simplifies code elsewhere compared to the stack, that would be a very good reason for the change.
There was a problem hiding this comment.
I agree with not looking into this too closely. To answer your question, though, the IDs were always stable. It just used to be implemented manually using two arrays. One of them was the one referenced with stable IDs, and the other acted as a stack and contained the full list of free IDs you could draw from. Its interface basically already matched the interface of a slab.
Because of that, when I was thinking of how to abstract that logic, the name of the data structure I wanted to use was "slab", and since we already depended on the slab crate, it seemed silly not to use that.
However, looking at the implementation of Slab, it seems like there might be a fair amount of memory overhead, as there's an enum with a usize as one of its options, which I think means that each slot takes at least 128 bits.
There was a problem hiding this comment.
One of them was the one referenced with stable IDs, and the other acted as a stack and contained the full list of free IDs you could draw from. Its interface basically already matched the interface of a slab.
Ah, that sounds like a fair reason to simplify with a real slab then! If upstream has a good reason not to do that, they should at least document it.
which I think means that each slot takes at least 128 bits.
This is unlikely to matter.
| } | ||
|
|
||
| impl skid_steer::Source for PngArray { | ||
| type Output = DedicatedImage; // TODO: We may want a dedicated struct here. |
There was a problem hiding this comment.
I left that comment there thinking I would be tripped up by having the asset loader return an image without any additional metadata, but I haven't reached that point yet.
I could imagine situations where the asset would want to retain additional data, such as the names of the materials it loaded. However, given Rust's type safety, I think that if that need arises, the refactor would be easy. Since we haven't needed a dedicated struct yet, I'll remove the comment.
| align: usize, | ||
| free_at: u64, | ||
| ) -> Allocation<'_> { | ||
| // TODO: Instead of blocking in this haphazard way, try growing the timeline ring instead if it's too small. |
There was a problem hiding this comment.
This may be necessary to avoid deadlocks in control flow paths that cross multiple allocations, which may occur in very difficult to reproduce ways with concurrent allocation traffic.
There was a problem hiding this comment.
Indeed, I do agree it's worth redesigning that part.
|
|
||
| impl PngArray { | ||
| async fn load_inner(self, context: &skid_steer::Context<'_>) -> anyhow::Result<DedicatedImage> { | ||
| println!("Started loading png array"); |
There was a problem hiding this comment.
I recommend getting comfortable with using tracing logs even (perhaps especially) for debugging, as it's easy to attach useful context to them via dynamic scope, and to include diagnostics that are normally inactive but don't need to be reinvented every time you're investigating an issue.
There was a problem hiding this comment.
That's a fair point. It would be nice to not have to delete all the logs before submitting a PR, especially when they've proved to be useful in the past. I am pretty comfortable with using tracing logs, but I guess not comfortable enough to reach to them as a default.
There was a problem hiding this comment.
It may help to adopt the test-log crate, and ensure your development environment sets RUST_LOG to a useful configuration by default.
87e2e61 to
223c79e
Compare
…ing and mesh generation
Very rough draft of new form of asset loading.
When testing this, I edited
lahar::ParallelQueueto specify.flags(vk::SemaphoreWaitFlags::ANY)in itsparkmethod, as that is surprisingly not the default.Recommendations for reviewing