This is a traditional Hello World style application for the Vulkan API. It renders a RGB shaded equilateral triangle (well, if the resolution is a square).
The code is relatively flat and basic, so I think it's good enough for learning.
No tutorial or even much comments are provided though (comments do lie anyway
:smirk:). Though some things I found noteworthy are in the doc/
folder.
My goal here is to be perfectly conformant to the Vulkan specification. Also I
do handle all the Vulkan VkResult
s (with app termination though). And I try to
do things in the efficient way, rather than simplify. But I am only human.
:innocent:
If you appriciate any of my free work or help (e.g. hosting this), you can send me some sweet sweet money:
The git branches demonstrate some basic Vulkan features which can be easily
grafted on this basic example (it is nice to see a diff of what exactly needs to
be changed to make it work). Their README.md
should be edited to reflect the
changes.
branch | diff link | description |
---|---|---|
master | -- | Your regular Hello Triangle app, and base for the others |
MSAA | diff | Antialiasing (i.e. Vulkan's multisample image resolve) |
queue_transfer | diff | Transfer of EXCLUSIVE image between queue families (separate graphics and compute queue family) |
vertex_offset | diff | Demonstrates how offset in vkCmdBindVertexBuffers() works |
dxgi_interop | diff | An experiment that shows how to import swapchain images from DXGI (Direct3D 12 Swapchain) |
OS: Windows or Linux
Language: C++14
Build environment: (latest) Vulkan SDK (requires VULKAN_SDK
variable being set)
Build environment[Windows]: Visual Studio, Cygwin, or MinGW (or IDEs running on top of them)
Build environment[Linux]: CMake compatible compiler and build system and libxcb-dev
and libxcb-keysyms-dev
Build environment[MacOS]: CMake compatible compiler and build system
Build Environment[GLFW]: GLFW 3.2+ (already included as a git submodule), requires xorg-dev
(or XCB) package on Linux
Build environment[Xlib]: Requires xorg-dev
package
Build environment[XCB]: Requires libxcb1-dev
, libxcb-util-dev
, libxcb-keysyms1-dev
, and x11proto-dev
packages
Build environment[Wayland]: Requires libwayland-dev
and libxkbcommon-dev
packages
Target Environment: installed (latest) Vulkan capable drivers (to see anything)
Target Environment: GLFW(recommended), XCB, Xlib, or Wayland based windowing system
On Unix-like environment refer to
SDK docs
on how to set VULKAN_SDK
variable.
Adding VkSurface
support for other platforms should be straightforward using
the provided ones as a template for it.
file | description |
---|---|
doc/synchronizationTutorial.md | Short explanation of Vulkan synchronization in the context of trivial applications |
doc/Schema.pdf | Bunch of diagrams explaining the app architecture and synchronization in a graphical form |
external/glfw/ | GLFW git submodule |
src/HelloTriangle.cpp | The app souce code, including the main() function |
src/CompilerMessages.h | Allows to make compile-time messages shown in the compiler output |
src/EnumerateScheme.h | A scheme to unify usage of most Vulkan vkEnumerate* and vkGet* commands |
src/ErrorHandling.h | VkResult check helpers + VK_EXT_debug_utils extension related stuff |
src/ExtensionLoader.h | Functions handling loading of select Vulkan extension commands |
src/LeanWindowsEnvironment.h | Included conditionally by VulkanEnvironment.h and includes lean windows.h header |
src/Vertex.h | Just simple Vertex definitions |
src/VulkanEnvironment.h | Contains header configuration, such platform-specific as VK_USE_PLATFORM_* |
src/VulkanIntrospection.h | Introspection of Vulkan entities; e.g. convert Vulkan enumerants to strings |
src/Wsi.h | Meta-header including one of the platform-specific headers in WSI directory |
src/WSI/Glfw.h | WSI platform-dependent stuff via GLFW3 library |
src/WSI/Win32.h | Win32 WSI platform-dependent stuff |
src/WSI/Xcb.h | XCB WSI platform-dependent stuff |
src/WSI/Xlib.h | Xlib WSI platform-dependent stuff |
src/WSI/Wayland.h | Wayland WSI platform-dependent stuff |
src/WSI/private/ | Stuff the WSI headers need; currently just generated Wayland protocols |
src/shaders/hello_triangle.vert | The vertex shader program in GLSL |
src/shaders/hello_triangle.frag | The fragment shader program in GLSL |
.gitignore | Git filter file ignoring most probable outputs messing up the local repo |
.gitmodules | Git submodules file describing the dependency on GLFW |
CMakeLists.txt | CMake makefile |
CONTRIBUTING.md | Extra info about contributing code, ideas, and bug reports |
LICENSE | Copyright licence for this project |
README.md | This file |
You can change the application configuration by simply changing following
variables in HelloTriangle.cpp
.
config variable | purpose | default |
---|---|---|
appName |
Application name; might show up in title of the window | whatever it is in code |
debugSeverity |
Which kinds of debug message severites will be shown | WARNING | ERROR |
debugType |
Which kinds of debug message types will be shown | all types |
useAssistantLayer |
Enable Assistant Layer too when debugging (TODO: does not support new way of enabling) | false |
fpsCounter |
Enable FPS counter via VK_LAYER_LUNARG_monitor layer |
true |
initialWindowWidth |
The initial width of the rendered window | 800 |
initialWindowHeight |
The initial height of the rendered window | 800 |
presentMode |
The presentation mode of Vulkan used in swapchain | VK_PRESENT_MODE_FIFO_KHR 1 |
clearColor |
Background color of the rendering | gray ({0.1f, 0.1f, 0.1f, 1.0f} ) |
forceSeparatePresentQueue |
By default the app prioritizes single Graphics and Present queue. This will create separate queues for testing purposes. There are virtually no platforms currently that naturally have separate Present queue family. |
1 I preferred VK_PRESENT_MODE_IMMEDIATE_KHR
before but it tends to
make coil whine because of the extreme FPS (which could be unnecessarily
dangerous to the PCB in the long term).
First just get everything:
$ git clone --recurse-submodules https://github.com/krOoze/Hello_Triangle.git
In many platforms CMake style build should work just fine:
$ cmake -G"Your preferred generator"
or even just
$ cmake .
Then use make
, or the generated Visual Studio *.sln
, or whatever it created.
There are two cmake options (supplied by -D
):
WSI
-- set this toUSE_PLATFORM_GLFW
or anyVK_USE_PLATFORM_*_KHR
to select the WSI to be used. Default is GLFW.TODO
-- set this toOFF
to remove TODO messages during compilation.
You also might want to add -DCMAKE_BUILD_TYPE=Debug
.
The code base is quite simple and it can be built manually. It only assumes that
the src
folder is in the include path, that you link the GLFW dependency, and
that you compile the GLSL shader files into SPIR-V.
In Visual Studio you can simply import the code and add the things mentioned above. Either "console" or "window" subsystem is a valid choice on Windows.
In Linux distro you would do e.g.:
$ g++ --std=c++14 -Wall -m64 -D_DEBUG -DNO_TODO -I$VULKAN_SDK/include -I./src/ -o./HelloTriangle src/HelloTriangle.cpp -ldl -L$VULKAN_SDK/lib -lvulkan -lglfw
GLSL shaders can be compiled using glslc
from LunarG Vulkan SDK like so:
On Windows-like environment:
%VULKAN_SDK%/Bin/glslc -mfmt=c -o ./src/shaders/hello_triangle.vert.spv.inl ./src/shaders/hello_triangle.vert
%VULKAN_SDK%/Bin/glslc -mfmt=c -o ./src/shaders/hello_triangle.frag.spv.inl ./src/shaders/hello_triangle.frag
Or on Unix-like environment you would use just $VULKAN_SDK
instead:
$VULKAN_SDK/Bin/glslc -mfmt=c -o ./src/shaders/hello_triangle.vert.spv.inl ./src/shaders/hello_triangle.vert
$VULKAN_SDK/Bin/glslc -mfmt=c -o ./src/shaders/hello_triangle.frag.spv.inl ./src/shaders/hello_triangle.frag
There are annoying (on purpose) TODOs generated on build. They can be disabled
by defining NO_TODO
preprocessor macro.
Using GLFW is optional. You may choose another windowing platform by modifying
VulkanEnvironment.h
, or supplying it via preprocessor. By default, all
platforms use GLFW.
You just run it as you would anything else.
Esc does terminate the app.
Alt + Enter toggles fullscreen (might not work on some WSI
platforms).