Skip to content

Combined #886 + #887: Nic's answers and EXR PIZ, pre-merged - #890

Merged
paul-hammant merged 19 commits into
mainfrom
combined/886-887
Oct 30, 2026
Merged

paul-hammant merged 19 commits into
mainfrom
combined/886-887

Conversation

@paul-hammant

@paul-hammant paul-hammant commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

#886 (Nic's answers: issues and small fixes) and #887 (PIZ in the OpenEXR reader) merged into one branch, so CI runs once for both. Merging this marks both as merged, since their commits are in it unchanged.

Resolved between them:

Also includes main's 420e3b8 (a Linux shard gets 40 minutes; #886 and #887's last runs were cut off at 25 in the benchmarks step).

Local, M6: test_envimage 191/191 (PIZ bit for bit against OpenEXR and the 2:1 shape checks), and test_environment, test_backend_parity, test_vk_msl, test_scene_look and test_gpu_envmap pass.

Supersedes #886 and #887.

🤖 Generated with Claude Code

paul-hammant and others added 19 commits October 28, 2026 22:43
A pure-Aether PIZ block decoder. Not wired in yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PXR24, B44, B44A, DWAA and DWAB are still refused by name. half_to_float
returned +0 for 0x8000 (0 - 0), so a decode could not equal the OpenEXR
library's bit for bit; it is negated by a product now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
25 small PIZ files plus two Poly Haven 1k assets (CC0): hashes of the OpenEXR
library's decode in test_envimage, the fuzz loops over the small ones, damaged
bit counts. tools/exr_reference is the development tool that wrote them (not
built, not linked). coded_piz.exr (a header only) is replaced by header-only
PXR24, B44 and DWAA refusals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Nic 872-2)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The comment in vkframe named a crowd's figure among the draws the pick pass has
no pipeline for; crowd_pick_pipeline (#865) has one. The exclusions are particles,
surfaces added over the frame, water (kept out on purpose: the CPU's
water.simulation_height_at serves a boat or a fishing cursor) and world text,
which is drawn after the pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Nic 873-4)

The test draws a 16-pixel pick and a view blitted into a rectangle in both
modes and holds the MSL's answers (model, instance, depth) and frame to the
SPIR-V's; vkpipes.msl_made_for(shader) lets it say these two modules were made
from MSL, not fall back. The four vertex shaders stay SPIR-V (MoltenVK 1.4.2).

Negative controls (the MSL text of the shader mutated, length kept in
vkmsl.bytes, tree restored): pick id x2, instance + 1, depth halved each fail
the pick check (2, 4, 4 of 48 answers); the blit's red unencoded, green x0.9,
and uv transposed fail the frame (669, 669, 2396 of 24576 channels). Alpha set
to 1.0 passes: the view is opaque, an equivalent mutant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…c 874-2)

Until now the targets stayed until the frame was remade. set_upscaler(0)
releases them (Vulkan: device idle first, then the framebuffers and textures;
OpenGL: both textures, the size forgotten so the next use remakes them), and
renderer_upscale_targets reports how many are alive. test_backend_parity
checks 2 while it runs, 0 right after turning it off and after a frame
without it, 2 again when turned back on.

Negative controls: the Vulkan release removed fails 'released at once'
(vulkan 2) and 'a frame without the upscaler makes none'; the OpenGL one the
same (opengl 2). Passes at AE3D_MSAA=0 and 4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ic 874-8)

One rule, the one vkframe states: a full-screen pass of the frame's own is
not a draw of the scene's. OpenGL counted the DoF's coc and gather (+2) and
the upscaler's easu and rcas (+1 each); those increments go. Vulkan reads its
count before the post chain runs, so its upscaler and DoF passes never
reached it, and nothing changes there.

test_backend_parity pins it: the upscale and the sharpen add 0 on both, DoF
adds 0 on both (measured over the SSAO's baseline, since Vulkan's DoF makes
the frame resolve the scene's depth during the scene, one counted pass the
SSAO needs too).

Negative controls: the DoF's +2 put back fails (opengl 7 -> 9); the easu's +1
and the rcas's +1 each fail (opengl 5 -> 6). Passes at AE3D_MSAA=0 and 4.
TAA, FXAA, SSR and the composite are a separate issue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
envimage.from_memory (and load, so the .hdr and .exr paths both) refuses a
decoded picture whose width is not twice its height: it is freed, null comes
back and envimage.error() / engine_environment_error() read "the environment
map is W x H: an equirectangular map is twice as wide as it is tall (2:1)".
decode_any is the unchecked reader the decoders' own tests use (their
fixtures are 8 by 20, 32 by 4, 600 by 2).

test_envimage: gradient.hdr, gradient.exr and flat.hdr are taken; five
fixtures of both formats are refused with their size in the error and still
decode as pictures; in-memory .hdr of 2x1, 4x2, 6x3 taken and 5x2, 3x2, 4x3,
4x4, 1x2 refused. Negative controls (the check removed, >= instead of ==,
w * 2 == h, squares also taken) fail 10, 3, 7, 10 checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on four times too strong fails (#830)

913754c moved the zombie_street figure-reflection check to the figure's own
part (the rows' change less the road's own with the figure gone). That part is
nearly blind to strength: a reflection raises the road's share and the whole
alike. Measured on the M6 (critique, vulkan, 320x180): as the scene draws it
(strength 1.5) the rows change 0.21, the road's own part 0.14, the figure's
0.07; at strength 6 they change 0.54, the road's 0.44, the figure's 0.10, and
the check against 0.20 passes.

So the measure keeps the smear check as it was and adds the whole against
SSR_UNDER_FEET_MAX = 0.35 (between 0.21 and 0.54; the original whole-measure
failure was 0.22 against a 0.20 limit, hence a limit above it, not a return
to it). Negative control: SSR_STRENGTH 6.0 in the tool fails the new check (0.54),
and only it; at 1.5 the critique passes (0.21).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test_environment holds the renderer's irradiance for two assets to the decoded
picture's integral on OpenGL and Vulkan; test_backend_parity draws one with
both and holds the frames equal (0 of 147456 channels at one sample).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tests/test_environment.ae: both sides added checks after ground(); keep the
Poly Haven PIZ assets (this branch) and the environment-map yaw checks (#888).
test_envimage 170/170 and test_environment pass on both backends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
src/ae3d/{gl,vulkan}/module.ae exports: this branch added
renderer_upscale_targets, main added renderer_set_environment_look; keep both.
test_envimage, test_environment, test_backend_parity, test_vk_msl and
test_scene_look pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/rendering.md: PIZ is now read, and a map that is not 2:1 is refused;
both sentences kept.
tests/test_envimage.ae: #886 made envimage.load refuse a map that is not
2:1, so #887's OpenEXR equality checks, which read PIZ pictures of any
proportions (1 to 1000 wide), now decode through envimage.decode_any.
refused("coded_piz.exr") is gone since PIZ decodes; #887's PXR24, B44 and
DWAA refusals are kept.

test_envimage 191/191; test_environment, test_backend_parity, test_vk_msl,
test_scene_look and test_gpu_envmap pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@paul-hammant
paul-hammant merged commit 35378c4 into main Oct 30, 2026
10 checks passed
@paul-hammant
paul-hammant deleted the combined/886-887 branch October 30, 2026 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant