Skip to content

Latest commit

 

History

History
348 lines (292 loc) · 37.1 KB

File metadata and controls

348 lines (292 loc) · 37.1 KB

Changelog

All notable changes to VCK are documented here. Format: Keep a Changelog. Versioning: SemVer.

[0.5.1] – 2026-05-31

Post-release patch that fixes CI failures introduced by the v0.5.0 merge, corrects two design-rule violations in the new HotReload class, and standardises the factory-method naming convention across the library. No new public API surface. No behaviour change for code that was compiling correctly against v0.5.0.

Changed

  • VulkanImage::Create(…)VulkanImage::Initialize(device, w, h, format, usage, aspect[, samples])Create was an inconsistent outlier; every other VCK class uses Initialize. All 27 call sites updated (core headers, expansion, examples). (breaking within 0.5.x)
  • VulkanSampler::CreateLinear(device) / CreateNearest(device)VulkanSampler::Initialize(device, filter = LINEAR, mipMode = LINEAR) — single entry point, filter and mip mode are explicit parameters. (breaking within 0.5.x)
  • Window::Create(info)Window::Initialize(info) — naming parity with the rest of the library. (breaking within 0.5.x)
  • HotReload::Initialize gains required std::function<void()> drainFn final parameter — callers supply a lambda (e.g. [&]{ scheduler.DrainInFlight(); }) that retires in-flight GPU work before each pipeline rebuild. The expansion layer never imports execution types directly (R2). Stored as m_DrainFn; cleared in Shutdown. (breaking within 0.5.x — no examples called HotReload::Initialize in v0.5.0)

Fixed

  • R2 layering violation in HotReload — v0.5.0 shipped HotReload::Initialize with a FrameScheduler& parameter, which pulled an execution-layer type into the expansion-layer header. Parameter removed; drain responsibility delegated to the caller via drainFn.
  • R4 violation in HotReload::Tick — the interim fix for the R2 violation replaced FrameScheduler::DrainInFlight() with vkDeviceWaitIdle, which is banned on the runtime hot path. Now calls m_DrainFn() instead.
  • DynamicRenderingExample compile errorsVulkanSwapchain::Config / VulkanDevice::Config (do not exist) replaced with VCK::Config; non-existent field pipeCfg.rendering.mode removed.
  • BindlessExample compile errorsVulkanDevice::ConfigVCK::Config; GetLayout()GetPipelineLayout().
  • OffscreenTarget::Initialize — was calling the non-existent VulkanImage::Config struct and VulkanImage::Create(). Replaced with the correct VulkanImage::Initialize(device, w, h, format, usage, aspect) signature.
  • OffscreenTargetExamplesampler.CreateLinear(device) updated to sampler.Initialize(device) following the naming-convention rename.
  • Post-0.5.0 audit sweep (B1–B5, C1–C10, D1–D10) — compiler-warning clean-up (B), correctness fixes on newly-added code paths (C), and design-rule alignment pass (D) applied 2026-05-20.

0.5.0 – 2026-05-18

Added

  • RenderingMode::Dynamic end-to-end: DynamicRenderingExample shows vkCmdBeginRendering / vkCmdEndRendering with barrier transitions
  • cfg.device.enableBindless fully wired: VulkanDescriptorAllocator::InitializeBindless() + WriteBindless() + BindlessExample
  • VK_KHR_synchronization2: all barriers use vkCmdPipelineBarrier2 / VkImageMemoryBarrier2
  • FrameData<T> per-frame typed resource ring [23]
  • RenderGraph declarative barrier-aware skeleton [24]
  • VCK::HotReload [31] — drives ShaderWatcher→DrainInFlight→Reinitialize→Recreate
  • VCK::OffscreenTarget [32] — VulkanImage + VkRenderPass/VkFramebuffer for render-to-texture
  • VCK::FullscreenPass [33] — fullscreen triangle with sampler input
  • VulkanPipeline::Reinitialize for hot-reload + live-resize
  • FrameScheduler::SlotCount() getter
  • VulkanSwapchain::GetImage(uint32_t) / GetImageView(uint32_t) index accessors
  • VulkanDescriptorAllocator::InitializeBindless / WriteBindless / GetBindlessSet / GetBindlessLayout
  • DebugTimeline::InitQueryPool / BeginGpuSpan / EndGpuSpan / ResolveGpuSpans — GPU timestamp pipeline
  • DynamicRenderingExample, BindlessExample, OffscreenTargetExample, RenderGraphExample
  • ASan + UBSan CI job linux-sanitize

