Commit graph

8 commits

Author SHA1 Message Date
c660ac881c feat(render3d): Vulkan textures, samplers and buffers
gpu_vk_res.ludic gains what gpu.ludic's texture and buffer handles stand for on Vulkan:

- gvk_tex_storage / _upload / _mips / _read / _release: an image and view per handle, a full mip
  chain when pixels come with it (the renderer asks for mipmaps after the upload) and one level
  for a target, every level in SHADER_READ_ONLY between uses. Uploads are converted to what the
  image stores: a missing alpha filled opaque (three-channel formats are stored with four), 16-bit
  PNG samples byte-swapped when the unpack state says so, 32-bit float HDR halved into half
  floats. Mips are blitted down level by level; a read-back brings level 0 home.
- gvk_sampler: one VkSampler per filter / wrap / compare / anisotropy combination, made when first
  asked for, with GL's defaults where the renderer set nothing.
- gvk_buf_*: vertex, index and instance buffers behind one handle, kept when an upload fits.
  Host-visible while the backend comes up.

gpu_vk.ludic switches on anisotropic sampling where the device has it and reads its limit.

examples/rendering/vk_resources.ludic checks it all: VKRES OK, validation-clean, every allocation
freed, on the RTX 3070 Ti (16x anisotropy) and on MoltenVK. One run on the Mac crashed while a
headless game run was using the GPU and did not come back in two reruns. OpenGL frames
byte-identical at the five viewpoints; 59 self-tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 11:57:28 +03:00
7d93f44e53 feat(render3d): gpu_vk.ludic - the Vulkan backend's device, memory and one-shot commands
The first part of the Vulkan side of gpu.ludic, not yet reached from the renderer: gvk_init
brings up the instance (portability enumeration where offered), the first discrete GPU, a
graphics queue and a device with the Tier 1 floor switched on (dynamic rendering,
synchronization2, descriptor indexing, timeline semaphores), and says why when it cannot so
the caller stays on OpenGL. gvk_mem_type / gvk_alloc pick and allocate memory (one allocation
per resource while the backend comes up), and gvk_once_begin / gvk_once_end carry uploads,
bakes and read-backs through submit and wait.

examples/rendering/vk_device.ludic runs it alone: VKDEVICE OK and validation-clean on the RTX
3070 Ti and on MoltenVK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 11:46:50 +03:00
c55a1cc7f2 feat(examples): vk_triangle - a headless draw through Vulkan's graphics pipeline
A Slang vertex and fragment shader draw a triangle into an image with dynamic rendering (no
render pass object: the pipeline names its colour format), image barriers move it to the
attachment and transfer layouts, and vkCmdCopyImageToBuffer reads it back into a PPM. It is
the path the Vulkan renderer's passes and screenshots take.

The corner comes from SV_VulkanVertexID: Slang compiles SV_VertexID to gl_VertexIndex -
gl_BaseVertex, which declares the draw-parameters capability.

Validation-clean and VKTRIANGLE OK on the RTX 3070 Ti (Windows) and the M4 Pro (MoltenVK),
13824 pixels covered on both.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 11:37:47 +03:00
f97d54aa2a feat(render3d): read the SPIR-V manifest the way a Vulkan backend will
gpu_manifest.ludic loads shaders/spv/manifest.txt and answers what a backend asks while drawing:
which variant a program built by r3d_program is, where a uniform lives in its stage's block,
which binding a sampler has, what the vertex inputs are. examples/rendering/vk_manifest.ludic
resolves every program in variants.list against it (45 of 45) and checks a few offsets and
bindings. Nothing imports it yet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:41:43 +03:00
208cad7ca1 feat(vk): Vk.* - Vulkan 1.0-1.4 generated from the registry, loaded at run time
ludic-dev vkgen reads vk.xml into runtime/native/vk_api.ludic (constants, every struct's
<Struct>_sizeof and <Struct>_<field> offsets, one extern per command) and vk_thunks.ll.
Every size and offset was compiled against the SDK's C headers; `ludic-dev test` checks the
tracked files against the registry wherever the Vulkan SDK is installed.

vk_win.ll (vulkan-1.dll) and vk_mac.ll (libvulkan.1.dylib, MoltenVK) open the loader at run
time, so a program built with Vk.* starts on a machine without Vulkan. ludicc and ludic
build link both for any program that uses Vk.*. The seeds are regenerated for the new
compiler.

vk_probe reports what a machine's Vulkan can do; vk_compute dispatches a Slang compute
shader and reads the picture back, clean under the validation layer on an RTX 3070 Ti and
on an M4 Pro through MoltenVK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 09:52:12 +03:00
a4a3d75cd9 feat(render3d): replace the world at run time, water bodies, terrain_sea
terrain_reload/terrain_unload release one map's height field, survey, photograph
and patch bounds and generate another at any TERRAIN_HALF; scatter_clear_all
(with streams), actor_clear_all, col_reset and mesh_free empty the scene;
water_body_add/water_bodies_clear draw several still-water planes with one
reflecting; terrain_sea separates the coast's sea level from the carved lake's,
and grass keeps off both. Fixes CDLOD patch bounds for TERRAIN_HALF != 4096 and
water_init leaking a mesh and program per call. examples/rendering/reload.ludic.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 00:03:40 +03:00
f25289db20 feat(gl): OpenGL 4.1 and the ludic.render3d renderer
Some checks failed
ci / build-and-test (push) Waiting to run
commit-lint / conventional-commits (push) Waiting to run
bootstrap / cfree-fixpoint (push) Has been cancelled
docs / build-and-deploy (push) Successful in 34s
`Gl.*` binds the whole OpenGL 4.1 core API — every entry point of the
platform gl3.h with every GL_* constant, generated by `ludic-dev glgen`
with per-call ABI thunks. Windowed builds get an NSOpenGLContext on the
existing window at Retina resolution; headless builds render into an
offscreen CGL context, so a program that uses Gl.* renders and
screenshots identically under the test harness. It links gl.ll, the
thunks and OpenGL.framework only when used; every other build stays
byte-identical.

packages/ludic.render3d is a physically based renderer written on that
surface: HDRI image-based lighting, GPU-generated terrain with scanned
PBR materials, CDLOD, cascaded shadows, glTF with skinning, instanced
vegetation with impostors, procedural grass, water, SSAO, and an HDR
pipeline with bloom, auto-exposure and ACES.

It also carries this session's work on it: the terrain at half its cost
(10.3 -> 5.4 ms of frame), the streaming hitch that got worse the longer
you played, a resize that emptied the world, and the packaging that lets
a game use the renderer from its own repository — `ludic assets`, the
material manifest shipping with the package, and shader lookup falling
back to the install root. See changes/ for each, with its numbers.

The camping game that drove all of it has moved out to its own
repository, Maroon Lake; examples/rendering/smooth.ludic stays as the
renderer's example here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 03:31:12 +03:00
fb728bbefe chore(repo): DX cleanup — categorise examples, text-diffable golden, build/ output (#27 #28 #30)
Repository-cleanup / DX pass folding three tracker items into one coherent
change, verified green end to end (`bin/x test` 49/0, `bin/x selfhost-test`
29/0, `bin/x test-tools` 29/0).

#28 — curate & categorise examples/
- 42 flat entries regrouped into intent-revealing subdirs: games/, rendering/,
  ecs/, events/, networking/, lang/, library/ (was lib/).
- chronorift dir-vs-file duplication resolved: the entry file and its import
  modules now live together under games/chronorift(.ludic).
- Every path reference updated repo-wide (test runner, editor-tool drivers,
  docs/site, design docs).
- New examples/README.md indexes the whole set with run commands.
- Showcase examples without a self-asserting entry (hello, events, net_rt) now
  get a compile-only rot guard in `bin/x test`, so nothing here rots silently.

#30 — text-diffable golden baseline
- The 4 binary selfhost/golden/*.ppm blobs are replaced by a single
  selfhost/golden/renders.sha256 manifest (SHA-256 per render). Hashes are
  byte-identical to the old PPMs, so the baseline is unchanged — only its form.
- game_case now compares framebuffer hashes; a regression shows as a changed
  hex line in review, not "binary files differ".
- New `bin/x golden` regenerates the manifest deliberately (review with
  `git diff selfhost/golden/renders.sha256`).

#27 — PPM & asset handling
- Headless renders now write build/out.ppm, never the repo root; `x app`,
  `x clean`, messaging and .gitignore updated to match. Nothing is written to
  the working root any more.
- Redundant local Kenney .zip archives removed (the art ships extracted;
  .gitignore already excludes *.zip). CC0 License.txt files retained.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-30 18:54:21 +03:00