1# ANGLE: Vulkan Back-end 2 3ANGLE's Vulkan back-end implementation lives in this folder. 4 5[Vulkan](https://www.khronos.org/vulkan/) is an explicit graphics API. It has a lot in common with 6other explicit APIs such as Microsoft's [D3D12][D3D12 Guide] and Apple's 7[Metal](https://developer.apple.com/metal/). Compared to APIs like OpenGL or D3D11 explicit APIs can 8offer a number of significant benefits: 9 10 * Lower API call CPU overhead. 11 * A smaller API surface with more direct hardware control. 12 * Better support for multi-core programming. 13 * Vulkan in particular has open-source tooling and tests. 14 15[D3D12 Guide]: https://docs.microsoft.com/en-us/windows/desktop/direct3d12/directx-12-programming-guide 16 17## Back-end Design 18 19The [`RendererVk`](RendererVk.cpp) class represents an `EGLDisplay`. `RendererVk` owns shared global 20resources like the [VkDevice][VkDevice], [VkQueue][VkQueue], the [Vulkan format tables](vk_format_utils.h) 21and [internal Vulkan shaders](shaders). The [ContextVk](ContextVk.cpp) class implements the back-end 22of a front-end OpenGL Context. ContextVk processes state changes and handles action commands like 23`glDrawArrays` and `glDrawElements`. 24 25## Command recording 26 27The back-end records commands into command buffers via the the following `ContextVk` APIs: 28 29 * `endRenderPassAndGetCommandBuffer`: returns a secondary command buffer *outside* a RenderPass instance. 30 * `flushAndBeginRenderPass`: returns a secondary command buffer *inside* a RenderPass instance. 31 * `flushAndGetPrimaryCommandBuffer`: returns the primary command buffer. You should rarely need this API. 32 33*Note*: All of these commands may write out (aka flush) prior pending commands into a primary 34command buffer. When a RenderPass is open `endRenderPassAndGetCommandBuffer` will flush the 35pending RenderPass commands. `flushAndBeginRenderPass` will flush out pending commands outside a 36RenderPass to a primary buffer. On submit ANGLE submits the primary command buffer to a `VkQueue`. 37 38If you need to record inside a RenderPass, use `flushAndBeginRenderPass`. Otherwise, use 39`endRenderPassAndGetCommandBuffer`. You should rarely need to call `flushAndGetPrimaryCommandBuffer`. 40It's there for commands like debug labels, barriers and queries that need to be recorded serially on 41the primary command buffer. 42 43The back-end usually records Image and Buffer barriers through additional `ContextVk` APIs: 44 45 * `onBufferTransferRead/onBufferComputeShaderRead` and `onBufferTransferWrite/onBufferComputeShaderWrite` accumulate `VkBuffer` barriers. 46 * `onImageRead` and `onImageWrite` accumulate `VkImage` barriers. 47 * `onRenderPassImageWrite` is a special API for write barriers inside a RenderPass instance. 48 49After the back-end records commands to the primary buffer we flush (e.g. on swap) or when we call 50`ContextVk::finishToSerial`. 51 52See the [code][CommandAPIs] for more details. 53 54### Simple command recording example 55 56In this example we'll be recording a buffer copy command: 57 58``` 59 # Ensure that ANGLE sets proper read and write barriers for the Buffers. 60 ANGLE_TRY(contextVk->onBufferTransferWrite(destBuffer)); 61 ANGLE_TRY(contextVk->onBufferTransferRead(srcBuffer)); 62 63 # Get a pointer to a secondary command buffer for command recording. May "flush" the RP. 64 vk::CommandBuffer *commandBuffer; 65 ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer)); 66 67 # Record the copy command into the secondary buffer. We're done! 68 commandBuffer->copyBuffer(srcBuffer->getBuffer(), destBuffer->getBuffer(), copyCount, copies); 69``` 70 71## Additional Reading 72 73More implementation details can be found in the `doc` directory: 74 75- [Fast OpenGL State Transitions](doc/FastOpenGLStateTransitions.md) 76- [Shader Module Compilation](doc/ShaderModuleCompilation.md) 77- [OpenGL Line Segment Rasterization](doc/OpenGLLineSegmentRasterization.md) 78- [Format Tables and Emulation](doc/FormatTablesAndEmulation.md) 79 80[VkDevice]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkDevice.html 81[VkQueue]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkQueue.html 82[CommandAPIs]: https://chromium.googlesource.com/angle/angle/+/df31624eaf3df986a0bdf3f58a87b79b0cc8db5c/src/libANGLE/renderer/vulkan/ContextVk.h#620 83 84