Skip to content

Mirror JPH per-arch VECTOR alignment so 32-bit ARM builds#24

Merged
LPGhatguy merged 1 commit into
SecondHalfGames:mainfrom
Solidor777:armv7-alignment
May 11, 2026
Merged

Mirror JPH per-arch VECTOR alignment so 32-bit ARM builds#24
LPGhatguy merged 1 commit into
SecondHalfGames:mainfrom
Solidor777:armv7-alignment

Conversation

@Solidor777

Copy link
Copy Markdown
Contributor

Problem

JoltC's LAYOUT_COMPATIBLE static_asserts in JoltCImpl/JoltC.cpp fail on 32-bit ARM targets (armv7 Android, armv7 Linux):

JoltC/Functions.h:55:1: error: static assertion failed due to requirement
    'alignof(JPC_Vec3) == alignof(JPH::Vec3)':
    align of JPC_Vec3 did not match align of JPH::Vec3

…and the same for JPC_Vec4, JPC_DVec3, JPC_Quat, JPC_Mat44, JPC_DMat44, JPC_RVec3, plus every higher-level struct that contains a vector field (JPC_ShapeCastSettings, JPC_CollideShapeSettings, JPC_BodyManager_DrawSettings, JPC_ContactPoints, JPC_ContactManifold).

Root cause

JoltPhysics/Jolt/Core/Core.h:180 defines:

#else  // 32-bit ARM
    #define JPH_VECTOR_ALIGNMENT 8 // 32-bit ARM does not support aligning on the stack on 16 byte boundaries
    #define JPH_DVECTOR_ALIGNMENT 8
#endif

JoltC's C-side typedefs in JoltC/Functions.h hardcode alignas(16) on JPC_Vec3 / Vec4 / Quat / Mat44 and alignas(32) on JPC_DVec3 / JPC_DMat44. On 32-bit ARM the C-side over-constrains relative to JPH; the static_assert fires.

Fix

Introduce JPC_VECTOR_ALIGNMENT / JPC_DVECTOR_ALIGNMENT macros at the top of JoltC/Functions.h mirroring the same per-arch logic JPH uses (x86 / x86_64 / aarch64 / WASM / E2K → 16/32; 32-bit ARM → 8/8; RISC-V splits on __riscv_xlen; PowerPC + LoongArch → 16/8). Replace the six load-bearing alignas(...) literals on the vector / matrix typedefs with the macros.

The macro values match the original on every 64-bit target, so this is a no-op except on the 32-bit ARM path that previously failed the build.

Verification

  • x86_64-pc-windows-msvc host build: passes (no behaviour change).
  • aarch64-linux-android cross-compile via cargo ndk r26d: passes.
  • armv7-linux-androideabi cross-compile via cargo ndk r26d: passes (previously failed at LAYOUT_COMPATIBLE).

JPH defines `JPH_VECTOR_ALIGNMENT = 8` on 32-bit ARM (per
`JoltPhysics/Jolt/Core/Core.h`: "32-bit ARM does not support
aligning on the stack on 16 byte boundaries"), but the JoltC
C-side typedefs hardcode `alignas(16)` for `JPC_Vec3` / `Vec4` /
`Quat` / `Mat44` (and `alignas(32)` for `JPC_DVec3` / `DMat44`).
The mismatch propagates: every settings struct that contains a
vector field — `JPC_ShapeCastSettings`, `JPC_CollideShapeSettings`,
`JPC_BodyManager_DrawSettings`, `JPC_ContactPoints`,
`JPC_ContactManifold` — fails the `LAYOUT_COMPATIBLE` static_assert
in `JoltCImpl/JoltC.cpp` with `align of JPC_<X> did not match
align of JPH::<X> (16 == 8)`.

Fix: introduce `JPC_VECTOR_ALIGNMENT` / `JPC_DVECTOR_ALIGNMENT`
macros at the top of `JoltC/Functions.h` mirroring JPH's
per-architecture branches (x86 / x86_64 / aarch64 / WASM / E2K
get 16/32; 32-bit ARM gets 8/8; RISC-V splits on `__riscv_xlen`;
PowerPC + LoongArch get 16/8). Replace the six load-bearing
`alignas` literals on the vector / matrix typedefs with the
macros; the value matches the original on every 64-bit target,
so this is a no-op except on the 32-bit ARM path that previously
failed the build.

Verified locally:
- x86_64-pc-windows-msvc host build: passes (no behaviour change)
- aarch64-linux-android cross-compile via cargo-ndk r26d: passes
- armv7-linux-androideabi cross-compile via cargo-ndk r26d: passes
  (previously failed at LAYOUT_COMPATIBLE static_assert)
Solidor777 added a commit to Solidor777/Titan that referenced this pull request May 8, 2026
Opened SecondHalfGames/JoltC#24 carrying the JPC_VECTOR_ALIGNMENT
macros against upstream main (cherry-picked off the in-fork commit;
TITAN PATCH marker stripped so upstream gets a clean diff).

VENDORING.md + TODO.md gain the PR URL. When upstream merges, the
in-fork patch becomes redundant — sync from upstream, bump the
submodule, drop the "Local patches" entry.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@Solidor777

Copy link
Copy Markdown
Contributor Author

Verification breadcrumb: this fix is downstream-validated in CI on the Titan engine repo — titan-jolt-3d cross-compiles via cargo ndk against both aarch64-linux-android (no behaviour change vs. main) and armv7-linux-androideabi (previously failed at the LAYOUT_COMPATIBLE static_assert; now passes). Mobile CI matrix is now a hard PR gate on the Titan side.

Companion infrastructure PR (independent — ships the cargo-ndk integration on joltc-sys/build.rs): SecondHalfGames/jolt-rust#12.

@LPGhatguy LPGhatguy merged commit 573b5e1 into SecondHalfGames:main May 11, 2026
9 checks passed
Solidor777 added a commit to Solidor777/Titan that referenced this pull request May 17, 2026
Opened SecondHalfGames/JoltC#24 carrying the JPC_VECTOR_ALIGNMENT
macros against upstream main (cherry-picked off the in-fork commit;
TITAN PATCH marker stripped so upstream gets a clean diff).

VENDORING.md + TODO.md gain the PR URL. When upstream merges, the
in-fork patch becomes redundant — sync from upstream, bump the
submodule, drop the "Local patches" entry.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Solidor777 added a commit to Solidor777/Titan that referenced this pull request Jun 4, 2026
Opened SecondHalfGames/JoltC#24 carrying the JPC_VECTOR_ALIGNMENT
macros against upstream main (cherry-picked off the in-fork commit;
TITAN PATCH marker stripped so upstream gets a clean diff).

VENDORING.md + TODO.md gain the PR URL. When upstream merges, the
in-fork patch becomes redundant — sync from upstream, bump the
submodule, drop the "Local patches" entry.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

2 participants