Skip to content

vKexterPLv/Vulkan-Core-Kit

Repository files navigation

V C K

Vulkan Core Kit. One header. You write the renderer. VCK shuts up about everything else.

not an engine · no scene graph · no material system · you own the frame

Windows build Platforms C++17 Vulkan Docs License Changelog


#include "VCK.h"   // pulls expansion + execution

Gets you the core Vulkan objects, expansion (textures, meshes, descriptors, mipmaps, AA), an optional memory manager (VMM), and an optional frame scheduler with a CPU job graph + GPU submission batcher.

v0.3 highlights:

  • Cross-platformVCK::Window + VCK_PLATFORM_* on Windows / Linux / macOS. No raw GLFW or Win32 in user code.
  • Live resize is one callVCK::HandleLiveResize(window, ...) handles 720p → 4K. The scheduler-aware overload drains via FrameScheduler::DrainInFlight() instead of vkDeviceWaitIdle.
  • Timeline semaphoresFrameScheduler signals a monotonic per-slot value, BeginFrame waits with one vkWaitSemaphores. Fence fallback when the timeline ext is absent.
  • Dedicated compute / transfer queues — picked when the vendor exposes them. VMM staging runs on transfer with release/acquire ownership barriers back to graphics (spec §7.7.4).
  • Secondary command buffersAllocate/Begin/End/ExecuteSecondaries for record-then-execute.
  • Ergonomic shadersVCKMath, VertexLayout, PushConstants, Primitives::Cube/Plane/Sphere/Quad/Line. Cube setup: ~40 lines → one call.
  • AA decision treecfg.aa.technique = Auto picks at Swapchain::Initialize (VRAM tier → forward path → motion vectors). MSAA / A2C / SampleRate ship; FXAA / SMAA / TAA / TAAU names are returned to the renderer (the cookbook has the shaders).
  • Structured loggingVCKLog::{Info,Notice,Warn,Error} with console-spam dedup. VK_CHECK routes failures to Error.
  • 24 design rules — fail loud, frame is the unit of truth, VCK.h is the surface, every public class has an example, etc. See docs/Design.md.
  • Cookbook — recipes for the things VCK refuses to ship (image / OBJ loading, ImGui, FXAA/SMAA/TAA, compute particles, shadows, PBR/IBL, deferred, bloom, hot-reload, picking).

Layers

 layers/core/            VCKCrossplatform + Vulkan*.{h,cpp}
    ↓                    window, instance, device, swapchain, pipeline, command, sync
 layers/expansion/       VCKExpansion.{h,cpp}
    ↓                    textures, meshes, samplers, descriptors, mipmaps
                         + HandleLiveResize (base + depth)
 layers/execution/       VCKExecution.{h,cpp}
    ↓                    FrameScheduler, JobGraph, TimelineSemaphore,
                         DebugTimeline, QueueSet, GpuSubmissionBatcher,
                         + timeline-aware HandleLiveResize
 layers/vmm/             VulkanMemoryManager.{h,cpp}  (optional)
    ↓                    staging ring, transient pool, persistent registry
 Your renderer

Everything lives in namespace VCK. LogVk and VK_CHECK are at global scope so any TU can use them without a using declaration. The single source of truth for the API surface is the doc block at the top of VCK.h — layer files carry only a one-line "what am I" comment.

One-hour tour

  1. Build one example. cd example && build.bat → pick [1] (RGBTriangle). That's main.cpp + App.h + App.cpp + assets/ — the whole onboarding surface. Full build steps: docs/Build.md.
  2. Read Hello VCK below. ~50 lines, one TU, no hidden state. Walks the entire init chain → frame loop → shutdown.
  3. Skim VCK.h top-to-bottom. Big ASCII banners split it into CLASSES / IMPLS. Every class has a doc block explaining what it owns, who calls it, and the init/shutdown order.
  4. Decide what you want next:
  5. Tune with VCK::Config (below) when you need a different present mode, MSAA, or more frames in flight.

Total surface: one header, everything in namespace VCK, no opaque ownership. When in doubt, the raw-handle overload (dev.Initialize(VkInstance, VkSurfaceKHR), etc.) is always still there for full manual control.

Hello VCK

Minimal program that stands up a window, the core stack, and clears the swapchain to a colour every frame through FrameScheduler. The full three-file version lives in example/HelloExample/.

#include "VCK.h"      // pulls in VCK::Window, the core, expansion, everything

