In order , it turns out that using the rasterization vertex function is the way to go. There are some things to note, however, for other future references:
A non-sterilizing vertex function is just a vertex function returning void ie:
vertex void non_rasterizing_vertex(...) { }
When performing non-rasterizing "rendering", the MTLRenderPassDescriptor
pass MTLRenderPassDescriptor
still have a set of textures - for example, in MTLRenderPassDescriptor
colorAttachments[0].texture
- for reasons that I do not know (I assume that this is simply due to the fixed nature of the GPU programming).
MTLRenderPipelineState
must have the rasterizationEnabled
property set to false
, then you can assign it a non-rasterizing vertexFunction
vertex vertexFunction
. The fragmentFunction
property may remain null as expected.
When actually skipping, one of the drawPrimitives:
methods (the assignment of which may be misleading ) still needs to call the configured MTLRenderCommandEncoder
. I ended up with the MTLPrimitiveType.Point
rendering MTLPrimitiveType.Point
, as it seems the most sensual.
Doing all of this sets up the "rendering" logic, ready to write back to vertex buffers from the vertex function if they are in the device
address space:
vertex void non_rasterizing_vertex(device float *writeableBuffer [[ buffer(0) ]], uint vid [[ vertex_id ]]) { writeableBuffer[vid] = 42;
This "answer" is more like a blog post, but I hope it will be useful for future links.
Todo
I would still like to explore performance trade-offs between compute-y execution, as is the case in the computing pipeline, compared to the rendering pipeline, as shown above. As soon as I have some more time, I will update this answer.