concinnity-core 0.19.24

Runtime vocabulary for the Concinnity engine: GPU layouts, ECS components, registry, CPU kernels
Documentation
// Previous-frame model snapshot for the G-buffer pre-pass's motion vectors.
// One thread per cull record: copies this frame's model matrix out of the
// bindless object buffer into the frame's slot of the model-history ring, which
// the NEXT frame's pre-pass reads as its previous-frame transform.
//
// The snapshot lives on the GPU because the object buffer already carries every
// model the pre-pass needs: a host-built parallel table would write the same
// 64 bytes per record a second time, once per backend.
//
// Records are indexed exactly as the object buffer indexes them (static prefix,
// instances, runtime reserve, skinned tail), so a record's history entry is only
// meaningful while that record keeps its occupant. A record whose occupant
// changed carries `DRAW_NO_HISTORY` in its draw args and the pre-pass falls back
// to the current model, which is what makes the copy unconditional here.
//
// Single source for every backend. Metal and DXIL assign the same slots from
// declaration order (params 0, objects 1, history 2), matching the hand-assigned
// host bindings on all three; Vulkan binds set 0 bindings 0-2.

{OBJECT_COMMON}

// Matches `ModelHistoryParams` in render/uniforms/geometry.rs (16 B).
struct ModelHistoryParams
{
    uint record_count;
    uint _pad0;
    uint _pad1;
    uint _pad2;
};

[[vk::binding(0, 0)]]
ConstantBuffer<ModelHistoryParams> params;

[[vk::binding(1, 0)]]
StructuredBuffer<GpuObjectData> objects;

[[vk::binding(2, 0)]]
RWStructuredBuffer<float4x4> history;

[shader("compute")]
[numthreads(64, 1, 1)]
void model_history_kernel(uint3 tid : SV_DispatchThreadID)
{
    uint i = tid.x;
    if (i >= params.record_count)
    {
        return;
    }
    history[i] = objects[i].model;
}