ANGLE emulates transform feedback using the vertexPipelineStoresAndAtomics features in Vulkan. But some GPU vendors do not support these atomics. Also the emulation becomes more difficult in GLES 3.2. Therefore ANGLE must support using the VK_EXT_transform_feedback extension.
We also expect a performance gain when we use this extension.
The Vulkan extension does not provide separate APIs for glPauseTransformFeedback
/ glEndTransformFeedback
.
Instead, Vulkan introduced Counter buffers in vkCmdBeginTransformFeedbackEXT
/ vkCmdEndTransformFeedbackEXT
as API parameters.
To pause, we call vkCmdEndTransformFeedbackEXT
and provide valid buffer handles in the pCounterBuffers
array and valid offsets in the pCounterBufferOffsets
array for the implementation to save the resume points.
Then to resume, we call vkCmdBeginTransformFeedbackEXT
with the previous pCounterBuffers
and pCounterBufferOffsets
values.
Between the pause and resume there needs to be a memory barrier for the counter buffers with a source access of VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT
at pipeline stage VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT
to a destination access of VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT
at pipeline stage VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
.
There is no equivalent function for glTransformFeedbackVaryings in Vulkan. The Vulkan specification states that the last vertex processing stage shader must be declared with the XFB execution mode.
The SPIR-V transformer takes care of adding this execution mode, as well as decorating the variables that need to be captured.
ANGLE modifies gl_position.z in vertex shader for the Vulkan coordinate system. So, if we capture the value of ‘gl_position’ in the XFB buffer, the captured values will be incorrect. To resolve this, we declare an internal position varying and copy the value from ‘gl_position’. We capture the internal position varying during transform feedback operation. For simplicity, we do this for every captured varying, even though we could decorate the gl_PerVertex
struct members in SPIR-V directly.