perf(render3d): Vulkan draws find pipelines by integer and reuse descriptor sets

R3D_VK_PROF at the camp view (about 2950 draws a frame) showed the frame spent in bookkeeping:
19.5 ms a frame finding pipelines by string key and 16 ms building descriptor sets.

- Pipelines: a mesh carries an interned vertex-layout id (dropped only when an attribute's shape
  changes, not when an instance buffer is swapped), render state packs into an int and the pass
  formats into another; the program's last hit is tried first. The string path only builds.
- Samplers: each texture keeps the sampler for its parameters until they change.
- Descriptor sets: a program's last set is reused within the frame while its blocks and resolved
  textures are unchanged; a uniform write that repeats the value it already holds changes nothing.

Headless on the RTX 3070 Ti at 1920x1080: 21.7 -> 53.3 fps (pipelines 0.2 ms, sets 8.5 ms, inside
draws 10 ms a frame; OpenGL 114 fps). The camp frame is unchanged and validation-clean. OpenGL frames
byte-identical at the five viewpoints; 59 self-tests pass; VKRES OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-15 13:22:51 +03:00
parent 6942c36853
commit f5d1a62ccf
4 changed files with 132 additions and 8 deletions

View file

@ -448,6 +448,8 @@ function gpu_mesh_record(m: Mesh, index: int, comps: int, type: int, stride: int
let o = index * GPU_ATTR_W
var st = stride
if st == 0 { st = comps * gpu_type_bytes(type) }
# re-pointing an attribute at another buffer keeps the layout; changing its shape does not
if m.attrs[o + 1] != comps or m.attrs[o + 2] != type or m.attrs[o + 3] != st or m.attrs[o + 4] != offset or m.attrs[o + 5] != gpu_b(normalized) or m.attrs[o + 6] != gpu_b(inst) or (m.attrs[o] == m.attrs[0]) != (m.cur_buf == m.attrs[0]) { m.vk_layout = 0 }
m.attrs[o] = m.cur_buf; m.attrs[o + 1] = comps; m.attrs[o + 2] = type; m.attrs[o + 3] = st
m.attrs[o + 4] = offset; m.attrs[o + 5] = gpu_b(normalized); m.attrs[o + 6] = gpu_b(inst)
if index + 1 > m.n_attrs { m.n_attrs = index + 1 }