Download as pdf or txt
Download as pdf or txt
You are on page 1of 29

10 9 tips for Vulkan development

Damien Mabin | 16/03/2016


0. Where does Vulkan come from ?
1. Overall architecture
2. GLSL Spir-V
3. Batch !

agenda 4. Multithreading
5. Multithreading - synchronisation
6. Re-use pipeline
7. Minimise render-pass
8. Group descriptor sets by frequency
0. Where does Vulkan come from ?
0. Where does Vulkan come from ?
Old pipeline (OpenGL 1.0)
0. Where does Vulkan come from ?
OpenGL 4.0 pipeline
0. Where does Vulkan come from ?

Vulkan answer the needs of:


● Cross-platform modern graphic api
● Predictable behavior
● Predictable performance
● Multi thread friendly
● Extensible

Confidential and proprietary


0. Where does Vulkan come from ?
Supporting text

Vulkan answer the needs of: OpenGL Vulkan

● Cross-platform modern graphic api


App
● Predictable behavior
● Predictable performance App

● Multi thread friendly


Driver
● Extensible
Driver

Confidential and proprietary


1. Overall architecture
1. Overall architecture

Scissors /
Descriptor sets layout

buffers
blending

buffers
Pipeline

buffers
Memory
Type 0
Shader module

Descriptor sets

Memory
Framebuffer Type 1
Render pass Command
buffer
Depth buffer

Color buffer

Queue(s)
Memory

Graphic
Type 2

Hardware

Confidential and proprietary


2. GLSL Spir-V
2. GLSL Spir-V

Spir-V is the only shader format accepted by Vulkan


● But GLSL can be compile to Spir-V
○ Statically (and your project embed only Spir-V)
○ Dynamically (during development)
● Help protect IP
● One shader can have multiple entry point
● One shader can be reused with different pipelines

Confidential and proprietary


3. Batch !
3. Batch !

Vulkan Api can perform many operation at a time


● vkAllocateCommandBuffers
● vkCmdDraw
● vkUpdateDescriptorSets
● vkDraw
● [...]

Confidential and proprietary


3. Batch !
Sub-allocate memory

● vkAllocateMemory -> relatively expensive


● => Allocate big chunk for your small buffers and small
textures

Confidential and proprietary


4. Multithreading
4. Multithreading
Synchronisation is your responsibility

Many operation can be done in //


● Load texture & shaders
● Build your pipeline(s)
● build your command buffers

● Avoid local data in each thread => make it is easy to use a


threadpool / change amount of threads

Confidential and proprietary


5. Multithreading - synchronisation
5. Multithreading - synchronisation
Synchronisation is your responsibility

Vulkan offer 5 synchronization primitives:


● Fence => Sync CPU and GPU
● Semaphore => Sync between queues
● Event => Sync inside a queue between command buffer
● Memory barrier
● Pipeline barrier

Confidential and proprietary


6. Re-use pipeline
6. Re-use pipeline

Represents all static state for entire 3D pipeline


● Shaders
● Vertex input
● Tests (depth, scissor, stencil)
● Blending
● Descriptor set layout

Create them outside the critical path (during your scene loading)
Pipeline have a “VkPipelineCache”, use it, and even cache them on your FS

Confidential and proprietary


7. Minimise render-pass
7. Minimise render-pass
Imediat renderer

You draw... GPU Renders

Triangle 1

then

Triangle 2

then

Triangle 3 Triangle 1 Triangle 2 Triangle 3

Confidential and proprietary


7. Minimise render-pass
Tile renderer

You draw... GPU Bins GPU Renders

Triangle 1 Tri 1 Tri 2


Tri 2 Tri 3
then

Bin A Bin B Tile A Tile B


Triangle 2

then Tri 2
Tri 2
Tri 3
Triangle 3

Bin C Bin D Tile C Tile D

Confidential and proprietary


7. Minimise render-pass
sub-passes

Without Vulkan sub-passes With Vulkan sub-passes


For each pass: render each tile and commit to For each tile: render each subpass.
memory. Later passes must reload. MSAA Relevant data stays on-chip. Resolve MSAA
multiplies off-chip cost. after last-pass, store once.

Pass 1 Pass 2
Tile 1, Tile 1,
Pass 1 Pass 2

Tile 2, Tile 2,
Pass 1 Pass 2

Confidential and proprietary


7. Minimise render-pass
sub-passes

Subpass dependencies Single-pixel sources only (for now)

● Specify by-region— otherwise it’s a


● Each subpass can only access
global dependency, and it waits on all data for the same pixel in prior
pixels in prior pass
passes

Confidential and proprietary


8. Group descriptor sets by frequency
8. Group descriptor sets by frequency

Shader code
Shader code
layout(set=0,binding=0) uniform { ... } set0;
layout(set=1,binding=0) uniform { ... } set1;
layout(set=2,binding=0) uniform { ... } set2;
[...]

Confidential and proprietary


8. Group descriptor sets by frequency

Shader code
Shader code
layout(set=0,binding=0) uniform { ... } set0; // “Scene/Global” data
layout(set=1,binding=0) uniform { ... } set1; // Per mesh data
layout(set=2,binding=0) uniform { ... } set2; // Per Instance data
[...]

Confidential and proprietary


thank
you

You might also like