Skip to content

Sky modernization 4: ALSky in place of the sky's objects and pools - #584

Merged
RyeMutt merged 13 commits into
rye/sky-p3-compositefrom
rye/sky-p4-alsky
Oct 27, 2026
Merged

RyeMutt merged 13 commits into
rye/sky-p3-compositefrom
rye/sky-p4-alsky

Conversation

@RyeMutt

@RyeMutt RyeMutt commented Oct 27, 2026

Copy link
Copy Markdown
Member

Phase 4 of the sky modernization (doc/SKY_MODERNIZATION.md): ALSky in place of the sky's viewer objects and pools. Stacked on #583 (rye/sky-p3-composite).

What changes

  • ALSky holds the sky's state (newview/alsky.h), owned by LLPipeline. LLVOSky, LLVOWLSky, LLDrawPoolSky, LLDrawPoolWLSky, POOL_SKY/POOL_WL_SKY, gSky and LLSky are deleted (D1).
    • It takes the sky before anything draws, and again after the environment update for the main view.
    • Each view builds its layer mask once, at its G-buffer's clear, which clears the stars' attachment only in views that draw stars.
    • The star field is laid out on the General work queue.
    • A null rainbow or halo id falls back to the sky's defaults, and llrender binds nothing for a null texture.
  • The probes-off environment cube is baked on the GPU from windlightDome (ALSkyCube, D2).
    • It starts mid grey, is retried at its interval when a bake fails, and compares its inputs within develop's tolerance.
    • It is recorded in the VRAM accounting as OTHER_TEXTURE.
  • Cleanups:
    • only the beacons' fog colour stays in LLAtmospherics;
    • RenderFogRatio and other orphaned settings are deleted;
    • the lens flare's probe is sized from the drawn quad;
    • the shader-constant mechanism and the never-bound deferred highlight program are deleted;
    • unlit pixels show their albedo;
    • ARCHITECTURE.md describes the sky as ALSky draws it.

Look changes

Probes-off sessions (low class, Intel legacy, reflections off) reflect the GPU-baked dome in place of the old CPU cube. The old cube held WindLight's colour along the opposite of each lookup, at quarter saturation.

Verified

  • On develop c32de66abf:
    • Release builds clean, the attribution step included;
    • ctest -LE manual passes 557/557;
    • the raw-GL guard passes.
  • The viewer reaches the login screen on a scratch profile with 323 programs linked and none failing.

Not verified

  • Not run in-world: probes-off reflections, the bloom with probes on, a runtime probes toggle, context loss.
  • No Tracy captures.
  • No macOS, AMD or Intel legacy runs.

🤖 Generated with Claude Code

RyeMutt and others added 10 commits October 26, 2026 20:03
The sky was two fake viewer objects (LLVOSky, LLVOWLSky) with pcodes,
drawables and faces, pushed into every view's cull and drawn through two
pools, one of them empty. Since the composite (Phase 3) only the stars
still drew through a pool. ALSky (newview/alsky.h) now holds the sky's
state, owned by LLPipeline as the water's surface is:

- the sun and moon (LLHeavenBody, trimmed to its direction and turn as
  the sky sets them, its disk and its quad; their colour, the bloom's
  tint, and whether each is up are the current sky's, read where they
  are drawn) and their quads, taken at the start of the frame rather
  than in every view the pool ran in. Their half-extent per unit of
  disk radius, scale and distance is ALSkyLayers::BODY_FACTOR, the one
  bodyCorners builds them with, which the lens flare's probe
  (LLPipeline::generateLensFlareState) reads too;
- the EEP textures, fetched from the ids the sky sets on the next
  update, at the priority they are drawn at; the bloom's only under the
  latched sun bloom. A rainbow or halo id the sky leaves null is
  LLSettingsSky's default, since every view that draws the dome samples
  both maps;
- the star field, laid out on the General work queue (requestStars) and
  landed on the main thread (landStars), which keeps only the field
  that answers the last request: a RenderStarCount change, which takes
  effect without a restart, draws the last field until its own lands.
  The star buffer is made from the field when next drawn, and where it
  cannot be made it is not asked for again until a new field lands or
  the context changes. The cells, the brightness cull (none on the float
  attachment, where every star in view is drawn), and the meteors;
