ANGLE's Vulkan back-end implementation lives in this folder.
Vulkan is an explicit graphics API. It has a lot in common with other explicit APIs such as Microsoft's D3D12 and Apple's Metal. Compared to APIs like OpenGL or D3D11 explicit APIs can offer a number of significant benefits:
- Lower API call CPU overhead.
- A smaller API surface with more direct hardware control.
- Better support for multi-core programming.
- Vulkan in particular has open-source tooling and tests.
The RendererVk
class represents an EGLDisplay
. RendererVk
owns shared global
resources like the VkDevice, VkQueue, the Vulkan format tables
and internal Vulkan shaders. The ContextVk class implements the back-end
of a front-end OpenGL Context. ContextVk processes state changes and handles action commands like
glDrawArrays
and glDrawElements
.
The back-end records commands into command buffers via the following ContextVk
APIs:
beginNewRenderPass
: Writes out (aka flushes) prior pending commands into a primary command buffer, then starts a new render pass. Returns a secondary command buffer inside a render pass instance.getOutsideRenderPassCommandBuffer
: May flush prior command buffers and close the render pass if necessary, in addition to issuing the appropriate barriers. Returns a secondary command buffer outside a render pass instance.getStartedRenderPassCommands
: Returns a reference to the currently open render pass' commands buffer.
The back-end (mostly) records Image and Buffer barriers through additional CommandBufferAccess
APIs, the result of which is passed to getOutsideRenderPassCommandBuffer
. Note that the
barriers are not actually recorded until getOutsideRenderPassCommandBuffer
is called:
onBufferTransferRead
andonBufferComputeShaderRead
accumulateVkBuffer
read barriers.onBufferTransferWrite
andonBufferComputeShaderWrite
accumulateVkBuffer
write barriers.onBuffferSelfCopy
is a special case forVkBuffer
self copies. It behaves the same as write.onImageTransferRead
andonImageComputerShadeRead
accumulateVkImage
read barriers.onImageTransferWrite
andonImageComputerShadeWrite
accumulateVkImage
write barriers.onImageRenderPassRead
andonImageRenderPassWrite
accumulateVkImage
barriers inside a started RenderPass.
After the back-end records commands to the primary buffer and we flush (e.g. on swap) or when we call
ContextVk::finishToSerial
, ANGLE submits the primary command buffer to a VkQueue
.
See the code for more details.
In this example we'll be recording a buffer copy command:
// Ensure that ANGLE sets proper read and write barriers for the Buffers.
vk::CommandBufferAccess access;
access.onBufferTransferWrite(destBuffer);
access.onBufferTransferRead(srcBuffer);
// Get a pointer to a secondary command buffer for command recording.
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(access, &commandBuffer));
// Record the copy command into the secondary buffer. We're done!
commandBuffer->copyBuffer(srcBuffer->getBuffer(), destBuffer->getBuffer(), copyCount, copies);
More implementation details can be found in the doc
directory: