xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/doc/TransformFeedbackViaExtension.md (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1# Transform Feedback via extension
2
3## Outline
4
5ANGLE emulates transform feedback using the vertexPipelineStoresAndAtomics features in Vulkan.
6But some GPU vendors do not support these atomics. Also the emulation becomes more difficult in
7GLES 3.2. Therefore ANGLE must support using the VK_EXT_transform_feedback extension.
8
9We also expect a performance gain when we use this extension.
10
11## Implementation of Pause/Resume using CounterBuffer
12
13The Vulkan extension does not provide separate APIs for `glPauseTransformFeedback` /
14`glEndTransformFeedback`.
15
16Instead, Vulkan introduced Counter buffers in `vkCmdBeginTransformFeedbackEXT` /
17`vkCmdEndTransformFeedbackEXT` as API parameters.
18
19To pause, we call `vkCmdEndTransformFeedbackEXT` and provide valid buffer handles in the
20`pCounterBuffers` array and valid offsets in the `pCounterBufferOffsets` array for the
21implementation to save the resume points.
22
23Then to resume, we call `vkCmdBeginTransformFeedbackEXT` with the previous `pCounterBuffers`
24and `pCounterBufferOffsets` values.
25
26Between the pause and resume there needs to be a memory barrier for the counter buffers with a
27source access of `VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT` at pipeline stage
28`VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT` to a destination access of
29`VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT` at pipeline stage
30`VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT`.
31
32## Implementation of glTransformFeedbackVaryings
33
34There is no equivalent function for glTransformFeedbackVaryings in Vulkan. The Vulkan specification
35states that the last vertex processing stage shader must be declared with the XFB execution mode.
36
37The SPIR-V transformer takes care of adding this execution mode, as well as decorating the variables
38that need to be captured.
39
40ANGLE modifies gl_position.z in vertex shader for the Vulkan coordinate system. So, if we capture
41the value of 'gl_position' in the XFB buffer, the captured values will be incorrect. To resolve
42this, we declare an internal position varying and copy the value from 'gl_position'. We capture the
43internal position varying during transform feedback operation. For simplicity, we do this for every
44captured varying, even though we could decorate the `gl_PerVertex` struct members in SPIR-V
45directly.
46