- the per-frame uniforms (bindDome, bindComposite, useHDRISky);
- the fog colour the tracker's beacons read, and for now the CPU-built
  legacy environment cube, moved as it was.

It runs at three fixed points, the same in every view: the stars right
after renderGeomDeferred's pool loop, the composite at the sky's pass,
and the dome where the haze binds for water. Nothing after the opaque
pools drew into the G-buffer (glow, alpha and water draw after the
lighting), so the stars land where they did.

ALSky::update takes the frame's sky at the start of display, before
anything draws: the mirrors draw it, and the previews and impostor
bakes read its environment cube. Right after LLEnvironment::update has
moved the sky on, followEnvironment takes the bodies and the textures
again for the main view; the mirrors, drawn before it, draw the sky as
the frame began, as they take its environment.

Each view takes what it draws of the sky once, at its G-buffer's clear.
LLPipeline::beginSkyView has ALSky::beginView take the view's layers
(ALSkyLayers::layersFor) from the kind of view, the current sky and the
latched inputs, none where drawsSky says the view draws no sky, and
clears the stars' attachment only where they have the stars. The
stars' draw, the meteors' tick and the composite read the same layers
(viewLayers). The composite's draw binds its program alone, not the
G-buffer through bindDeferredShader: bindComposite binds the stars'
attachment among its maps, only where the layers have them, records
each map it binds, and unbindComposite lets go of those alone. It
leaves the meteors out where none is on the screen. hazeOnWater asks
drawsSky.

gSky is folded in (D1): its callers move to gPipeline.mSky, and LLSky
goes with the init and cleanup calls that existed only because the sky
was an in-world object (llstartup, llworld, the agent's region hack).
Its destroyGL/restoreGL are now the pipeline's releaseAllGLResources,
restoreGL and cleanup. setWind, setCloudDensity and setMoonDirectionCFR
fed nothing and go, and with setWind the region's average wind
LLAppViewer::idle took for it; setSunDirectionCFR keeps its one effect,
the sun bump maps are lit by. LLFace's moon ray and the sun and moon
beacons take their directions from LLEnvironment.

Deleted: LLVOSky, LLVOWLSky, LLDrawPoolSky, LLDrawPoolWLSky, POOL_SKY,
POOL_WL_SKY, LL_VO_SKY, LL_VO_WL_SKY and their special cases, the cull
pushes, the pool members and their lookups, the drawable's sky case, the
pipeline's unread LLCullResult mSky, and the bump pool's uncalled
bindCubeMap/unbindCubeMap. RENDER_TYPE_SKY and RENDER_TYPE_WL_SKY stay,
beside RENDER_TYPE_CLOUDS outside the pool range; nothing persists pool
or render-type numbers (the menu names its types by string).

LLAtmospherics' constructor read two settings, SkyAmbientScale and
SkyNightColorShift, into members nothing reads; ALSky constructs it
with the pipeline, before settings load, so those reads go, and the
two settings with them (settings.xml and their Portuguese comments).

LLGLSLShader::bindTexture given a null texture or render target, and
bindDepthTexture given a null target, bind nothing and return the unit
all the same, let go of what an earlier bind left there, so the draw
reads none of it; ALTextureSlot::bindFast given a null texture, or one
with no GL image, lets its slot go likewise. llglslshader_gl_test binds
each null over a unit holding a target and finds the unit let go, and
the disable a reader pairs with the bind finding nothing to release
under the debug checks.

quadCoord, the CPU mirror of skyQuadCoord that only alskylayers_test
calls, moves out of ALSkyLayers into it. alskydome_gl_test takes the
sky tests' shared helpers (alskyraster_gl.h, which RAINBOW_SKY joins)
in place of its own copies, and holds the haze on water against itself
with its weight floor at zero: over a made-up scene whose dome weight
runs from zero through the floor, the two are one picture where the
weight is zero or at the floor and past it, and under the floor differ
by no more than the floor allows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Where reflection probes are off (the low feature class, every Intel
legacy session, RenderReflectionsEnabled off) the shiny and probe-less
reflections read an environment cube. The CPU built it through
LLAtmospherics a face a frame. Now ALSky bakes it from windlightDome
whenever the sky changes, at most every quarter second as before, then
mips it (D2):

- ALSkyCube (alrender): each GL face's directions in the agent's frame
  the readers look it up in, and their turn into the dome's frame
  (toDome, ALFarPlane::skyFrame); the cube's storage (RGBA8, 64 a face
  as before, every level, LEVELS worked from SIZE), counted whole as an
  image's (LLImageGLMemory::OTHER_TEXTURE), every face and level mid
  grey as the readers take it (NEUTRAL) until its first bake;
  and the bake. The six faces draw side by side in one pass over a
  strip, then are copied into their faces and mipped
  (LLImageGL::generateMipmaps), so nothing is bound over the program's
  own texture units between them.
