-
Notifications
You must be signed in to change notification settings - Fork 63
metal: Create a global residency set, holding all allocated heaps #273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
c90ef32 to
bf93064
Compare
bf93064 to
9f5dedf
Compare
src/metal/mod.rs
Outdated
| } | ||
| // Note that `block` will be destroyed on `drop` here | ||
| if mem_block.sub_allocator.is_empty() | ||
| && (!mem_block.sub_allocator.supports_general_allocations() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This complex conditional is significantly less readable then what was there before with the multiple if statements. Please revert.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to deduplicate the bodies since more and more code gets added to the destruction path now. But since the original expression is confusing, I've factored it out to a let binding now with explanatory comment (on each of the 3 backends) in hopes of making more clear what's going on.
In short, we'll only destroy empty memory blocks if they are either dedicated or not dedicated and not the last block. That way we always have one general (i.e. suballocatable) memory block available.
| pub allocation_sizes: AllocationSizes, | ||
| /// Whether to create a [`MTLResidencySet`] containing all live heaps, that can be retrieved via | ||
| /// [`Allocator::residency_set()`]. Only supported on MacOS 15.0+ / iOS 18.0+. | ||
| pub create_residency_set: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe for now its a bit early, but if we do more of these platform specific settings I don't think they belong in AllocatorCreateDesc, maybe we need some platform specific traits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AllocatorCreateDesc already is platform-specific (defined in metal/mod.rs), gpu-allocator has relatively few platform-agnostic types and definitions (just the error, debug settings, allocation reports, and the allocator algorithms themselves). Everything else is platform-specific because it integrates with platform-specific primitives (i.e. having to pass the Device of the given API).
7f79300 to
7463571
Compare
`gpu-allocator` creates heaps on which callers can allocate ranges and create "placed" resources like textures, buffers and acceleration structures. These individual resources, or the heaps as a whole, need to be made resident on the command buffer or even globally on an entire queue. In the previous API those heaps had to be made resident on individual command *encoders* with `useHeap(s):` (making an entire heap resident perfectly matches a bindless design, as opposed to making every individual resource -either placed on the heap or allocated separately- resident with `useResource(s):`). Worse, this API only applies `MTLResourceUsageRead` (exluding `RenderTarget` and `ShaderWrite` textures) which would disallow any resources on the heap to be written. Now with `MTLResidencySet` multiple heaps can be made resident with one call, defeating the performance overhead of individually "using" all heaps on *every* command *encoder*. But without tracking this inside `gpu-allocator`, users of our crate still have to manually rebuild this `MTLResidencySet` each time they change their allocations, without knowing when `gpu-allocator` created or destroyed a heap. By managing a single updated `MTLResidencySet` in `gpu-allocator`, callers can simply call `.commit()` on this object right before they submit command buffers referencing resources on these heaps, as long as they have the residency set attached to the queue in question or "used" on the command buffer that is being submitted. This removes all the performance overhead of repeatedly creating `MTLResidencySet`s, which otherwise defeats the purpose of it over plain `useHeap(s):` call(s).
7463571 to
2136bcf
Compare
gpu-allocatorcreates heaps on which callers can allocate ranges and create "placed" resources like textures, buffers and acceleration structures. These individual resources, or the heaps as a whole, need to be made resident on the command buffer or even globally on an entire queue.In the previous API those heaps had to be made resident on individual command encoders with
useHeap(s):(making an entire heap resident perfectly matches a bindless design, as opposed to making every individual resource -either placed on the heap or allocated separately-resident with
useResource(s):). Worse, this API only appliesMTLResourceUsageRead(exludingRenderTargetandShaderWritetextures) which would disallow any resources on the heap to be written.Now with
MTLResidencySetmultiple heaps can be made resident with one call, defeating the performance overhead of individually "using" all heaps on every command encoder. But without tracking this insidegpu-allocator, users of our crate still have to manually rebuild thisMTLResidencySeteach time they change their allocations, without knowing whengpu-allocatorcreated or destroyed a heap.By managing a single updated
MTLResidencySetingpu-allocator, callers can simply call.commit()on this object right before they submit command buffers referencing resources on these heaps, as long as they have the residency set attached to the queue in question or "used" on the command buffer that is being submitted. This removes all the performance overhead of repeatedly creatingMTLResidencySets, which otherwise defeats the purpose of it over plainuseHeap(s):call(s).