Commit c79b0ea5 by Jamie Madill Committed by Commit Bot

Vulkan: Document command access APIs.

Includes a short description of the ContextVk command APIs. Also a few small cleanups to other Vulkan back-end documentation. Bug: angleproject:4029 Change-Id: I3bd04861f27b718e6a94fdae00644c124452bc62 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2070597 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com>
parent 0a450363
...@@ -22,7 +22,55 @@ and [internal Vulkan shaders](shaders). The [ContextVk](ContextVk.cpp) class imp ...@@ -22,7 +22,55 @@ and [internal Vulkan shaders](shaders). The [ContextVk](ContextVk.cpp) class imp
of a front-end OpenGL Context. ContextVk processes state changes and handles action commands like of a front-end OpenGL Context. ContextVk processes state changes and handles action commands like
`glDrawArrays` and `glDrawElements`. `glDrawArrays` and `glDrawElements`.
Implementation details can be found in the `doc` directory. ## Command recording
The back-end records commands into command buffers via the the following `ContextVk` APIs:
* `endRenderPassAndGetCommandBuffer`: returns a secondary command buffer *outside* a RenderPass instance.
* `flushAndBeginRenderPass`: returns a secondary command buffer *inside* a RenderPass instance.
* `flushAndGetPrimaryCommandBuffer`: returns the primary command buffer. You should rarely need this API.
*Note*: All of these commands may write out (aka flush) prior pending commands into a primary
command buffer. When a RenderPass is open `endRenderPassAndGetCommandBuffer` will flush the
pending RenderPass commands. `flushAndBeginRenderPass` will flush out pending commands outside a
RenderPass to a primary buffer. On submit ANGLE submits the primary command buffer to a `VkQueue`.
If you need to record inside a RenderPass, use `flushAndBeginRenderPass`. Otherwise, use
`endRenderPassAndGetCommandBuffer`. You should rarely need to call `flushAndGetPrimaryCommandBuffer`.
It's there for commands like debug labels, barriers and queries that need to be recorded serially on
the primary command buffer.
The back-end usually records Image and Buffer barriers through additional `ContextVk` APIs:
* `onBufferRead` and `onBufferWrite` accumulate `VkBuffer` barriers.
* `onImageRead` and `onImageWrite` accumulate `VkImage` barriers.
* `onRenderPassImageWrite` is a special API for write barriers inside a RenderPass instance.
After the back-end records commands to the primary buffer we flush (e.g. on swap) or when we call
`ContextVk::finishToSerial`.
See the [code][CommandAPIs] for more details.
### Simple command recording example
In this example we'll be recording a buffer copy command:
```
# Ensure that ANGLE sets proper read and write barriers for the Buffers.
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, destBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, srcBuffer));
# Get a pointer to a secondary command buffer for command recording. May "flush" the RP.
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
# Record the copy command into the secondary buffer. We're done!
commandBuffer->copyBuffer(srcBuffer->getBuffer(), destBuffer->getBuffer(), copyCount, copies);
```
## Additional Reading
More implementation details can be found in the `doc` directory:
- [Fast OpenGL State Transitions](doc/FastOpenGLStateTransitions.md) - [Fast OpenGL State Transitions](doc/FastOpenGLStateTransitions.md)
- [Shader Module Compilation](doc/ShaderModuleCompilation.md) - [Shader Module Compilation](doc/ShaderModuleCompilation.md)
...@@ -31,3 +79,5 @@ Implementation details can be found in the `doc` directory. ...@@ -31,3 +79,5 @@ Implementation details can be found in the `doc` directory.
[VkDevice]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkDevice.html [VkDevice]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkDevice.html
[VkQueue]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkQueue.html [VkQueue]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkQueue.html
[CommandAPIs]: https://chromium.googlesource.com/angle/angle/+/aa09ca69e4173cb14261e39be3b7bdf56bbd3840/src/libANGLE/renderer/vulkan/ContextVk.h#579
...@@ -3,15 +3,19 @@ ...@@ -3,15 +3,19 @@
Typical OpenGL programs issue a few small state change commands between draw call commands. We want Typical OpenGL programs issue a few small state change commands between draw call commands. We want
the typical app's use case to be as fast as possible so this leads to unique performance challenges. the typical app's use case to be as fast as possible so this leads to unique performance challenges.
Vulkan in quite different from OpenGL because it requires a separate compiled Vulkan is quite different from OpenGL because it requires a separate compiled
[VkPipeline][VkPipeline] for each state vector. Compiling VkPipelines is multiple orders of [VkPipeline][VkPipeline] for each state vector. Compiling VkPipelines is multiple orders of
magnitude slower than enabling or disabling an OpenGL render state. To speed this up we use three magnitude slower than enabling or disabling an OpenGL render state. To speed this up we use three
levels of caching when transitioning states in the Vulkan back-end. levels of caching when transitioning states in the Vulkan back-end.
The first level is the driver's [VkPipelineCache][VkPipelineCache]. The driver ## L3 Cache
The outermost level is the driver's [VkPipelineCache][VkPipelineCache]. The driver
cache reduces pipeline recompilation time significantly. But even cached cache reduces pipeline recompilation time significantly. But even cached
pipeline recompilations are orders of manitude slower than OpenGL state changes. pipeline recompilations are orders of manitude slower than OpenGL state changes.
## L2 Cache
The second level cache is an ANGLE-owned hash map from OpenGL state vectors to compiled pipelines. The second level cache is an ANGLE-owned hash map from OpenGL state vectors to compiled pipelines.
See [GraphicsPipelineCache][GraphicsPipelineCache] in [vk_cache_utils.h](../vk_cache_utils.h). ANGLE's See [GraphicsPipelineCache][GraphicsPipelineCache] in [vk_cache_utils.h](../vk_cache_utils.h). ANGLE's
[GraphicsPipelineDesc][GraphicsPipelineDesc] class is a tightly packed 256-byte description of the [GraphicsPipelineDesc][GraphicsPipelineDesc] class is a tightly packed 256-byte description of the
...@@ -19,6 +23,8 @@ current OpenGL rendering state. We also use a [xxHash](https://github.com/Cyan49 ...@@ -19,6 +23,8 @@ current OpenGL rendering state. We also use a [xxHash](https://github.com/Cyan49
fastest possible hash computation. The hash map speeds up state changes considerably. But it is fastest possible hash computation. The hash map speeds up state changes considerably. But it is
still significantly slower than OpenGL implementations. still significantly slower than OpenGL implementations.
## L1 Cache
To get best performance we use a transition table from each OpenGL state vector to neighbouring To get best performance we use a transition table from each OpenGL state vector to neighbouring
state vectors. The transition table points from GraphicsPipelineCache entries directly to state vectors. The transition table points from GraphicsPipelineCache entries directly to
neighbouring VkPipeline objects. When the application changes state the state change bits are neighbouring VkPipeline objects. When the application changes state the state change bits are
...@@ -35,6 +41,11 @@ applications map from one state to many this will slow down the transition time. ...@@ -35,6 +41,11 @@ applications map from one state to many this will slow down the transition time.
improved in the future using a faster look up. For instance we could keep a sorted transition table improved in the future using a faster look up. For instance we could keep a sorted transition table
or use a small hash map for transitions. or use a small hash map for transitions.
## L0 Cache
The current active PSO is stored as a handle in the `ContextVk` for use between draws with no state
change.
[VkPipeline]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkPipeline.html [VkPipeline]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkPipeline.html
[VkPipelineCache]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkPipelineCache.html [VkPipelineCache]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkPipelineCache.html
[GraphicsPipelineCache]: https://chromium.googlesource.com/angle/angle/+/225f08bf85a368f905362cdd1366e4795680452c/src/libANGLE/renderer/vulkan/vk_cache_utils.h#498 [GraphicsPipelineCache]: https://chromium.googlesource.com/angle/angle/+/225f08bf85a368f905362cdd1366e4795680452c/src/libANGLE/renderer/vulkan/vk_cache_utils.h#498
......
...@@ -17,9 +17,8 @@ is not supported. ...@@ -17,9 +17,8 @@ is not supported.
## The Vulkan Format Table ## The Vulkan Format Table
Overrides and fallbacks are implemented in ANGLE's [Vulkan format Overrides and fallbacks are implemented in ANGLE's [Vulkan format table][../vk_format_table_autogen.cpp].
table][../vk_format_table_autogen.cpp]. The table is auto-generated by The table is auto-generated by [`gen_vk_format_table.py`](../gen_vk_format_table.py). We store the mapping from
[`gen_vk_format_table.py`](../gen_vk_format_table.py). We store the mapping from
[`angle::Format::ID`](../../FormatID_autogen.h) to [VkFormat][VkFormat] in [`angle::Format::ID`](../../FormatID_autogen.h) to [VkFormat][VkFormat] in
[`vk_format_map.json`](../vk_format_map.json). The format map also lists the overrides and fallbacks. [`vk_format_map.json`](../vk_format_map.json). The format map also lists the overrides and fallbacks.
To update the tables please modify the format map JSON and then run To update the tables please modify the format map JSON and then run
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment