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
Resource copying/clearing/updating investigations #28
Comments
To clarify, clear commands are not supported on transfer queues even though they count as transfer operations. |
I don't believe there is any scaling. It's just a copy of that rectangle into the destination, at a specified origin. |
@grorg thanks for clarification! I removed the note from the body now. |
Thanks for the nice analysis! I'd like to point out that in NXT we have found a way to abstract the With respect to the proposed API:
It sounds like it could be a built-in compute shader. |
For any kind of resource (texture or buffer) easy clearing would be highly desirable for compute shader usecases which don't have any way of doing clear via new RenderPasses. Today, all of these cases required specialized clear passes and in many cases (even more to the annoyance of any users) bindgroups, layouts etc. |
Can you explain how it requires bindgroups layouts, etc? |
Yes, I was referring to the usecase of having a dedicated compute pass. For everything where a beginRenderPass works, a separate clear function isn't truly needed anyways. It's ofc true that a user can encapsulate something like this in a function but this way of clearing requires a lot of book keeping that the clear functions of dx12/vulkan don't need: For every type (image format, image dimension etc.) there i a special compute pipeline needed. Every single resource that needs cleaning also needs a bind group just containing this one resource. |
@Wumpf would you be willing to write down a more concrete proposal (in a separate issue), with the following:
|
metal has BlitCommandEncoder::fillBuffer function |
Native APIs provide different constraints and features when it comes to resource copies and clears, where resources can be buffers or images. In this issue, we'll try to find a common ground (a least common denominator API) that is usable and efficient on all backends.
In Metal, all of the copy/clear operations are done via the
MTLBlitCommandEncoder
.In Vulkan, these are transfer operations, supported on any queue type. They require
TRANSFER_SRC
flag on the source andTRANSFER_DST
flag on the destination.Operation table
Buffer Updates
In D3D12, the only way to update a buffer with new data coming from CPU is to use a staging buffer (that is mapped, filled, then copied to the destination).
In Metal, similar effect can be achieved by creating a buffer with makeBuffer that re-uses the existing storage.
In Vulkan, the implementation may have a fast-path for small buffer updates by in-lining the data right into the command buffer space. The implementation can fall back to a staging-like scheme for larger updates.
Image Blitting
Image blits are different from image copies for allowing format conversion and arbitrary scaling with filtering. A typical use case for blitting is mipmap generation. It is not clear to me why/how Vulkan provides this on a transfer-only queue, but other APIs are far more (and reasonably) limited with regards to where and how they can blit surfaces.
Alignment rules
Vulkan
VkPhysicalDeviceLimits has optimal alignments for buffer data when transferring to/from image:
optimalBufferCopyOffsetAlignment
is the optimal buffer offset alignment in bytes forvkCmdCopyBufferToImage
andvkCmdCopyImageToBuffer
optimalBufferCopyRowPitchAlignment
is the optimal buffer row pitch alignment in bytes forvkCmdCopyBufferToImage
andvkCmdCopyImageToBuffer
These are not enforced by the validation layers but are recommended for optimal performance.
D3D12
MSDN section lists the following restrictions:
D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT
(512) bytesD3D12_TEXTURE_DATA_PITCH_ALIGNMENT
(256) bytesProposed API
Clears
D3D12 model appears to be the least common denominator. If we have the concept of views, we can have API calls to clear them. In Vulkan, these calls would trivially translate into direct clears. In Metal, we'd need to run a compute shader to clear the resources. Supporting multiple cear rectangles seems to complicate this scheme quite a bit, so I suggest only doing the full-slice clears.
Updates
Given the limited support of resource updates, I suggest not providing this API at all in favor of requiring the user to use staging resources manually.
Copies
All 3 APIs appear to provide the copy capability between buffers and textures. The difference is mostly about the alignment requirements. I suggest having device flags to the minimum offset/pitch required:
Blits
D3D12 doesn't support any sort of blitting, I'm inclined to propose no workarounds here. Users doing simple render passes for blitting textures shouldn't be slower than emulating this in the API, anyway.
Afterword
This analysis may be incomplete, corrections are welcome to go directly as the issue edits.
The text was updated successfully, but these errors were encountered: