Vulkan toy renderer/playground
This project is intended to be a toy rendering engine to familiarize myself with vulkan.
I also use it to test more modern C++ features such as coroutines and the executors proposal. As such, it uses features that are only supported in rather modern compilers.
-
descriptor set/shader uniforms abstraction
- basics demo done
- manage descriptors and sets via ResourceManager
- Images, Samplers, Buffers, DescriptorSets all managed
- define a global descriptor set 0 that is managed by cory itself
-
Render Graphs/Frame Graphs
- basic coroutine-based API and render pass resolution via graph search
- automatically create render passes and layouts
- perform automatic resource transitions
- actually execute render pass code that renders stuff
- implement a multi-pass example that reads from a texture
- vulkan object debug names set up
- restructure swapchain frame generation as a coroutine-based generator
- extend multi-pass to dynamic uniforms & interactivity
- proper allocation of transient textures from arena
- create AccessInfo templates for most common usages
- automatically figure out required image usage for a transient image
- extend transient resource system to buffers
- split barriers
- simplify / make more efficient the ShaderBindGroup (currently flushes too often, should only have to flush before submit?)
-
Window and event system
- basic mouse and kb event forwarding
- better abstraction/encapsulation
- design simple coroutine-based event system for "game" logic
-
Application-level memory management
- Use std::pmr more consistently to improve memory allocations
- introduce per-frame memory arena into
FrameContext - use std::pmr based allocator for Vulkan API calls
-
GameObject/Scenegraph system (Entities + Components, not full data-drive ECS)
- basic entity/component system
-
Shader System
- push constants
- On-the fly shader compilation using Slang
- shader hot-reloading
- shader reflection using SPIR-V Reflect
- shader compilation cache
- shader specialization constants
-
Debug drawing utilities
- Simple, immediate-mode debug drawing system for lines, shapes, text etc.
-
Parallel BMP Stack loading for large volumetric data sets (oVert)
- Implement a simple BMP loader uncompressed grayscale bmp
- Use a thread pool to load multiple BMP files in parallel
- Integrate loaded textures into the renderer and display them
- Figure out how to further optimize loader performance parallel performance (currently not saturating disk IO)
-
Basic coroutine-based framegraph concept/API draft
-
ImGui integration
-
Performance and Logging classes
-
The triangle!
-
Basic window and renderer infrastructure
-
KHR_dynamic_rendering
- Implement a simple Volume Raymarcher
- Extend usage of c++20 coroutines where meaningful
- use coroutines for framegraph execution
- use coroutines for "game" logic
- Multithreading?!
- Multithreaded framegraph recording?
- Offload resource creation (shaders/pipelines) to another thread (pool)
- explicit sync with queues where necessary
- texture uploads etc.
- C++ Modules (whenever cmake and compiler support actually catches up)
- Implement Monte Carlo Volume Raycasting (for medical volume rendering)
- Play around with ray tracing
- Play around with mesh shaders (cause they seem to be hot right now)
- Ideas around Engine structure and event handling basics from Hazel engine by TheCherno, greatly documented on his Youtube Channel
- Alexander Overvoorde's excellent Vulkan tutorial
- Brendan Galea's Vulkan Tutorial
- Tutorial on how to actually integrate imgui into a vulkan renderer based off of the vulkan-tutorial.com source code
- Framegraphs/Render graphs:
- Dynamic rendering:
For the "bigger" libraries, this project uses conan to manage the dependencies. The integration is transparent, which means that if you have a suitable conan installation, the packages should be downloaded and built automatically when you configure the CMake project. (after you have registered the corrade and magnum recipes, see below).
Cory also pulls in sources from some third-party libraries into this repository. They all live in the
subdirectory ThirdParty and are available under their respective license, included in the respecive directory or at
the top of the header files:
- some cmake files in /cmake are from https://github.com/Lectem/cpp-boilerplate, MIT License
- glm, https://github.com/g-truc/glm, MIT / Happy Bunny License
- stb_image, https://github.com/nothings/stb, MIT / Public Domain
- tinyobjloader, https://github.com/tinyobjloader/tinyobjloader, MIT License
- Modified
CameraManipulatorClass, https://github.com/KhronosGroup/Vulkan-Hpp/tree/master/samples/RayTracing, Apache 2.0 License - Dear ImGui Vulkan backend, https://github.com/ocornut/imgui/tree/master/backends, MIT License
- imGuIZMO.quat for rotation widgets https://github.com/BrutPitt/imGuIZMO.quat, BSD 2-clause License
- KDBindings, https://github.com/KDAB/KDBindings, MIT License
- Ported simpler_vulkan_synchronization by Tobias Hector, https://github.com/Tobski/simple_vulkan_synchronization/, MIT License -- this has been adapted to this project's conventions and interfaces, see Renderer/SimplerVulkanSynchronization
See conanfile.txt for the additional libraries and their exact versions used. I update them to their latest versions
sporadically, but there is of course always some flexibility in using different versions.
I'm currently building on MSVC 2022 and use several of the latest features, so you'll only be able to build this with a fairly recent compiler. While I generally try to stick with platform-independent code, I did not invest much time into actual testing with different platforms (compilers and/or drivers) - likely I'm already hitting some MSVC and NVidia-specific quirks that may make compiling/running the application difficult on other environments. I'm always interested in feedback on compatibility issues, but I can of course not promise to be able to fix anything.
That being said, to build and run the app, use the cbt tool from the repo root. It handles
configuration, building, testing, running, and tool setup in a consistent way.
# Configure once
python3 -m cbt configure --profile codex --build-type Debug
# Build
python3 -m cbt build --profile codex
# Run a target
python3 -m cbt run --profile codex SceneGraphDemo -- --help
# Run a single test (or regex)
python3 -m cbt test --profile codex "Smoketests.HelloTriangle"Please avoid calling cmake, ctest, or running binaries directly unless explicitly requested.
According to this very trustworthy-looking web source, Corynetes was the son of the roman god Vulcan. Also, something something coroutines.
- KHR_dynamic_rendering: used for implementing the framegraph
- EXT_debug_utils: validation stuff!
- KHR_synchronization2: better barriers
- EXT_device_memory_report: would be nice to get some insights on memory usage
- KHR_timeline_semaphore: semaphores with monotonically increasing counters, useful for e.g. parallel subsystems like gpu-physics running asynchronously to rendering
- EXT_mesh_shader: mesh shaders are the new hot thing, I should try at some point
- EXT_full_screen_exclusive: full screen stuff. maybe better handled through GLFW?