-
Notifications
You must be signed in to change notification settings - Fork 70
[Do not merge] Metal 4 #612
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
Open
christiangnrd
wants to merge
7
commits into
main
Choose a base branch
from
mtl4
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
8f380fb
Add basic Metal4 elements
christiangnrd 85ed5db
Fix and complete the Metal 4 wrappers
christiangnrd 43f6b60
Hook up
christiangnrd 6d22968
Address review findings in the Metal 4 submission path
christiangnrd 7f10e94
Order derived Metal 3 command buffers after later Metal 4 batches
christiangnrd 0c4b901
Rename MTL4Submission to Mtl4Submission
christiangnrd 64f8843
Qualify @atomic in the batching code for Julia 1.10 and 1.11
christiangnrd File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| # | ||
| # argument table descriptor | ||
| # | ||
|
|
||
| export MTL4ArgumentTable, MTL4ArgumentTableDescriptor | ||
|
|
||
| # @objcwrapper managed = true MTL4ArgumentTableDescriptor <: NSObject | ||
|
|
||
| function MTL4ArgumentTableDescriptor() | ||
| return @objc [MTL4ArgumentTableDescriptor new]::MTL4ArgumentTableDescriptor | ||
| end | ||
|
|
||
|
|
||
| # | ||
| # argument table | ||
| # | ||
|
|
||
| # @objcwrapper managed = true MTL4ArgumentTable <: NSObject | ||
|
|
||
| """ | ||
| MTL4ArgumentTable(device, desc::MTL4ArgumentTableDescriptor) | ||
|
|
||
| Create an argument table: the Metal 4 replacement for the per-encoder `setBuffer:`/ | ||
| `setBytes:` binding state. Bindings are captured when a command is encoded, so a single | ||
| table can be rebound between dispatches on the same encoder. | ||
| """ | ||
| function MTL4ArgumentTable(device::MTLDevice, desc::MTL4ArgumentTableDescriptor) | ||
| err = Ref{id{NSError}}(nil) | ||
| argtab = @objc [device::id{MTLDevice} newArgumentTableWithDescriptor:desc::id{MTL4ArgumentTableDescriptor} | ||
| error:err::Ptr{id{NSError}}]::Union{Nothing,MTL4ArgumentTable} | ||
| argtab === nothing && throw_error(err[]) | ||
| return argtab | ||
| end | ||
|
|
||
| function MTL4ArgumentTable(device::MTLDevice; buffers::Integer=0, textures::Integer=0, | ||
| samplers::Integer=0, label=nothing) | ||
| desc = MTL4ArgumentTableDescriptor() | ||
| desc.maxBufferBindCount = buffers | ||
| desc.maxTextureBindCount = textures | ||
| desc.maxSamplerStateBindCount = samplers | ||
| label === nothing || (desc.label = label) | ||
| return MTL4ArgumentTable(device, desc) | ||
| end | ||
|
|
||
| # NOTE: binding indices are 1-based here, like `set_buffer!`/`set_bytes!` on a Metal 3 | ||
| # compute command encoder; they are lowered to Metal's 0-based `[[buffer(n)]]` slots. | ||
|
|
||
| """ | ||
| set_address!(argtab::MTL4ArgumentTable, address, index) | ||
|
|
||
| Bind a raw GPU virtual address to the 1-based buffer binding `index`. | ||
| """ | ||
| function set_address!(argtab::MTL4ArgumentTable, address::Integer, index::Integer) | ||
| @objc [argtab::id{MTL4ArgumentTable} setAddress:UInt64(address)::MTLGPUAddress | ||
| atIndex:(index-1)::NSUInteger]::Nothing | ||
| end | ||
|
|
||
| """ | ||
| set_address!(argtab::MTL4ArgumentTable, address, stride, index) | ||
|
|
||
| Bind a raw GPU virtual address with an explicit attribute stride. The table must have been | ||
| created with `supportAttributeStrides` enabled. | ||
| """ | ||
| function set_address!(argtab::MTL4ArgumentTable, address::Integer, stride::Integer, | ||
| index::Integer) | ||
| @objc [argtab::id{MTL4ArgumentTable} setAddress:UInt64(address)::MTLGPUAddress | ||
| attributeStride:stride::NSUInteger | ||
| atIndex:(index-1)::NSUInteger]::Nothing | ||
| end | ||
|
|
||
| """ | ||
| set_buffer!(argtab::MTL4ArgumentTable, buf::MTLBuffer, offset, index) | ||
|
|
||
| Bind `buf` (at a byte `offset`) to the 1-based buffer binding `index`. | ||
|
|
||
| Unlike Metal 3's `setBuffer:offset:atIndex:`, this binds the buffer's GPU address and does | ||
| *not* make it resident: the buffer must be covered by a residency set that is used by the | ||
| command buffer, or attached to the queue. | ||
| """ | ||
| function set_buffer!(argtab::MTL4ArgumentTable, buf::MTLBuffer, offset::Integer, | ||
| index::Integer) | ||
| @inline set_address!(argtab, UInt64(buf.gpuAddress) + offset, index) | ||
| end | ||
|
|
||
| function set_resource!(argtab::MTL4ArgumentTable, resource::MTLResourceID, index::Integer) | ||
| @objc [argtab::id{MTL4ArgumentTable} setResource:resource::MTLResourceID | ||
| atBufferIndex:(index-1)::NSUInteger]::Nothing | ||
| end | ||
|
|
||
| function set_texture!(argtab::MTL4ArgumentTable, texture::MTLResourceID, index::Integer) | ||
| @objc [argtab::id{MTL4ArgumentTable} setTexture:texture::MTLResourceID | ||
| atIndex:(index-1)::NSUInteger]::Nothing | ||
| end | ||
| set_texture!(argtab::MTL4ArgumentTable, texture::MTLTexture, index::Integer) = | ||
| set_texture!(argtab, texture.gpuResourceID, index) | ||
|
|
||
| function set_sampler_state!(argtab::MTL4ArgumentTable, sampler::MTLResourceID, index::Integer) | ||
| @objc [argtab::id{MTL4ArgumentTable} setSamplerState:sampler::MTLResourceID | ||
| atIndex:(index-1)::NSUInteger]::Nothing | ||
| end | ||
| set_sampler_state!(argtab::MTL4ArgumentTable, sampler::MTLSamplerState, index::Integer) = | ||
| set_sampler_state!(argtab, sampler.gpuResourceID, index) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| # | ||
| # command allocator descriptor | ||
| # | ||
|
|
||
| export MTL4CommandAllocatorDescriptor | ||
|
|
||
| # @objcwrapper managed = true MTL4CommandAllocatorDescriptor <: NSObject | ||
|
|
||
| function MTL4CommandAllocatorDescriptor() | ||
| return @objc [MTL4CommandAllocatorDescriptor new]::MTL4CommandAllocatorDescriptor | ||
| end | ||
|
|
||
| function MTL4CommandAllocatorDescriptor(label) | ||
| desc = MTL4CommandAllocatorDescriptor() | ||
| desc.label = label | ||
| return desc | ||
| end | ||
|
|
||
|
|
||
| # | ||
| # command allocator | ||
| # | ||
|
|
||
| export MTL4CommandAllocator | ||
|
|
||
| # @objcwrapper managed = true MTL4CommandAllocator <: NSObject | ||
|
|
||
| function MTL4CommandAllocator(dev::MTLDevice) | ||
| return @objc [dev::id{MTLDevice} newCommandAllocator]::MTL4CommandAllocator | ||
| end | ||
|
|
||
| function MTL4CommandAllocator(dev::MTLDevice, desc::MTL4CommandAllocatorDescriptor) | ||
| err = Ref{id{NSError}}(nil) | ||
| alloc = @objc [dev::id{MTLDevice} newCommandAllocatorWithDescriptor:desc::id{MTL4CommandAllocatorDescriptor} | ||
| error:err::Ptr{id{NSError}}]::Union{Nothing,MTL4CommandAllocator} | ||
| alloc === nothing && throw_error(err[]) | ||
| return alloc | ||
| end | ||
|
|
||
| function MTL4CommandAllocator(dev::MTLDevice, label::Union{String,NSString}) | ||
| desc = MTL4CommandAllocatorDescriptor(label) | ||
| return MTL4CommandAllocator(dev, desc) | ||
| end | ||
|
|
||
| """ | ||
| allocatedSize(alloc::MTL4CommandAllocator)::UInt64 | ||
|
|
||
| The amount of memory, in bytes, that `alloc` currently holds for command storage. | ||
| """ | ||
| function allocatedSize(alloc::MTL4CommandAllocator) | ||
| @objc [alloc::id{MTL4CommandAllocator} allocatedSize]::UInt64 | ||
| end | ||
|
|
||
| """ | ||
| reset!(alloc::MTL4CommandAllocator) | ||
|
|
||
| Return `alloc`'s memory to it for reuse. This invalidates the commands of every command | ||
| buffer that was encoded with `alloc`, so it is only legal once the GPU has finished | ||
| executing all of them. | ||
| """ | ||
| function reset!(alloc::MTL4CommandAllocator) | ||
| @objc [alloc::id{MTL4CommandAllocator} reset]::Nothing | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| # | ||
| # command buffer options | ||
| # | ||
|
|
||
| export MTL4CommandBufferOptions | ||
|
|
||
| # @objcwrapper managed = true MTL4CommandBufferOptions <: NSObject | ||
|
|
||
| function MTL4CommandBufferOptions() | ||
| return @objc [MTL4CommandBufferOptions new]::MTL4CommandBufferOptions | ||
| end | ||
|
|
||
|
|
||
| # | ||
| # command buffer | ||
| # | ||
|
|
||
| export MTL4CommandBuffer, beginCommandBuffer!, endCommandBuffer! | ||
|
|
||
| # @objcwrapper managed = true MTL4CommandBuffer <: NSObject | ||
|
|
||
| """ | ||
| MTL4CommandBuffer(dev::MTLDevice) | ||
|
|
||
| Create a Metal 4 command buffer. Unlike a Metal 3 `MTLCommandBuffer`, this object is not | ||
| tied to a queue and carries no storage of its own: it is a reusable encoding cursor that | ||
| writes into the [`MTL4CommandAllocator`](@ref) passed to [`beginCommandBuffer!`](@ref), and | ||
| it can be re-used for another encoding pass as soon as it has been committed. | ||
| """ | ||
| function MTL4CommandBuffer(dev::MTLDevice) | ||
| return @objc [dev::id{MTLDevice} newCommandBuffer]::MTL4CommandBuffer | ||
| end | ||
|
|
||
| function MTL4CommandBuffer(dev::MTLDevice, label::Union{String,NSString}) | ||
| cmdbuf = MTL4CommandBuffer(dev) | ||
| cmdbuf.label = label | ||
| return cmdbuf | ||
| end | ||
|
|
||
| """ | ||
| beginCommandBuffer!(cmdbuf::MTL4CommandBuffer, allocator::MTL4CommandAllocator, [options]) | ||
|
|
||
| Open `cmdbuf` for encoding, storing its commands in `allocator`. | ||
| """ | ||
| function beginCommandBuffer!(cmdbuf::MTL4CommandBuffer, allocator::MTL4CommandAllocator) | ||
| @objc [cmdbuf::id{MTL4CommandBuffer} beginCommandBufferWithAllocator:allocator::id{MTL4CommandAllocator}]::Nothing | ||
| end | ||
|
|
||
| function beginCommandBuffer!(cmdbuf::MTL4CommandBuffer, allocator::MTL4CommandAllocator, | ||
| options::MTL4CommandBufferOptions) | ||
| @objc [cmdbuf::id{MTL4CommandBuffer} beginCommandBufferWithAllocator:allocator::id{MTL4CommandAllocator} | ||
| options:options::id{MTL4CommandBufferOptions}]::Nothing | ||
| end | ||
|
|
||
| """ | ||
| endCommandBuffer!(cmdbuf::MTL4CommandBuffer) | ||
|
|
||
| Close `cmdbuf` for encoding, making it eligible for `commit!`. | ||
| """ | ||
| function endCommandBuffer!(cmdbuf::MTL4CommandBuffer) | ||
| @objc [cmdbuf::id{MTL4CommandBuffer} endCommandBuffer]::Nothing | ||
| end | ||
|
|
||
| """ | ||
| MTL4CommandBuffer(f, dev, allocator; queue, options) | ||
|
|
||
| Open a command buffer, apply `f` to it, then end and commit it on `queue`, returning `f`'s | ||
| value. | ||
| """ | ||
| function MTL4CommandBuffer(f::Base.Callable, dev::MTLDevice, | ||
| allocator::MTL4CommandAllocator=MTL4CommandAllocator(dev); | ||
| queue::MTL4CommandQueue=MTL4CommandQueue(dev), | ||
| options::Union{Nothing,MTL4CommitOptions}=nothing) | ||
| cmdbuf = MTL4CommandBuffer(dev) | ||
| beginCommandBuffer!(cmdbuf, allocator) | ||
| ret = try | ||
| f(cmdbuf) | ||
| finally | ||
| endCommandBuffer!(cmdbuf) | ||
| end | ||
| if options === nothing | ||
| commit!(queue, cmdbuf) | ||
| else | ||
| commit!(queue, cmdbuf, options) | ||
| end | ||
| return ret | ||
| end | ||
|
|
||
| function use_residency_set!(cmdbuf::MTL4CommandBuffer, resset::MTLResidencySet) | ||
| @objc [cmdbuf::id{MTL4CommandBuffer} useResidencySet:resset::id{MTLResidencySet}]::Nothing | ||
| end | ||
|
|
||
| function use_residency_sets!(cmdbuf::MTL4CommandBuffer, ressets, count) | ||
| @objc [cmdbuf::id{MTL4CommandBuffer} useResidencySets:ressets::Ptr{id{MTLResidencySet}} | ||
| count:count::NSUInteger]::Nothing | ||
| end | ||
|
|
||
| function push_debug_group!(cmdbuf::MTL4CommandBuffer, name::Union{String,NSString}) | ||
| @objc [cmdbuf::id{MTL4CommandBuffer} pushDebugGroup:name::id{NSString}]::Nothing | ||
| end | ||
|
|
||
| function pop_debug_group!(cmdbuf::MTL4CommandBuffer) | ||
| @objc [cmdbuf::id{MTL4CommandBuffer} popDebugGroup]::Nothing | ||
| end |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
How large is the Metal 4 API? Should we put it in a
mtl4top-level folder?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.
A lot of the Metal 4 API lives as new methods of Metal 3 Objects so maybe a mtl4 subfolder in lib/mtl would be more appropriate?