Commit Graph
38 Commits
Author SHA1 Message Date
MarcelineVQ b12fc820ef Publish source: Unlicense, public README, repo hygiene
The remote was previously a distribution-only point for pre-built DLLs.
This opens the source.

- LICENSE: Unlicense, with a GPL-3.0 carve-out for src/dpslog/WeirdDPSMate
  (a DPSMate fork that keeps its own license)
- README.md replaces the stale internal one with the user-facing docs from
  DLL_README.md, swapping the 'Why No Source Code?' section for build and
  layout notes. DLL_README.md is dropped; one README now serves both.
- RELEASING.md: drop the trim-the-README-per-release dance and the
  remote/WeirdUtils/ distribution clone, both obsolete now
- gitignore agent/editor scratch, build caches, the vendored WSBT addon,
  and the WeirdThreat/uwu-logs checkouts (separate upstream repos)
- Commit outstanding module work: superweirdo, clickthrough portal visuals,
  transform44 decompiles, worldmarkers demo presets, tools/
2026-07-27 21:47:55 -07:00
MarcelineVQ f500147fc7 weirdperformance: f64-intermediate bone transform to eliminate spell/doodad z-fighting
Adds bone_sse64.zig as an f64-intermediate port of transformMatrix4x4, used as
the active hook. M2 bone matrices are built and multiplied as [16]f64 and only
narrow to f32 on final store into the bone output buffer -- matching the x87
original's rounding profile (wide intermediates, single f32 store) and keeping
M2 vertex positions aligned with the terrain/projected-texture pipeline.

Also fixes, in both bone_sse (f32) and bone_sse64:

- Pre-billboard tx/ty/tz accumulation order (row 0 = pz+px+py; rows 1/2 = pz+py+px)
- Post-billboard pos_y/pos_z accumulation order (py+pz+px)
- Post-billboard scale-recompute accumulation order (row0 + row2 + row1)
- Billboard types 2/4 normalize using f64 intermediates (load-bearing for camera
  basis vectors -- pure f32 drifted from x87 by a ULP per axis and caused
  particle emitters to jitter on camera motion)

Additional bone_sse64-specific changes:

- Local attachmentRecursion64 that recurses into transformImpl_SSE64 instead of
  bone_sse.transformImpl_SSE, so attached child models stay on the f64 path
- child_padding (this+0x84) computed with f64 intermediates

bone_sse remains the reference f32 implementation; its struct fields, inline
helpers, and section-loop fns are now `pub` so bone_sse64 can share them
(types/interpolation helpers/post-loop loops). Artifact size is unchanged.

build.zig adds bench_bone_sse64 object; src/bench/main.zig runs the new variant
through the same warmup/timing harness and prints SSE vs SSE64 vs BASELINE
cycles plus a parity check.
2026-04-16 22:58:09 -07:00
MarcelineVQ 5f33944fda luavm: strip to newlstr-only, add Detour overhead bench
A/B results: hash_lookup prefetch/cache both regressed (original is
near-optimal at 59 bytes), VM opcode SSE2 patches were break-even.
Only luaS_newlstr hash pre-check shows consistent 40-45% per-call win.

Drop hash_lookup hook, VM jump table patches, and resize hook. Keep
newlstr Detour with per-call A/B rdtsc and OnWorldUpdate periodic dump.

Add GC_WRITE_BARRIER.md documenting the barrier globals at 0xCEEAC0/C4
found in lua_vm_execute (useful for luagc module).

bench: add Detour overhead micro-benchmark. Simulates zhook's
JMP+trampoline mechanism on mmap'd executable pages. Result: 5 cyc/call
overhead -- negligible vs the ~100 cyc/call newlstr savings.
2026-04-06 16:04:02 -07:00
MarcelineVQ f213f9b617 perf: move luaalloc into weirdperformance, wire clip SSE hook (1.9x)
- luaalloc moved from standalone module to weirdperformance sub-module
- ClipPolygonToSinglePlane SSE hook wired up (410->206 cyc, 2.55% CPU)
- Eliminated calling convention wrappers: clip_sse (fastcall),
  bone_sse (thiscall) match hook conventions directly
