Canta is a Tolkien elvish word meaning shape/framework. This library acts as a framework for creating vulkan applications.
- Device creation.
- Resource management.
- Indexed ("bindless") resources.
- Automatic frame synchronisation.
- Render graph.
- Pipeline/Shader management.
- Included ImGui backend.
Simple graphics device creation.
auto device = canta::Device::create({
.applicationName = "hello world",
.enableMeshShading = false,
// ... enable other feature flags
});Includes a render graph to help with synchronisation dependencies between shader passes.
// Create graph
auto renderGraph = canta::RenderGraph::create({
.device = device.get(),
.name = "graph"
});
// Create graph resources
auto objectBuffer = renderGraph->addBuffer({
.size = sizeof(Object) * numObjects,
.name = "object_buffer"
});
auto backbuffer = renderGraph->addImage({
.width = 1920,
.height = 1080,
.format = canta::Format::RGBA8_SRGB,
.name = "backbuffer"
});
// Create graph passes
const auto objects = rendergraph->compute("run_objects", runPipeline)
.pushConstants(Write(objectBuffer))
.dispatchThreads(x, y).output<BufferIndex>();
const auto finalBackbuffer = renderGraph->compute("main_draw", drawPipeline)
.pushConstants(Write(backbuffer), Read(objects))
.dispatchThreads(x, y).output<ImageIndex>();
// Set output target
renderGraph->setRoot(finalBackbuffer);
// Compile and run
renderGraph.compile();
renderGraph.run({}, {}, false); // First arg is semaphores to wait on and second is semaphores to signal for use with frame sync, third is whether to run the graph asynchronously or not.
There are several ways to use shaders with canta. Either compiled and embedded through the build script or evaluated at runtime using a pipeline manager.
Shaders can be embedded into the binary using cmake functions included with the library. The function takes two named parameters. NAME which designates a namespace the shaders will be available under. And SHADERS which is a list of paths to shaders to embed.
embed_shaders(
NAME project_name
SHADERS path/to/shader/file.spv path/to/shader/file.slang
)Additionally, the included slang compiler can be used to build slang shaders at build time which can then be embedded into the binary.
compile_shaders(path/to/shader/file.slang path/to/shader/file1.slang)
embed_shaders(
NAME project_name
SHADERS ${COMPILED_SHADER_OUTPUTS}
)Once embedded the shader data is available in the embedded_shaders_${NAME}.h header file. The shader data is contained in a namespace NAME in variables named ${file_name}_${file_type}_embedded with file_type being either slang or spv. Embedded spirv compute shaders will also have a helper function generated which facilitates using the shader in a render graph. These function are named using the file name.
#include "embedded_shaders_PROJECT.h"
auto shader_data = project_name::file_slang_embedded;
auto computePass = project_name::file(x, y, z)(graph, push, constants, go, here, with, Read(and), Write(depenencies));Includes a pipeline manager which facilitates the creation and management of shaders and pipeline objects. Shaders/Pipelines are cached after the first use so passing the same arguments to getShader/getPipeline will return the same object.
auto pipelineManager = canta::PipelineManager::create({
.device = device.get();
.rootPath = "assets/shaders"
});
// Create and cache shader object
auto shader = pipelineManager.getShader({
.path = "path/to/shader",
.stage = canta::ShaderStage::COMPUTE,
.name = "compute_shader"
});
// Create and cache pipeline.
auto pipeline = pipelineManager.getPipeline({
.vertex = {
.path = "path/to/vertex/shader",
.name = "vertex_shader",
.entry = "main"
},
.fragment = {
.path = "can/also/just/provide/a/path/for/the/shader.slang",
.entry = "fragmentMain"
},
.name = "raster_pipeline"
});- SDL2
- Vulkan
- spdlog
- Ende
- volk
- VulkanMemoryAllocator
- Tessil/robin-map
- SPIRV-Cross
- slang
- imgui
- rapidjson
- imnodes
sudo pacman -Syu libsdl2
sudo apt install libsdl2-dev libspdlog-dev libvulkan-dev
To build library standalone.
git clone https://git.melamar.xyz/olorin99/Canta
cd Canta
mkdir build
cd build
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --target Canta -j8To include in cmake project.
FetchContent_Declare(
Canta
GIT_REPOSITORY https://git.melamar.xyz/olorin99/Canta
GIT_TAG "main"
)
FetchContent_MakeAvailable(Canta)