Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
Add output merger UAV binding. #478
Previously, unordered access views could only be bound to the compute stage. This patch lets them be bound to the output merger stage, so pixel shaders can read and write to them.
Much of the patch is based on how UAV binding for the compute stage works - there is an array of currently bound UAVs, and in SetUnorderedAccessView this is checked against and the UAV is bound if necessary.
However due to how Direct3D ties render targets and UAVs together (see here), its also necessary to keep track of the number of bound render targets, and to re-bind all the UAVs whenever one is changed. The patch prioritises render targets, in that if the targets and UAV registers are interleaved for whatever reason, it'll ensure all the render targets stay bound. Hopefully that makes sense haha.
I originally posted about this here: #471
Motivation and Context
There are several techniques that need the pixel shader to be able to write to arbitrary locations, such as voxelization, or order independent transparency.
Types of changes
Haha I'll admit I'm not really sure what to do regarding proper tests. At the very least I can say I've bound multiple UAVs (buffers and textures), and have successfully written and read from them. I imagine something like that'd be a good test to write? I'll look into getting that done.
Ah sorry for replying so late! Thanks so much for the review, will correct the patch (that typo is embarrassing, sorry).
My C# skills being as rusty as they are though, do you have any tips on how to pre-allocate those arrays?
The reason I currently allocate, is so I can pass a slice of the currentUARenderTargetViews array to SetUnorderedAccessViews. The only way I know how to do this in C# without an allocation is with ArraySegment, but I can't pass one to SetUnorderedAccessViews. Any ideas?
@WhyPenguins No problem for the typo, we had/have many of them as well!
For preallocating, the idea is to create a field which preallocate the array:
Yeah that was my concern, sorry if I wasn't clear enough. It's unfortunate since there's an internal method that does end up taking a pointer and count, but yeah it can't be used.
I suppose if the pre-allocation is important, a workaround could be an array of arrays with increasing sizes. Then the desired slice of the currentUARenderTargetViews array could be copied into the array with correct count, and that could be passed in?
Also would you prefer the commits to be cleaned up via rebasing (I'd squash the original and typo commits together and rebase to the current master) or do you prefer keeping the original history?