Changed

  • VulkanDescriptorAllocator::Initialize: std::initializer_list<PoolSize>const std::vector<PoolSize>& (MSVC ABI fix)
  • VulkanDevice R23 notice updated to point at InitializeBindless
  • VCK.h expansion header now covers [1]-[12] + [26]-[36]
  • VCK.h example count: 13 → 14; actual dirs now 18

Fixed

  • Stale QueueSet [16] and TimelineSemaphore [14] comments in VCKExecution.h
  • ShaderWatcher debug-only warning when instantiated outside debug mode
  • VulkanDescriptorAllocator::Shutdown now destroys m_BindlessLayout

0.4.0 - 2026-04-27

Added

  • Shader tooling layer (5 new expansion classes, PR #10). A grouped layer that owns the shader-side ceremony so users never write their own SPIR-V loaders, hot-reload polling, specialization constant buffers, or per-stage descriptor declarations. All five live in layers/expansion/VCKExpansion.{h,cpp} under namespace VCK and follow the standing rules — zero state until first call (R19), escape hatches everywhere (R9), VCKLog::Error on every failure (R14), VCKLog::Notice on every behavioral decision (R23), no GPU state held except the descriptor layout BuildSetLayout returns to the caller (R10).
    • ShaderLoaderLoadFromFile(path, stage) reads pre-compiled .spv. LoadFromGLSL(glslPath, stage) is a debug-only helper that shells out to glslangValidator on PATH. GetShaderInfo() produces a ready-to-pass VulkanPipeline::ShaderInfo. GetSpirv(stage) exposes the raw word-vector.
    • ShaderWatcherWatch(path, stage) registers a .spv and stores its last_write_time. HasChanged() polls all watched files (one timestamp compare per file, never throws). Reload() rereads the SPIR-V; the user drives the pipeline rebuild + framebuffer recreate. Conceptually debug-only.
    • SpecConstants — builder around VkSpecializationInfo + VkSpecializationMapEntry. Set(constantID, value) overloads for uint32_t / int32_t / float / bool (bool stored as 0/1 uint32). Re-Set on the same constantID overwrites in place when sizes match, otherwise the data buffer is rebuilt and downstream offsets shift accordingly. GetInfo() returns nullptr when empty.
    • ShaderStage — pure-data per-stage declaration. Vertex() returns VertexLayout&, Push() returns PushConstants&, Uniform/Sampler/Storage(set, binding) declare descriptor bindings. No GPU objects.
    • ShaderInterface — merges multiple ShaderStages. VertexInput() pulls Bindings[0] / Attributes[0] from the vertex stage. PipelineConfig() pre-fills pushConstantRanges from the merged push block. BuildSetLayout(device, setIndex) returns a caller-owned VkDescriptorSetLayout. Push() returns the shared push block. Warns via VCKLog::Warn when two stages declare push blocks of different sizes.
    • ApplyToConfig(spec, cfg) free function — convenience for wiring one SpecConstants into both vert + frag fields of VulkanPipeline::Config.
  • PushConstants::Declare(name, type, count) — array overload, reserves count * sizeof(type) bytes.
  • PushConstants::SetRaw(name, data, size) — typed-Set escape hatch. Returns false + VCKLog::Error on unknown name or size mismatch.
  • VulkanPipeline::Config::vertSpecialization / fragSpecializationconst VkSpecializationInfo*, default nullptr. CreateGraphicsPipeline plumbs them into VkPipelineShaderStageCreateInfo::pSpecializationInfo for both stages.
  • VCK.h class index extended to 20 expansion classes ([26]–[30]).

Notes

v0.4.0 is a feature release — minor SemVer bump because the shader tooling adds new public surface but does not change any existing class signature, behavior, or example. CI green on Linux / macOS / Windows MinGW / Windows MSVC at merge.

0.3.3 - 2026-04-27

Fixed

  • tests/test_r11_r12_reliability.cpp — direct include of layers/execution/VCKExecution.h. That header forward-uses VulkanDevice / VulkanCommand / VulkanSync without including their core headers, so it only compiles when the umbrella has already pulled them in. Switched the include to VCK.h to match the working tests. CI broke on all 4 jobs (Linux / macOS / Windows MinGW / Windows MSVC) on the post-merge run of v0.3.2.
  • tests/test_r19_r15_r16_cost_scope.cpp — used VCK::Test::LogCapture without vck_log_capture.h. Added the include.
  • tests/test_vckmath.cppMat4 access mismatch. Mat4 stores float m[16] flat (column-major) with an At(row, col) accessor; the tests indexed it as m[col][row]. Switched to At(row, col).
  • tests/test_vckmath.cpplookat_z_axis_points_to_target asserted positive view-space Z. VCK is right-handed (the third row of LookAt negates f, matching the Perspective convention which negates z into w), so a target one unit ahead at world (0, 0, -1) lands at view-space z = -1. Fixed assertion.

Notes

v0.3.3 is a test-harness fix release on top of v0.3.2 — no library code changed, no behaviour change. If your tree was on v0.3.2 with green CI on PR #8, you don't need to take this; it only matters for the maintainer's a9f3e92 "Moar tests" commit that landed post-merge.

0.3.2 - 2026-04-27

Fixed

  • VMM SubmitStagingCmd — unchecked vkEndCommandBuffer. If End failed, the staging cmd was malformed, the next vkQueueSubmit would VUID-fail, AND any pending acquire barriers would issue layout transitions against resources still in UNDEFINED (the release halves never actually ran). VUID-VkImageMemoryBarrier-oldLayout-01197. Now bails with cmd-buffer free + drops m_PendingAcquire{Buffers,Images}.
  • VMM cross-family acquire path — unchecked vkBeginCommandBuffer / vkEndCommandBuffer. Recording into a not-begun cmd is undefined; submitting a not-ended cmd is a VUID violation. Both now VK_CHECK and bail with cmd-free + pending-acquire drop on failure.
  • VMM cross-family acquire path — fence path could silently skip the submit. If vkCreateFence or the fenced vkQueueSubmit failed, the acquire barriers never ran, leaving resources stranded in "released to graphics family with no matching acquire" state (UB per spec §7.7.4). Added a vkQueueWaitIdle-based fallback so the acquire submit always actually runs (matches the staging fallback).
  • Swapchain CreateSwapchain — unchecked vkCreateSwapchainKHR and both vkGetSwapchainImagesKHR. Continuing past these on failure left a half-built swapchain; now returns false on device-lost so the caller can teardown (rule 14).
  • VulkanOneTimeCommand::Begin — leaked the allocated cmd buffer when vkBeginCommandBuffer failed. m_Cmd stayed populated so the caller couldn't tell Begin failed; a later End() would VUID-fail on a never-begun cmd, or never get called and the allocation leaked until pool teardown. Free + zero m_Cmd on Begin failure.

Build

  • .spv outputs no longer tracked. glslangValidator regenerates them on every build and bytes differ across glslang versions, so tracking them dirtied every local build against a CI-built tree. Added to .gitignore.

Documentation

  • De-AI rewrite pass. Every comment, doc, README, and CONTRIBUTING that read like marketing copy got the AI tells removed (no more "leverages", "seamlessly", "robust", "this ensures"). Voice is terser, comments explain why not what, README leads with a 3-line elevator pitch, CONTRIBUTING has opinions. Technical accuracy preserved; only the voice changed.
  • CHANGELOG, VCK.h header block, and docs/*.md resynced to v0.3.2 state.
  • Wiki tarball rebuilt: VCK.wiki.v0.3.2.tar.gz.

0.3.1 - 2026-04-27

Build (cmake migration, PR #7)

  • CMake + Ninja replaces build.bat / build.sh as the canonical build path. example/CMakeLists.txt is now the single source of truth for all 4 platforms (Windows MinGW, Windows MSVC, Linux, macOS). Auto-detects cl from a Developer Cmd Prompt or g++ / clang++ from PATH — no --toolchain flag.
  • Lib-once compile model. All 12 VCK sources compile once into vck.lib / libvck.a; the 13 example exes + the R14 test exe link against it. Eliminates 143 redundant TU recompilations. Wall-clock cold build-all on a modern 8c box: Linux/macOS ~30-45s (was 10-12 min), Windows MSVC ~1-2 min, Windows MinGW ~2-3 min.
  • Vulkan-Headers via FetchContent. CMakeLists.txt fetches the vulkan-sdk-1.4.321.0 tag itself, so the vk_video/*.h gap on Ubuntu 22.04 (which ships 1.3.x) is gone. CI no longer needs the manual sparse-checkout dance.
  • R14 unit test harness (tests/). Header-only assertion micro-framework, no GoogleTest dep. Asserts every Initialize() failure returns false AND emits exactly one VCKLog::Error. Wired through ctest. 14/14 pass on all 4 platforms.
  • build.bat / build.sh are now thin wrappers around cmake --build that preserve the interactive [1-13/A/T/0] menu UX.

Added

  • CI matrix: Linux + macOS jobs.github/workflows/build.yml now also runs on ubuntu-latest (apt: libvulkan-dev libglfw3-dev vulkan-tools glslang-tools pkg-config g++, ./build.sh A) and macos-latest (brew: vulkan-headers vulkan-loader glfw glslang molten-vk pkg-config, CXX=clang++ ./build.sh A). The Windows job (build.bat [A] on MinGW + LunarG SDK) is unchanged and remains the canonical platform; Linux + macOS catch POSIX regressions in VCK::Window / VCKCrossplatform / build.sh that the Windows runner can't.
  • Design rule R23 — Extension transparency — every instance- / device-level extension VCK enables on the user's behalf is announced via VCKLog::Notice("Context", ...) / VCKLog::Notice("Device", ...) at init, including the extension name, the support verdict from the driver, and the fallback path. The user can grep the init log for ext and see exactly what's bound to the device.
  • Design rule R24 — cfg is the contract — every behavioural difference VCK can express that the user can reasonably want to choose between lives in cfg. Litmus test: "If it changes how the user writes their renderer → cfg. If it changes how VCK works underneath → silent bundle." Codified in docs/Design.md together with R23 and the new six-category index (Explicitness / Ownership / Synchronisation / Cost & Scope / Reliability / Transparency).
  • Silent extension bundle (R24 silent path, R23 logged)VulkanDevice::CreateLogicalDevice now probes for and enables the following on-demand when the device advertises them, with one Notice line per result: VK_KHR_synchronization2, VK_KHR_buffer_device_address, VK_EXT_memory_budget, VK_EXT_device_fault, VK_KHR_present_wait, VK_KHR_present_id. No public API surface; symbols become reachable for v0.4 use sites (sync2 in FrameScheduler, BDA in VMM, memory_budget polling in DebugTimeline, present_wait / present_id pacing in FrameScheduler).
  • cfg extension knobs (R24 user-visible path, R23 logged)
    • cfg.rendering.mode = RenderingMode::{Classic, Dynamic}Dynamic requests VK_KHR_dynamic_rendering and announces it; the dynamic-rendering codepath itself ships in v0.4, today the request is acknowledged with a fallback Notice and rendering stays Classic.
    • cfg.device.enableBindlesstrue requests VK_EXT_descriptor_indexing and announces it; bindless descriptor helpers (DescriptorPool::AddBindlessSet, VulkanPipeline::EnableBindless) ship in v0.4.
    • cfg.swapchain.presentMode = PresentMode::FifoLatestReady — selects VK_PRESENT_MODE_FIFO_LATEST_READY_EXT when VK_EXT_present_mode_fifo_latest_ready is advertised, otherwise falls back to FIFO with a Notice (rule 23 — never silently substitute a present mode).

Changed

  • Example menu reordered low → high VCK assistexample/build.bat and example/build.sh now present examples in tiers (raw core → debug + tooling → expansion → execution layer → mostly VCK) so the menu narrates the design surface from "you write everything" to "VCK does the boring parts". New numbering: [1] RGBTriangle, [2] MipmapExample, [3] VMMExample, [4] SecondaryCmdExample, [5] DebugTimelineExample, [6] DebugShowcaseExample, [7] AAShowcaseExample, [8] JobGraphExample, [9] SubmissionBatchingExample, [10] TimelineExample, [11] SchedulerPolicyExample, [12] HelloExample, [13] EasyCubeExample. No example code or behaviour changes — menu, dispatch, build-all, and docs/Examples.md reflect the new ordering. Historical [#] references in the v0.3.0 / v0.2.x sections below are kept as shipped at the time.
  • Cookbook expanded to 24 recipes — added recipes 12-24 covering compute dispatch, GPU particles, indirect draw, async compute, shadow mapping, skybox / cubemap, PBR Cook-Torrance + IBL, deferred shading, HDR + tonemapping, bloom, shader hot-reload, GPU picking, and frustum culling. Cookbook now covers most rule-16 gaps (things VCK explicitly refuses to ship but every renderer ends up needing). Doc-only.
  • Linux + macOS build noise silencedexample/build.sh now compiles with -w -Werror=return-type (matching build.bat's silent-on-warnings behaviour); VMA single-header impl, GLFW Cocoa deprecations on macOS, and vulkan_core.h -Wmissing-field-initializers no longer surface as user-visible warnings. CI Linux + macOS jobs gain apt-get -qq / brew install -q flags so the workflow log isn't dominated by Get: / Setting up: / Suggested: lines from package install.

0.3.0 - 2026-04-26

v0.3 is a synchronisation-layer release. The runtime no longer calls vkDeviceWaitIdle outside Shutdown; frame retirement is consolidated on one per-scheduler timeline semaphore (with a fence fallback when the device doesn't expose the feature); VMM staging gets its own transfer-family command pool with release/acquire ownership barriers; swapchain recreate is scheduler-aware; and secondary command buffers are supported.

Added

  • Dedicated compute + transfer queuesVulkanDevice::FindQueueFamilies now picks dedicated compute-only and transfer-only families where the vendor exposes them (AMD / NVIDIA almost always; Intel often does not). VulkanDevice::GetComputeQueue() / GetTransferQueue() return the dedicated VkQueues (rule 9 escape hatch). Fallback to the graphics queue is logged via VCKLog::Notice when separate families aren't available. Thread safety: different VkQueues = different external-sync scopes per rule 18 — callers can submit graphics + compute in parallel without locking.
  • Timeline semaphore feature enableVulkanDevice::Initialize chains VkPhysicalDeviceTimelineSemaphoreFeatures into VkDeviceCreateInfo::pNext when the adapter supports it (Vulkan 1.2+, functionally every modern GPU). VulkanDevice::HasTimelineSemaphores() exposes the capability to the rest of the library. TimelineSemaphore::Initialize now returns true on supporting adapters instead of silently failing.
  • Scheduler-owned timelineFrameScheduler allocates one TimelineSemaphore at Initialize (gated on cfg.enableTimeline and device.HasTimelineSemaphores() — rule 19, zero cost when disabled). EndFrame signals a monotonically increasing per-slot value (m_SlotTimelineValue[slot] = ++m_NextTimelineValue). RetireCompletedFrames uses one vkGetSemaphoreCounterValue call instead of N vkGetFenceStatus calls (O(1) device chatter). New public FrameScheduler::FrameTimeline() + FrameScheduler::SlotToken(slot) expose the timeline to external waiters.
  • FrameScheduler::DrainInFlight() — waits on the scheduler's own in-flight work (timeline when active, per-slot fences otherwise) without touching vkDeviceWaitIdle. Replaces the global device wait on window resize.
  • Scheduler-aware HandleLiveResize overloadVCK::HandleLiveResize(window, swapchain, framebuffers, pipeline, scheduler [, depth]) drains the scheduler and recreates the swapchain without a global wait. The old (window, device, ...) overload remains available for scheduler-free code.
  • VMM release/acquire ownership barriersVulkanStagingAllocator records a release barrier on the transfer queue, waits on the per-submit fence, then records an acquire barrier on the graphics queue before first use. Preserves async-upload on dedicated transfer families without violating Vulkan §7.7.4 ownership rules on VK_SHARING_MODE_EXCLUSIVE resources. CPU-serialised for v0.3; a semaphore-driven async acquire can follow in v0.4.
  • Secondary command buffer APIVulkanCommand::AllocateSecondary() / FreeSecondary(cb) / BeginSecondary(cb, inheritance, extraFlags = 0) / EndSecondary(cb) / static ExecuteSecondaries(primary, cbs, count). BeginSecondary sets VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT by default; callers may OR in ONE_TIME_SUBMIT / SIMULTANEOUS_USE via extraFlags. Rule 18 (no internal lock) — callers serialise multi-threaded allocation themselves.
  • New example [13] SecondaryCmdExample — records the RGB triangle's draw in a per-slot secondary, primary opens the render pass with VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS and dispatches it via vkCmdExecuteCommands. Exercises the secondary-command API plus the scheduler-aware HandleLiveResize overload. Rule 20.

Changed

  • Per-submit fence in VMM stagingVulkanStagingAllocator::SubmitStagingCmd no longer calls vkQueueWaitIdle; it creates a one-shot VkFence, submits with it, and vkWaitForFences / destroys on the CPU side (rule 4 allow-list shrinks). When the transfer queue is dedicated, staging and graphics submits overlap.
  • Frame retirement consolidated on one word — when the timeline is active, BeginFrame / EndFrame / lockstep prefer vkWaitSemaphores over per-slot fence waits. Per-slot fences remain as the fallback path when the feature isn't supported.
  • VulkanSwapchain::Recreate(w, h, drainedExternally = false) — opt-in flag skips the internal vkDeviceWaitIdle when the caller has already drained (scheduler-aware HandleLiveResize passes true). Default behaviour unchanged for existing users.
  • VulkanDevice::Shutdown — now resets m_ComputeQueue / m_TransferQueue so GetComputeQueue / GetTransferQueue don't return dangling handles post-shutdown.
  • LogVkVCKLog::{Info,Notice,Warn,Error} migration — every call site in core / expansion / execution / vmm / example now routes through VCKLog with a subsystem tag. LogVk stays as a shim for user code that hasn't migrated yet.
  • build.bat / build.sh — menu now [1]-[13]; [A] builds all 13 examples.

Fixed

  • VulkanOneTimeCommand::End infinite hang — previously called vkWaitForFences(UINT64_MAX) unconditionally; if vkQueueSubmit failed the fence would never be signalled and the call would block forever. Now short-circuits on submit failure.
  • Cross-family submit during staging — first v0.3 iteration submitted a graphics-pool-allocated command buffer to the transfer queue (spec violation on dedicated-transfer GPUs). Fixed by giving VMM its own transfer-family command pool.
  • VMM fallback path missing VK_CHECK — fence-creation-failed branch submitted without the standard VK_CHECK wrapper, silently dropping VK_ERROR_OUT_OF_DEVICE_MEMORY / friends (rule 14).
  • Stale acquire barriers on failed transfer submit — if the transfer submit failed the CPU-side acquire barrier list would still run on the graphics queue with oldLayout = TRANSFER_DST_OPTIMAL on images actually still UNDEFINED. The acquire list is now cleared when the release submit fails.

0.2.1 - 2026-04-24

Added

  • Rules 18-22 in docs/Design.md:
    • R18 External synchronisation — codifies Vulkan's per-handle external-sync requirement; JobGraph is the one exception.
    • R19 Zero cost for unused features — un-Initialized modules allocate nothing, spawn no thread, emit no log line.
    • R20 Every public API has an example — public classes in VCK.h must be exercised by at least one example under example/.
    • R21 VCK.h is the API surface — layer headers are implementation detail; breaking changes to VCK.h bump the minor version until v1.0.0.
    • R22 VCK never owns user handles — completes rule 9; VCK destroys only handles it created.
  • VCKMath.hVec2 / Vec3 / Vec4 / Mat4 POD structs, free-function Translate / Rotate / Scale / Perspective / LookAt / Radians / Degrees. No templates, no SIMD, row-major.
  • VertexLayout — fluent Add(name, VertexAttrType)Binding(0) + Attributes() builder; returns plain VkVertexInput* structs the caller hands to VulkanModelPipeline (rule 22, no ownership).
  • PushConstantsDeclare(name, type) cold path, Set(name, value) + Apply(cb, layout, stages) hot path. Name → offset resolved at Declare; no hashing / std::any / std::variant in the hot path.
  • Primitives::Cube / Plane / Sphere / Quad / Line — return-by-value Mesh { positions, normals, uvs, indices }. Shrinks cube setup from ~40 lines of vertex tables to one call.
  • DebugTimeline::DumpChromeTracing(path) — emits a Chrome-tracing JSON array you can load in chrome://tracing or ui.perfetto.dev. No viewer bundled.
  • New example [10] DebugShowcaseExample — guided tour of every VCKLog level, cfg.debug gating, dedup, VK_CHECK fail-loud path, GPU / driver / memory / surface dump. No draw loop.
  • New example [11] AAShowcaseExampleDetectRecommendedAA decision matrix across forwardRenderer × supportsMotionVectors, live swapchain auto-pick echoed via GetAATechnique() + GetMSAASamples(), RGB triangle drawn with the picked AA.
  • New example [12] EasyCubeExamplePrimitives::Cube() + VertexLayout + PushConstants + VCKMath in one screen. Rule 20 parity for the v0.2.1 ergonomic API.
  • Wiki Cookbook — one-stop recipe book: image / OBJ / cube / text / line / circle / FXAA / SMAA / TAA skeletons / ImGui bootstrap / offscreen PNG readback.

Changed

  • Rule 14 tightened — now explicitly requires VCKLog::Error with a subsystem tag on every failure; a return false without a matching Error is a bug.
  • VulkanModelPipeline::Initialize (4-arg overload) emits VCKLog::Warn when called; the hardcoded VK_SAMPLE_COUNT_1_BIT is hazardous when the render pass uses MSAA. Use the 5-arg overload and pass swapchain.GetMSAASamples().
  • build.bat / build.sh — menu grew to [1]-[12].

Fixed

  • Top-left quadrant rendering in MipmapExample + VMMExample — caused by pipeline-vs-render-pass sample-count mismatch (pipeline was 1x, render pass was MSAA 4x — undefined per spec, on NVIDIA confines rasterisation to the top-left quadrant). Both examples now pass swapchain.GetMSAASamples() to the 5-arg VulkanModelPipeline::Initialize.
  • Windows ANSI colour outputVCKLog::Init() now calls SetConsoleMode with ENABLE_VIRTUAL_TERMINAL_PROCESSING once on startup so Windows CMD renders colours instead of ←[96m literals.
  • build.bat line endings.gitattributes forces CRLF on *.bat so Windows CMD stops fragmenting comment lines into garbage tokens.
  • EasyCubeExample sizeof bugVulkanMesh::Upload takes total byte count, not per-vertex stride; was uploading 1 of 24 vertices.
  • DebugTimeline::DumpChromeTracing underflow guardendUs - startUs now matches Dump()'s endUs > startUs ? endUs - startUs : 0 pattern.

0.2.0 - 2026-04-23

Added

  • Cross-platform support (Windows / Linux / macOS) via VCK::Window + VCKCrossplatform facade over GLFW. VCK_PLATFORM_WINDOWS/LINUX/MACOS macros gate platform includes.
  • example/build.sh — Linux + macOS builder with the same [1]-[9] / [A] / [0] menu as build.bat; auto-detects OS, uses pkg-config for Vulkan + GLFW.
  • Live resize as first-classVCK::HandleLiveResize(window, dev, sc, fb, pipe[, depth]) handles any OS resize (720p ↔ 4K) in one call per frame. Timeline-aware overloads in layers/execution/ emit a DebugTimeline CPU span (rule 12).
  • Anti-aliasing frameworkVCK::AATechnique enum (Auto, Off, MSAA, MSAA_A2C, SampleRate, FXAA, SMAA_1x, SMAA_T2x, TAA, TAAU). cfg.aa.technique = AATechnique::Auto runs a 5-step decision tree at VulkanSwapchain::Initialize. Sample-based techniques implemented pipeline-side; post-process names returned via swapchain.GetAATechnique() for renderer to implement (rules 15/16).
  • VCK::VCKLog structured logger — Info (debug-gated) / Notice / Warn / Error. Console-spam dedup of identical consecutive (tag, body) lines. Classify helper parses legacy LogVk("[Tag] body") into the new levels.
  • cfg.debug flag (default false) — VulkanContext::Initialize wires it into VCKLog::SetDebug().
  • cfg.pipeline.alphaToCoverage — flips alphaToCoverageEnable in pipeline multisample state.
  • cfg.pipeline.sampleRateShading + minSampleShading — enables per-sample shading.
  • Repo reorganisation: layers/{core,expansion,execution,vmm}/ + vendor/{vulkan_headers,glfw,vma}/. VCK.h at root is the single source of truth for API documentation.
  • WikiHello-VCK.md (per-line walkthrough targeting 1-hour onboarding budget), _Sidebar.md (navigation).
  • LICENSE, CHANGELOG.md, CONTRIBUTING.md, .editorconfig, .gitignore at repo root.

Changed

  • VK_CHECK now routes failures directly to VCKLog::Error(…) instead of the debug-gated LogVk(…) — fail loud regardless of cfg.debug (rule 14 fix).
  • VulkanContext::Initialize takes VCK::Window& (was HWND on Windows only); raw-handle overload preserved as escape hatch (rule 9).
  • <windows.h> / <vulkan_win32.h> guarded behind VCK_PLATFORM_WINDOWS in VulkanHelpers.h and VCK.h — no more platform leakage in the public surface.
  • docs/Design.md rule 4 allow-list updated to include VulkanSwapchain::Recreate and HandleLiveResize vkDeviceWaitIdle calls.
  • Examples 1-9 ported to VCK::Window + VCK::HandleLiveResize — dropped raw GLFWwindow*, HWND, g_Resized, g_Minimized, OnFramebufferResize.

Removed

  • core/VulkanHelpers.cpp (empty shell).
  • core/ at repo root (moved to layers/core/).
  • VMM/ at repo root (moved to layers/vmm/).
  • BuildRequiredExtensions helper in VulkanContext.cpp (dead code from pre-crossplatform era, no matching header decl).

0.1.0 - 2026-04-22

The first release under the VCK name. Project was rebranded from VVCS ("Vulkan-VCS") to VCK — Vulkan Core Kit in commit deced77. This release establishes the public surface (VCK.h amalgam header), the three-layer architecture (core / expansion / execution), the in-tree example builder (build.bat + ANSI menu), the structured logger, and a Windows CI gate. The project is Windows-only at this point; cross-platform support lands in v0.2.0.

Added

  • Project rebrandVVCS → VCK (Vulkan Core Kit). README, build scripts, header guards, and namespace VCK:: finalised.
  • VCK.h amalgam header — single public include surface; per-class declarations stop being duplicated and the amalgam now #includes the layer headers directly (rule 21 precursor).
  • Three-layer architecturecore/ (VulkanContext, VulkanDevice, VulkanSwapchain, VulkanPipeline, VulkanCommand, VulkanSync, VulkanBuffer, VulkanImage, VulkanHelpers), expansion (framebuffers, depth, samplers, textures, model pipelines, descriptor sets, mipmaps), execution (FrameScheduler, JobGraph, GpuSubmissionBatcher, BackpressureGovernor, DebugTimeline, TimelineSemaphore).
  • VCK::Config master init-chain control struct — cfg.device, cfg.swapchain, cfg.pipeline, cfg.scheduler, cfg.aa, cfg.debug knobs; passed once to VulkanContext::Initialize.
  • VulkanPipeline::Config — cull mode, front-face winding, blend state, push-constant ranges, descriptor-set layouts.
  • Mailbox present mode by default with FIFO fallback when the surface doesn't expose Mailbox.
  • Six VCKExpansion examplesHelloExample, ModelExample, VMMExample, FrameSchedulerExample, TripleBufferExample, LockstepExample, plus three execution-layer examples (SubmissionBatchingExample, JobGraphExample, DebugTimelineExample).
  • example/build.bat — Windows MinGW builder with [1]-[9] / [A] / [0] ANSI-coloured menu, BUILD_ALL section that compiles every example in one pass, and CRLF-safe shader compile via glslangValidator.
  • VMM (Vulkan Memory Manager) — three-layer allocator (VmmPersistent / VmmTransient / VmmStaging) wrapping VMA's pool-aware allocators. VmmBuffer / VmmImage are typed POD-by-handle wrappers. LogStats dump every N frames for the example.
  • VCKLog — coloured [VCK] [Tag] body logger with Info / Notice / Warn / Error levels and an init-time global toggle for debug-gated Info lines.
  • docs/ at repo root — split out from README into Build.md, Examples.md, Design.md, Home.md. README slimmed to badges + 60-second tour + pointers.
  • GitHub wiki — initial structure; _Sidebar.md, design rules.
  • CI: Windows workflow.github/workflows/build.yml runs build.bat A on windows-latest for every push / PR. SDK installer
    • vk_video/*.h sparse-checkout patch (the LunarG installer's vulkan_video component is optional but vulkan_core.h hard-includes it).
  • .gitattributes — forces CRLF on *.bat so Windows CMD doesn't fragment comment lines into garbage tokens.

Changed

  • build.bat redesigned with an ANSI UI; chcp 65001 for UTF-8; em-dashes scrubbed from console-bound strings (CMD prints them as ? on default codepages).
  • AllocConsole removed in favour of g++'s default console-subsystem stdout — no flicker on launch, no leftover console if the program crashes.
  • VulkanContext::Initialize drops the leftover BuildRequiredExtensions helper (Win32-only dead code with no header declaration).

Fixed

  • VMM lifecycle bugs — wrong destruction order between VmmTransient ring slots and VmmStaging was leaking allocations on Shutdown. Routed VMM logs to a Windows console.
  • FrameScheduler Lockstep + AsyncMax deadlocks — Lockstep was waiting on the slot fence before signalling the previous frame's release; AsyncMax could double-acquire the same slot under contention.
  • build.bat BUILD_ALL trailing whitespace in set EX=... causing the all-build pass to skip examples whose name had a trailing space.
  • MinGW compileSubmitInfo and VCK::Config need explicit default ctors; gcc 13 wouldn't aggregate-init through inheritance.
  • JobGraph::Add — counted invalid (out-of-range) deps toward the job's wait count, so Execute() could deadlock waiting for a job that would never run.
  • VCKExpansion.h — forward-declared VulkanDepthBuffer before VulkanFramebufferSet (compile order fix).
  • HelloExample — quad winding flipped so the embedded "Hello, World" text isn't back-face culled.

[0.0.x] - 2026-04-05 → 2026-04-21 (pre-rebrand prehistory)

The original project was named VVCS (Vulkan-VCS). These commits are preserved in git history but never shipped under the VCK name; they're listed here for repo archaeologists. No SemVer was applied during this period.

  • Initial drop — bare-bones VulkanModule.h + sample main.cpp / App.cpp / App.h exercising context + device + swapchain + pipeline.
  • VMM iteration — first staging / persistent / transient layers; early lifecycle bug fixes.
  • Windows console plumbingAllocConsole route for log output (later replaced by g++ console subsystem in v0.1.0).
  • README iteration — multiple README rewrites before the v0.1.0 rebrand.
  • core/ (9 primitive classes + VulkanHelpers), VCKExpansion ([1]-[12] rendering building blocks), execution layer ([13]-[22] frame scheduling), VMM/ (three-layer memory manager).
  • 17 design rules documented in docs/Design.md.
  • 9 example applications (HelloExample, ModelExample, VMMExample, FrameSchedulerExample, TripleBufferExample, LockstepExample, SubmissionBatchingExample, JobGraphExample, DebugTimelineExample).
  • example/build.bat Windows MinGW builder with [1]-[9] / [A] / [0] menu.
  • GitHub Actions CI (.github/workflows/build.yml) running build.bat [A] on Windows.