- deferred/skyCubeF.glsl: windlightDome along each texel's direction,
  halved as the haze takes it, the scale the readers double
  (applyLegacyEnv). Built only without probes (ALShaderInputs).
- ALRenderResourcePlan::Id::EnvironmentCube: a persistent texture of the
  pipeline's own, wanted only without probes. The reconcile makes and
  frees it; made neutral, it is bound from the frame it is made in,
  wherever the plan wants it, and where it is not the unit is let go.
  RenderWater no longer decides whether it exists.
- The bake runs when windlightDome's inputs change: its Environment
  block terms, its loose uniforms, and the rainbow and halo maps as far
  as they have loaded. A term counts as changed only past
  ALSkyCube::TERM_TOLERANCE, 0.0005, of the larger of its two values
  (termsAlike), the comparison the CPU cube made of its atmospherics
  (approximatelyEqual): a sky that has drifted less differs from its
  bake by under a step of its eight bits.
  The fog colour the tracker's beacons read follows the same change,
  with probes on too, where it was never updated.
- Both run from ALSky::followEnvironment, once LLEnvironment::update
  has packed the Environment block the main view takes, whether or not
  the sky is drawn: the cube lights the reflections, and the fog colour
  the beacons. A bake that cannot run, its program not built or its
  strip not made, leaves the sky untaken, and is tried again at the
  same interval until one does.

LLAtmospherics keeps the fog colour alone: the sky texture's path,
LLHaze and the atmospherics' comparisons go, and with them the members
of AtmosphericsVars nothing reads (the haze below the clouds, the
clouds' colours and density, the distance multiplier, the cloud shadow
and the light transmittance). LLHeavenBody keeps its disk and its quad
alone: the quads turn by the current sky's rotations, and nothing read
its copies of the directions and turns. ALSkyDome, the dome's mesh,
which nothing in the viewer draws, moves out of alrender into the sky
tests' support (alskyraster_gl.h), for the raster sky they draw.