2026-04-04 22:39:17 -07:00
MarcelineVQ 14ba112b0d perf: fix deferred divide precision, threadlocal TLS, MSVC target
Removed deferred divide from both ray-tri functions -- the det-scaled
epsilon comparisons lose precision for near-parallel rays, potentially
accepting triangles the original rejects. Downstream SetupBoxFrustum
then writes to wrong globals near 0xCE6738 (SGroupPtr), causing
ERROR #124 on exit.

inflate_hook: replaced manual FS:0x24 thread ID pool with Zig native
threadlocal. Fixes potential crash on Wine where FS segment layout
may differ.

Build: switched from GNU to MSVC ABI (4-5K smaller per DLL, no
.eh_frame unwind tables). Added setjmp.h stub for libdeflate MSVC
build. Added noperf build variant (zig build noperf).
2026-03-26 11:38:33 -07:00
MarcelineVQ 1f318a8565 perf: GUID lookup cache (97% hit, 2.6x)
FindObjectByGUID (0x464890): 4096-entry direct-mapped cache with
validate-on-hit. 97% hit rate at 10K+ calls/frame, reducing from
0.8% to 0.3% frame time. Validates cached pointers by checking
GUID at obj+0x30/+0x34 on every hit.

AddToSpatialGrid (0x6816F0): SSE rewrite attempted, no measurable
gain (memory-bound linked list ops dominate). Not shipped.
2026-03-25 14:46:56 -07:00
MarcelineVQ ad33eb9b90 perf: SSE ray_tri_indexed_int (2.2x), new profiling hooks
rayTriIntersectIndexedInt (0x7C2C40): SSE Moller-Trumbore with deferred
divide, matching original's epsilon thresholds. Parity-tested against
original for edge hits, backfaces, parallel rays, and per-triangle t/uv.
JMP-patched in weirdperformance.

Added transform44 profiling hooks for ray_tri_indexed_int (0x7C2C40)
and ProcessStaticObjectsCulling (0x683BF0).

Bench: added rayTriIndexedInt bench with exhaustive parity tests.
2026-03-25 13:36:33 -07:00
MarcelineVQ 41ca30cfd5 perf: SSE spatial culling, inlined ray-tri, clickthrough CC fix
PerformSpatialCulling (0x6B8C60): Zig rewrite with SSE outcode
computation. 1.4x speedup, JMP-patched in weirdperformance.

performCollisionDetection (0x6B88E0): fully inlined SSE Moller-Trumbore
ray-triangle intersection, eliminating 4 SetVector3 calls and the
ray_tri function pointer call per triangle. ~22 cyc/tri in bench.

Both graduated from transform44 A/B testing to production JMP patches.

entity_sse.zig: reimplementations of UpdateEntityAndChunksPositions and
updateEntitiesInBounds (A/B tested, 1.2x bench, not shipped - memory
bound with negligible real-world gain).

clickthrough: fixed CheckObjectTypePermissions hook from fastcall to
thiscall (ECX preservation), fixed ClntObjMgrObjectPtr from fastcall(4)
to fastcall(5) with correct arg count.

bench: added performCollisionDetection bench with synthetic mesh data
and patched FindOrCreateHashEntry stub.
2026-03-25 12:34:57 -07:00
MarcelineVQ d205693dbb particle: Ghidra decompilations, particle_sse.zig scaffold, bench
- Ghidra C decompilation of RenderParticleSprites (422 lines) and 5
  helper functions (calculateColorValues, matVec3Transform, etc.)
- particle_sse.zig with calcColorValues_SSE (10.7x bench but cache-miss
  bound in-game — needs inlining into full function replacement)
- Bench harness for calcColorValues with correctness check
- build.zig: particle_sse as separate ReleaseFast compilation unit
- colorDetour reverted to pass-through (SSE has no in-game effect due
  to L1 cache misses on scattered ColorCtx structs)
2026-03-23 21:56:57 -07:00
MarcelineVQ 035355b757 perf: FrustumCullBoundingBox SSE replacement, 1.6x speedup
- silicon_sse: si_frustumCullBBox (0x686000) — inline V4 mat*vec3
  transforms, SSE perspective divide, 4-wide horizon buffer scan.
  Benched 1.6x (117→72 cyc/call). Installed via JMP patch (544 bytes,
  won't fit in 380-byte original).
- bench: add frustumCullBBox benchmark with mapped globals, identity
  matrices, and horizon buffer test fixture.
- Remove patch table entry for frustumCullBBox, install via detour hook
  instead (allows future A/B testing if needed).
2026-03-23 20:46:28 -07:00
MarcelineVQ 7819d6d914 perf: findInterpIdx dedup, processLinkedListCollision SSE, permanent t44
- bone_sse: deduplicate findInterpIdx calls in bone loop — rotation's
  search result reused for scale/translation when tracks share temporal
  structure (canReuseInterp guard). Est. ~23% bone loop cycle reduction.
- silicon: SSE replacement for processLinkedListCollision (0x6ABC40,
  1.57% CPU). V4 AABB overlap test replaces 6 x87 FCOMP/FNSTSW.
  Benched at 3.2x speedup (378→115 cyc/call, 8 nodes).
- transform44: remove A/B toggle, always use SSE path (teardown guard
  kept). A/B infrastructure remains for other hooks.
- bench: add processLinkedListCollision benchmark with fake linked list
  test fixture and stubbed addGeometryToBuffer.
2026-03-23 20:27:26 -07:00
MarcelineVQ 10bd922cc3 silicon: fix CC mismatches (normalizeVec3InPlace TC, packParticleColor TC, addVec3ToAccumulator remove phantom scale param, revert classifyPointFrustum/testOBBFrustum to TC); runtime JMP address resolution 2026-03-17 13:33:51 -07:00
MarcelineVQ dc37042e6a silicon: naked asm for transpose/setAlpha/addColor/normalize, remove vec3Dot/distPlane/insideBounds from patches, direct patch transpose (7cy, 3.7x) 2026-03-17 03:52:50 -07:00
MarcelineVQ 4152d1dc78 silicon: JMP patch infrastructure + native CC for all functions, no naked asm except ftol 2026-03-17 03:12:28 -07:00
MarcelineVQ 6140a3a333 silicon_sse: native calling conventions (thiscall/fastcall/stdcall) for all functions, ready for JMP patching 2026-03-17 02:51:50 -07:00
MarcelineVQ 9f2fa5213a bench: best-of-5 for all silicon functions; silicon_sse: V4 column mulMat3x4/InPlace (1.8x/1.7x) 2026-03-17 01:43:16 -07:00
MarcelineVQ 662c854376 silicon_sse: patch-in-place isPointInsideBounds 6cy->5cy (1.2x), naked vucomiss 2026-03-17 01:26:55 -07:00
MarcelineVQ cb0888e0fa silicon_sse: naked FMA asm for vec3Dot (0.4x->0.8x) and distanceToPlane (0.7x->1.0x) 2026-03-17 01:01:07 -07:00
MarcelineVQ 8537587df3 silicon: si_ftol SSE3 FISTTP replacement, bench patch-in-place framework
si_ftol: 9-byte naked asm using FISTTP (SSE3 truncate-from-x87) replaces
the 39-byte FSTCW/FLDCW/FISTP rounding mode dance. 4 vs 7 cycles (1.7x).
13.2M calls/7.5s in-game -- ~13ms savings per period.

Benchmark: patch-in-place at mapped 0x40A2B0, test parity across 19 values,
best-of-5 timing with varying inputs. Framework for all silicon functions.

Also disabled h67 (ConvertPixelsToScreenAlt) probe -- game passes ECX=0
as valid input, thiscall probe crashes on null this.
2026-03-17 00:22:07 -07:00
MarcelineVQ 0419f39833 bench: 2M iterations, baseline 4176 cycles, SSE 3841 (-8%), parity PASS 2026-03-16 15:25:00 -07:00
MarcelineVQ 99b4c8b2d0 bone_sse: f32 findInterpIdx t division, non-inline sections with quota — 3697 cycles (-6%) 2026-03-16 14:12:53 -07:00
MarcelineVQ 22f9e712f4 bench: 100% code path coverage — multi-track ranges, FloatTrack12 mode=0, 9120 bytes parity PASS 2026-03-16 12:34:07 -07:00
MarcelineVQ 4776a979c9 bench: 94% code path coverage, 8988 bytes parity check — all interp modes, billboards, particles, crossfade, attachments 2026-03-16 12:29:31 -07:00
MarcelineVQ 5baa49d97a bench: fix frame_ctr=0 so section functions execute — 3249 cycles, parity PASS 2026-03-16 12:20:22 -07:00
MarcelineVQ 9c215a0bb1 bench: full parity check across all 13 output buffers (8136 bytes), dual BASELINE/SSE 2026-03-16 12:12:57 -07:00
MarcelineVQ 4ed5495219 bench: dual BASELINE/SSE with parity check — 2177 vs 2112 cycles, PASS 2026-03-16 12:10:51 -07:00
MarcelineVQ 4198a00c26 bench: full path coverage + determinism validation — 2065 cycles/call, PASS 2026-03-16 11:57:37 -07:00
MarcelineVQ 75bb38f5af bench: full coverage fixture — 1012 cycles/call (ribbon, particle, attach, billboard, crossfade, clamped, GS, time delta) 2026-03-16 11:50:38 -07:00
MarcelineVQ b6ab4ac59f bench: comprehensive fixture exercising all code paths — 636 cycles/call baseline 2026-03-16 11:46:16 -07:00
MarcelineVQ f119c15b37 bench: comprehensive transform44 fixture — 578 cycles/call baseline (12 bones + texAnim + colorAnim + wordAnim + boneKF) 2026-03-16 11:42:31 -07:00
MarcelineVQ 93100a1a7e bench: add transform44 SSE benchmark — 288 cycles/call baseline (8 bones, 4 animated) 2026-03-16 11:30:06 -07:00
MarcelineVQ c9249c6c96 bench: fix 3 correctness bugs found by benchmarker
mulMat3x4 / mulMat3x4InPlace: translation row had A*B operands swapped.
Original computes A_translation * B_rotation + B_translation, but our
code was doing A_rotation * B_translation + A_translation. Verified by
tracing x87 disassembly: first element loads A[9]*B[col] pattern.
Fixed in both silicon_sse.zig and silicon.zig.

packParticleColor: x87 rounds 127.5 to 128 (round-to-nearest), but SSE
@intFromFloat truncates to 127. Added @round() before @intFromFloat.

42/42 benchmarks now pass correctness. 0 MISMATCHes.
2026-03-15 12:27:59 -07:00
MarcelineVQ 7c88423a41 bench: add remaining silicon functions, total 38 benchmarks
Added 8 more silicon SSE functions to benchmark: normalizeVec3,
testOBBFrustum, calculateSinCos, translateBoundingVol, addToColorAccum,
packParticleColor, setParticleAlpha, and addVec3ToAccumulator (export fn).

Notable results from new entries:
  packParticleColor: 6.8x (109->16) MISMATCH -- alpha byte diff
  setParticleAlpha:  3.4x (24->7)
  calculateSinCos:   3.0x (138->45)
  normalizeVec3:     1.8x (18->10)
  testOBBFrustum:    1.3x (107->81)

3 MISMATCHes total (mulMat3x4, mulMat3x4InPlace, packParticleColor)
need correctness investigation -- likely matrix layout and struct
byte-order differences.
2026-03-15 12:08:59 -07:00
MarcelineVQ 55b4931fcb bench: map WoW PE sections for full-fidelity benchmarking, add silicon SSE
Major bench harness upgrade:
- Maps WoW .text (4MB) and .rdata (160KB) at original virtual addresses
  instead of individual function byte arrays. All CALL targets and float
  constants resolve automatically -- no more manual mapGameConstants().
- Bench binary linked at 0x10000000 to avoid address conflict with WoW
  PE sections at 0x400000-0xD00000.

Added silicon_sse.zig: 18 pure math functions extracted from silicon.zig
as export fn (C ABI) for standalone compilation. Covers frustum culling,
bounding volume ops, quaternion slerp, matrix multiplies, trig, etc.

Silicon benchmark results (all 14 new entries pass correctness):
  checkBoxLineIntersect: 3.2x (72->22)  -- slab AABB intersection
  rotateMatByQuat:       3.1x (172->54) -- quat->mat + mat multiply
  quatSlerp:             2.5x (454->178)
  createZRotMat3x3:      2.5x (140->55)
  createRotMat3x4:       2.2x (163->73)
  normalizeVec3InPlace:  1.8x (34->18)
  mulMat3x4InPlace:      1.6x (106->66) -- MISMATCH (layout diff, needs investigation)
  classifyPointFrustum:  1.5x (60->40)
  mulMat3x4:             1.2x (64->52)  -- MISMATCH (same layout issue)

Two MISMATCH entries on mat3x4 multiply -- likely row/column order
difference between original and our implementation. Correctness needs
verification against game behavior.
2026-03-15 12:04:02 -07:00
MarcelineVQ 008d74ddb6 bench: add original x87 bytes for 22 silicon module functions
Extracted via Ghidra from WoW.exe for the 22 silicon SSE functions that
don't overlap with ssemaths addresses. These cover frustum culling,
bounding volume transforms, quaternion slerp, matrix operations, and
various geometry functions. Ready for benchmarking.
2026-03-15 11:26:38 -07:00
MarcelineVQ b9603c75f9 bench: add inlined x87 vs SSE comparison, update release notes
Inlined benchmarks use x87 inline asm vs direct Zig @Vector code with
no CALL/RET on either side. Shows the true instruction-level comparison
that in-place patching would achieve:

  dotProduct:  x87=3 SSE=1 -> 3.0x (was 0.3x when called)
  evalPoly:    x87=4 SSE=1 -> 4.0x (was 0.7x when called)
  vec3MulScal: x87=3 SSE=2 -> 1.5x (was 0.8x when called)

Every "loser" from the called benchmarks flips to a winner when inlined.
The entire performance gap was function call overhead (~5 cycles), not
instruction quality. Confirms in-place patching as the right strategy.

Also added RADV_TEX_ANISO env var exploration item to release notes and
updated math polyfill section with full benchmark breakdown.
2026-03-14 22:12:04 -07:00
MarcelineVQ 99503f883f bench: fresh data each iteration to fix overflow artifacts
In-place functions (vec3MulAssign, scaleByVec, etc.) were showing fake
speedups (121x, 10x) because repeated application on the same data
caused values to overflow to Inf/NaN. x87 FPU traps on denormals while
SSE handles them in hardware, making the comparison meaningless.

Now each iteration resets from a template copy. Real results show these
functions are ~1.0x (neutral), not 100x wins. The actual winners are
rotMat3x3/4x4 at 2.1x, and several functions where our scalar-through-
pointers approach is slower than the original x87 pipeline (dotProduct
0.3x, evaluatePolynomial 0.4x) — candidates for real SIMD optimization.
2026-03-14 21:41:56 -07:00
MarcelineVQ db28746182 bench: add x86 Linux micro-benchmark harness for math_sse functions
Extracts original x87 FPU bytes from WoW.exe via Ghidra, mmaps them
executable, and benchmarks against our SSE replacements. Covers all 17
UnitXP polyfill functions with correctness validation and cycle counts.

Maps a page at 0x7ff000 for the float 1.0 constant referenced by
rotMat3x3/rotMat4x4/planeNormal via absolute address 0x7ff9d8.

Build: zig build bench / zig build run-bench
2026-03-14 19:29:41 -07:00