int main()
{
    // window (cross-platform facade - no raw GLFW/HWND in user code)
    VCK::Window            win;
    VCK::WindowCreateInfo  wci;
    wci.width = 800; wci.height = 600; wci.title = "Hello VCK";
    wci.resizable = true;
    win.Create(wci);

    // core
    VCK::VulkanContext   ctx;
    VCK::VulkanDevice    dev;
    VCK::VulkanSwapchain sc;
    VCK::VulkanCommand   cmd;
    VCK::VulkanSync      sync;

    ctx.Initialize (win, "hello");
    dev.Initialize (ctx);
    sc .Initialize (dev, ctx, win.GetWidth(), win.GetHeight());
    cmd.Initialize (dev);
    sync.Initialize(dev);

    // execution layer (optional)
    VCK::FrameScheduler sched;
    VCK::FrameScheduler::Config cfg;
    cfg.policy = VCK::FramePolicy::Pipelined;
    sched.Initialize(dev, cmd, sync, cfg);

    while (!win.ShouldClose())
    {
        win.PollEvents();
        VCK::Frame& f = sched.BeginFrame();

        uint32_t imageIndex = 0;
        vkAcquireNextImageKHR(dev.GetDevice(), sc.GetSwapchain(),
                              UINT64_MAX, f.ImageAvailable(),
                              VK_NULL_HANDLE, &imageIndex);

        // ... begin render pass, clear, end render pass on f.PrimaryCmd() ...

        // One-liner — wires ImageAvailable / RenderFinished on the frame's
        // own semaphores and submits f.PrimaryCmd() on the graphics queue.
        f.QueueGraphics();

        sched.EndFrame();

        VkSemaphore     renderDone = f.RenderFinished();
        VkSwapchainKHR  sw         = sc.GetSwapchain();
        VkPresentInfoKHR p{ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR };
        p.waitSemaphoreCount = 1;
        p.pWaitSemaphores    = &renderDone;
        p.swapchainCount     = 1;
        p.pSwapchains        = &sw;
        p.pImageIndices      = &imageIndex;
        vkQueuePresentKHR(dev.GetGraphicsQueue(), &p);
    }

    sched.Shutdown();
    sync.Shutdown(); cmd.Shutdown(); sc.Shutdown(); dev.Shutdown(); ctx.Shutdown();
    win.Destroy();
}

Optional VCK::Config

Every Initialize(...) in the core has a zero-arg form and an overload that takes a const VCK::Config& — one struct, nested by class. Pass only the knobs you care about; everything else uses sensible defaults matching the zero-arg behaviour.

VCK::Config cfg;
cfg.context.appName        = "Hello VCK";
cfg.context.enableValidation = true;                             // debug only
cfg.device.preferDiscreteGpu = true;
cfg.swapchain.presentMode  = VCK::PresentMode::Mailbox;          // Auto | Fifo | Mailbox | Immediate
cfg.swapchain.imageCount   = 3;                                  // 0 = minImageCount + 1
cfg.swapchain.msaaSamples  = VCK::MSAA_AUTO;                     // 0 = pick from device; or VK_SAMPLE_COUNT_{1,2,4,8}_BIT
cfg.aa.technique           = VCK::AATechnique::Auto;             // Auto | Off | MSAA | MSAA_A2C | SampleRate | FXAA | ...
cfg.aa.forwardRenderer     = true;                               // detector input
cfg.aa.supportsMotionVectors = false;                            // detector input
cfg.debug                  = false;                              // true = VCKLog Info lines visible
cfg.sync.framesInFlight    = 3;                                  // clamped to MAX_FRAMES_IN_FLIGHT

ctx.Initialize (window, cfg);
dev.Initialize (ctx,    cfg);
sc .Initialize (dev, ctx, window.GetWidth(), window.GetHeight(), cfg);
sync.Initialize(dev,  cfg);
cmd.Initialize (dev,  cfg);
pipe.Initialize(dev, sc, shaders, vi);    // pulls msaaSamples from the swapchain

Mailbox requests fall back to FIFO if the driver doesn't expose it, and framesInFlight is clamped to the compile-time upper bound VCK::MAX_FRAMES_IN_FLIGHT (= 8). v0.3 enables VK_KHR_timeline_semaphore at device-create time when the adapter supports it (functionally every modern GPU); FrameScheduler uses it by default.

Examples

Thirteen runnable examples in example/. All follow a 3-file + assets/ layout (main.cpp + App.h + App.cpp + assets/), all use the cross-platform VCK::Window facade and VCK::HandleLiveResize (so resizing from 720p to 4K is handled in-library). Build with:

  • Windows: example/build.bat (CMake + Ninja under the hood; cl from a Developer Cmd Prompt or MinGW g++ on PATH)
  • Linux / macOS: example/build.sh (CMake + Ninja under the hood; g++ / clang++ from PATH)
  • Anywhere: cmake -S example -B build -G Ninja && cmake --build build -j (the canonical command - build.bat / build.sh are thin wrappers around it)
# Example Demonstrates
1 RGBTriangle coloured triangle, live resize — raw core
2 MipmapExample texture upload + mip generation + sampling — raw core
3 VMMExample VMM persistent / transient / staging — raw core + VMM
4 SecondaryCmdExample secondary command buffers + scheduler-aware resize (v0.3)
5 DebugTimelineExample span recorder + Dump every 120 frames — debug tooling
6 DebugShowcaseExample every VCKLog level, dedup, VK_CHECK path
7 AAShowcaseExample DetectRecommendedAA matrix + live auto-pick — expansion
8 JobGraphExample CPU task graph with dependencies — execution layer
9 SubmissionBatchingExample 2 cmd buffers → 1 vkQueueSubmit
10 TimelineExample TimelineSemaphore + DependencyToken
11 SchedulerPolicyExample live-swap Lockstep / Pipelined / AsyncMax
12 HelloExample smallest FrameScheduler program — mostly VCK
13 EasyCubeExample Primitives::Cube + VertexLayout + PushConstants + VCKMath — peak ergonomic

Full walkthroughs: docs/Examples.md.

Build

Windows — CMake + Ninja picks whichever C++ compiler is on PATH. Run from a Developer Cmd Prompt and cl is used; otherwise MinGW-w64 g++ (MSYS2's C:\msys64\mingw64\bin) is picked up automatically:

cd example
build.bat                    :: interactive menu, picks compiler from PATH
build.bat A                  :: build all 13 examples
build.bat T                  :: build + run the R14 unit-test harness
:: or skip the wrapper entirely:
cmake -S . -B build -G Ninja
cmake --build build -j --target examples

Linux / macOS (pkg-config vulkan glfw3 + glslangValidator + g++ or clang++):

cd example
./build.sh

Both scripts share the same [1]-[13] / [A] / [T] / [0] menu and print a diagnostic if tools or dependencies are missing. [T] builds and links the R14 unit-test harness against the lib-once vck.lib / libvck.a and runs it. Full step-by-step: docs/Build.md.

Both scripts use a lib-once compile model (PR #7): the VCK static library compiles once into build/vck.lib (cl) or build/libvck.a (gcc/clang) and every example links against it (main.cpp + App.cpp only). Build-all wall-clock on a modern 8-core machine: ~30-40 s on Linux/macOS, ~2-3 min on Windows MSVC /MP, ~3-4 min on MinGW.

Documentation

The README is deliberately short. Everything else lives under docs/ — these files mirror the GitHub Wiki layout, so the maintainer can push them to the *.wiki.git repo at any time.

Page Covers
docs/Home.md index + layer map
docs/Overview.md one-page tour: what VCK is / gives / never takes, modern v0.3 optimisations, why it's fresh
docs/Core-API.md VCK.h — Context / Device / Swapchain / Pipeline / Command / Sync / Buffer / Image
docs/Expansion-API.md VCKExpansion.h — framebuffers, depth, samplers, textures, meshes, descriptors, mipmaps
docs/Execution-Layer.md FrameScheduler, JobGraph, GpuSubmissionBatcher, BackpressureGovernor, TimelineSemaphore, QueueSet, DebugTimeline
docs/VMM.md VulkanMemoryManager — lifetimes, strategies, staging
docs/Examples.md per-example walkthrough
docs/Build.md Windows / Linux / macOS: Vulkan SDK + GLFW + build.bat / build.sh
docs/Design.md design rules, status, caveats, roadmap

Contributing

PRs welcome. Read CONTRIBUTING.md for the 22-rule architectural contract, commit style, and branching workflow. Small, focused diffs preferred; new public API goes in VCK.h (the single source of truth).

Changelog

See CHANGELOG.md for the per-version list of added, changed, and removed items. Format: Keep a Changelog. Versioning: SemVer.

License

MIT — vendored third-party sources in vendor/ keep their own licenses (Apache 2.0 for Vulkan-Headers, MIT for VMA, zlib/libpng for GLFW). See the LICENSE file for the full list.

About

VCK — small, no-magic Vulkan kit for Windows / Linux / macOS. Cross-platform window, live resize, AA auto-detect, structured logging, optional frame scheduler + VMM. One header, one namespace, every raw Vk handle exposed. Not an engine — you own the frame.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Contributors