alskycube_test pins each texel's direction against GL's face selection
table, and holds termsAlike to the tolerance either side of it.
alskycube_gl_test bakes with the viewer's program and samples every
texel against windlightDome (0.56/255 at most, the rounding to eight
bits), checks each face's last level against the mean of its first,
checks that a cube never baked is complete and neutral at every level,
read back and through the trilinear lookup the readers take, and that
its storage is counted whole from its making to its deletion, and
reports the bake against the old CPU cube, kept in the test.
That cube differs on purpose. It held WindLight's colour along the
opposite direction of each lookup (calcSkyColorInDir negates every
axis), at a quarter saturation, and below -0.02 a dim fog-grey ground.
Midday: above its horizon 14.6/255 on average (83 at most), below it
72.5/255 (115). Sunset: 17.9 (242, at the sun's glow) and 22.6 (139).
Moonlit night: 2.2 (16) and 8.9 (19). Turning the mirror round changes
little (15.7 for 14.6 at midday above the horizon), and full saturation
with the haze in place of the ground leaves 13.4 above and 57.1 below:
most of it is the old CPU model itself, which has no below-cloud blend,
rainbow or halo, and dims the sun again by the haze's transmittance
along the ray.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sky is no longer a viewer object, a pool or a cull push: say what
holds and draws it, beside the water's paragraph, and drop LLVOWLSky,
POOL_WL_SKY and the sky pushes from the cutout's choke points.

The paragraph says when ALSky takes the sky, at the start of display
before the mirrors draw it and again once the environment update has
moved it on, before the main view; that the environment cube is
neutral grey until its first bake; that the star field is laid out on
the General queue; and that each view takes what it draws of the sky
once, at its G-buffer's clear, which clears the stars' attachment only
where the view draws them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LLAtmospherics worked out three things on each sky update: the fog
colour the tracker's beacons fade into, a fog distance from the fog
ratio, and a GL fog colour, the water's below its surface. Only the
first has a reader. The fog distance went into a local, and nothing
has asked for the GL fog colour or the ratio since before the sky moved
to ALSky (develop's LLSky::getFogRatio and LLVOSky::getGLFogColor had
no caller either).

So the ratio goes (ALSky::setFogRatio/getFogRatio, its first-update
read of RenderFogRatio and the setting's listener), and so do the GL
fog colour and its underwater branch with the two settings only it
read, WaterGLFogDepthScale and WaterGLFogDepthFloor. updateFog takes
the direction to the light alone, and the file drops the includes only
those paths needed.

RenderFogRatio goes too, from settings.xml and its Portuguese comment,
the three feature tables and the feature manager's skipped list. The
test spinner floater's control spinner takes RenderDebugNormalScale in
its place, a setting only the normals' debug display reads, its range
0 to 1 at two decimals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The flare's state pass probes how much of the sun or the moon the world
hides over the body's own angular radius. It worked that radius out by
hand from what ALSkyLayers::bodyCorners builds the quad from: the factor,
the disk radius, the sky's scale and the quad's growth toward the
horizon, 1 + (1 - z) / 4, the mean of its 1.3 and 1.2. It now reads the
quad the sky draws (LLHeavenBody::angularHalfSize, the mean of the
corners' half-width and half-height over their distance), so retuning
the disc moves the probe with it.

The two agree wherever a body is up and its scale is at least 0.01, the
floor the old sum held it to. They differ only while neither body is
up, when the pass takes the moon and the old sum the direction the
lighting falls back to, level, where the moon's quad lies lower and
larger; and at a scale under 0.01, where the probe now shrinks with the
quad.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ALStarField::pointDraws gives glMultiDrawArrays one run a cell in view,
the prefix of it bright enough to show, so at dusk a view draws over a
hundred short runs. Drawing every point of the cells in view instead,
the runs that meet merged, and leaving the faint stars out in the vertex
stage would make the runs few. alstarfield_gl_bench measures the two at
the default count, 1920x1080 into R11G11B10F, through a level 60-degree
view and a 100-degree one 60 degrees up, at faintest 0 (night) and 20,
40, 80 and 140 (dusk), on NVIDIA:

- the CPU's time is the same either way, 1.2-1.4 us and 2.2-2.3 us:
  glMultiDrawArrays is one call whatever its runs;
- at night the two draw the same runs, 5.2 against 5.1 us and 14.2
  against 14.2 us of GPU;
- at dusk the prefixes are cheaper on the GPU, the more so the fainter
  the stars left out: 3.5 against 3.7 us at faintest 20 and 0.8 against
  1.4 us at 140 in the level view (121 runs against 13), 8.8 against 8.8
  us and 1.8 against 3.5 us in the wide one (298 runs against 16). A
  vertex left out still runs, and a run costs less than the vertices.

So pointDraws keeps its prefixes, and the benchmark stays as the reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The comments carried over from the raster clouds and aurora told how
each fade came to be: what WindLight drew, a rate the aurora's fade
once had, a hard edge a user once saw. They now say what each fade
does and, for the clouds, why SL-10751's fade is not the one used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A comma in a Catch2 test spec means "or", so a name with one cannot be
run by its name alone. Seven of alwatersurface_gl_test's cases had one;
they read the same without it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LLGLSLShader::addConstant defined LL_SHADER_CONST_CLOUD_MOON_DEPTH and
LL_SHADER_CONST_STAR_DEPTH into a program's permutations (SL-14113), and
no shader reads either. The raster cloud and moon programs that took
the first are gone, and the star program's second only added a dead
key to its permutations. The enum, the two tables and addConstant go,
with the star program's call and the GL tests' copies of it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gDeferredHighlightProgram (deferred/highlightF.glsl) was built and
unloaded but never bound: the highlights draw through gHighlightProgram
and its normal and specular twins, forward. It was the last program to
flag a fragment in front of the far plane SKIP_ATMOS but one: class 1's
material program (deferred/materialF.glsl), which writes a flat magenta
into the albedo with no normal. The soften pass showed such a pixel
through skyColor, the sky's old decode: with the emissive buffer it
read the emissive, which that program leaves black, and scaled it by
sky_hdr_scale. It now shows the albedo as it is, linear through the
sRGB target's decode, and softenLightF neither declares sky_hdr_scale
nor keeps skyColor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 102 files, which is 2 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ad731d9e-ed9e-4d06-8700-688d69acbf7b
Commits

Reviewing files that changed from the base of the PR and between 54e3ab6 and 3cc20b4.

Files selected for processing: 102
  • doc/ARCHITECTURE.md
  • indra/alrender/CMakeLists.txt
  • indra/alrender/alrenderresourceplan.cpp
  • indra/alrender/alrenderresourceplan.h
  • indra/alrender/alskycube.cpp
  • indra/alrender/alskycube.h
  • indra/alrender/alskydome.cpp
  • indra/alrender/alskydome.h
  • indra/alrender/alskylayers.cpp
  • indra/alrender/alskylayers.h
  • indra/alrender/alstarfield.h
  • indra/alrender/tests/alrenderresourceplan_test.cpp
  • indra/alrender/tests/alskycomposite_gl_test.cpp
  • indra/alrender/tests/alskycube_gl_test.cpp
  • indra/alrender/tests/alskycube_test.cpp
  • indra/alrender/tests/alskydome_gl_test.cpp
  • indra/alrender/tests/alskylayers_gl_test.cpp
  • indra/alrender/tests/alskylayers_test.cpp
  • indra/alrender/tests/alskyraster_gl.h
  • indra/alrender/tests/alstarfield_gl_bench.cpp
  • indra/alrender/tests/alstarfield_gl_test.cpp
  • indra/alrender/tests/alstarfield_test.cpp
  • indra/alrender/tests/alwatersurface_gl_test.cpp
  • indra/llrender/altextureslot.cpp
  • indra/llrender/altextureslot.h
  • indra/llrender/llglslshader.cpp
  • indra/llrender/llglslshader.h
  • indra/llrender/llshadermgr.cpp
  • indra/llrender/llshadermgr.h
  • indra/llrender/tests/llglslshader_gl_test.cpp
  • indra/newview/CMakeLists.txt
  • indra/newview/alsky.cpp
  • indra/newview/alsky.h
  • indra/newview/app_settings/settings.xml
  • indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl
  • indra/newview/app_settings/shaders/class1/deferred/skyAuroraF.glsl
  • indra/newview/app_settings/shaders/class1/deferred/skyCloudsF.glsl
  • indra/newview/app_settings/shaders/class1/deferred/skyCompositeF.glsl
  • indra/newview/app_settings/shaders/class1/deferred/skyCubeF.glsl
  • indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
  • indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
  • indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
  • indra/newview/featuretable.txt
  • indra/newview/featuretable_linux.txt
  • indra/newview/featuretable_mac.txt
  • indra/newview/llagent.cpp
  • indra/newview/llappviewer.cpp
  • indra/newview/lldrawable.cpp
  • indra/newview/lldrawpool.cpp
  • indra/newview/lldrawpool.h
  • indra/newview/lldrawpoolalpha.cpp
  • indra/newview/lldrawpoolavatar.cpp
  • indra/newview/lldrawpoolbump.cpp
  • indra/newview/lldrawpoolbump.h
  • indra/newview/lldrawpoolsimple.cpp
  • indra/newview/lldrawpoolsky.cpp
  • indra/newview/lldrawpoolsky.h
  • indra/newview/lldrawpoolterrain.cpp
  • indra/newview/lldrawpooltree.cpp
  • indra/newview/lldrawpoolwlsky.cpp
  • indra/newview/lldrawpoolwlsky.h
  • indra/newview/llenvironment.cpp
  • indra/newview/llface.cpp
  • indra/newview/llfeaturemanager.cpp
  • indra/newview/llflexibleobject.cpp
  • indra/newview/llfloatergodtools.cpp
  • indra/newview/llfloaterpreference.cpp
  • indra/newview/llglsandbox.cpp
  • indra/newview/lllegacyatmospherics.cpp
  • indra/newview/lllegacyatmospherics.h
  • indra/newview/llsettingsvo.cpp
  • indra/newview/llsky.cpp
  • indra/newview/llsky.h
  • indra/newview/llstartup.cpp
  • indra/newview/llsurfacepatch.cpp
  • indra/newview/lltoolgun.cpp
  • indra/newview/lltoolmorph.cpp
  • indra/newview/lltracker.cpp
  • indra/newview/llviewercontrol.cpp
  • indra/newview/llviewerdisplay.cpp
  • indra/newview/llviewerjointmesh.cpp
  • indra/newview/llviewermessage.cpp
  • indra/newview/llviewerobject.cpp
  • indra/newview/llviewerobject.h
  • indra/newview/llviewerobjectlist.cpp
  • indra/newview/llviewershadermgr.cpp
  • indra/newview/llviewershadermgr.h
  • indra/newview/llviewerwindow.cpp
  • indra/newview/llvoavatar.cpp
  • indra/newview/llvograss.cpp
  • indra/newview/llvopartgroup.cpp
  • indra/newview/llvosky.cpp
  • indra/newview/llvosky.h
  • indra/newview/llvosurfacepatch.cpp
  • indra/newview/llvovolume.cpp
  • indra/newview/llvowlsky.cpp
  • indra/newview/llvowlsky.h
  • indra/newview/llworld.cpp
  • indra/newview/pipeline.cpp
  • indra/newview/pipeline.h
  • indra/newview/skins/default/xui/en/floater_test_spinner.xml
  • indra/newview/skins/default/xui/pt/settings_comments.xml

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

quadCoord left alskylayers.cpp for alskylayers_test.cpp on this branch,
so its scale-free parallel test is carried to the test's copy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RyeMutt and others added 2 commits October 27, 2026 08:26
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A meteor end on to the camera has its two ends apart on the screen by
rounding alone. packMeteors left a streak out only where that came to
exactly nothing, so whether it packed one hung on how the compiler fused
the arithmetic: the sanitized Clang build packed four of the layers
test's meteors where every other build packed five. A streak shorter
than a hundredth of a pixel each way is now left out, as the CPU test's
end on meteor already was. Such a streak covers no pixel's centre but
by chance, and the old program's sliver for this one drew nothing.

The CPU test adds an end on meteor whose head rounding has moved, which
packMeteors packed before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Martin-Pitt pushed a commit to Martin-Pitt/Alchemy-Skooma that referenced this pull request Oct 27, 2026
The Windows ARM Tests build stopped at the link of xui_translate_repair
(AlchemyViewer#581, AlchemyViewer#584) and of llui_libtest (AlchemyViewer#578) with "The process cannot access
the file because it is being used by another process." The half of the
command that failed is the POST_BUILD "vcpkg z-applocal" that vcpkg's
toolchain hangs on every executable declared while VCPKG_APPLOCAL_DEPS
is on, and the three llui utilities, ready at the same moment, link
together.

The directory they share, sharedlibs/<config>, is not what fails. They
import no port's DLL on Windows, where the spell checker is the
system's, so z-applocal copies nothing. Eighty concurrent z-applocal
runs, each into a directory of its own, fail the same way 3 times in
640, and eighty concurrent "vcpkg version" runs 6 times in 640: a start
of vcpkg.exe beside another fails now and then, as d5095f9 found for
the test binaries.

So these are declared with the step off, as al_add_test_binary declares
a test: the three utilities, http_texture_load (the other executable in
sharedlibs/<config>) and llimage_libtest. Each exists only in a tests
build and runs from the build tree; xui_overlay_check's ctest entry
still runs with AL_TEST_ENVIRONMENT's PATH. Serializing them instead
would leave them racing every other launch of vcpkg.exe in the build,
and a Ninja job pool does nothing under MSBuild.

With AL_USE_WINSPELLCHECK turned off, llui links Hunspell's DLL, which
llui_libtest and xui_translate_repair no longer copy into
sharedlibs/<config>; the llui tests, whose PATH names that directory,
would then need vcpkg's bin directory on it. No CI row builds that way.

Proof: a tests-on vs2026-os configure leaves z-applocal on five
projects, alchemy-bin, dullahan_host, media_plugin_cef,
media_plugin_libvlc and template_verifier, and on none of these; the
three utilities build in Release and ctest -R xui_overlay_check passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@RyeMutt
RyeMutt merged commit e9d2331 into develop Oct 27, 2026
39 of 40 checks passed
@RyeMutt
RyeMutt deleted the rye/sky-p4-alsky branch October 27, 2026 23:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant