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.
This commit is contained in:
MarcelineVQ
2026-03-25 12:34:57 -07:00
parent 4274729a77
commit 41ca30cfd5
7 changed files with 1219 additions and 56 deletions
+8 -23
View File
@@ -64,14 +64,9 @@ fn transformMatrix4x4_SSE(this: u32, mat1: u32, mat2: u32, mat3: u32, mat4: u32)
const TransformFn = fn (u32, u32, u32, u32, u32) callconv(.{ .x86_thiscall = .{} }) void;
var transform_hook: hook.Detour(TransformFn) = .{};
var teardown_active: bool = false;
fn transformDetour(this: u32, mat1: u32, mat2: u32, mat3: u32, mat4: u32) callconv(.{ .x86_thiscall = .{} }) void {
if (teardown_active) {
transform_hook.callOriginal(.{ this, mat1, mat2, mat3, mat4 });
} else {
transformMatrix4x4_SSE(this, mat1, mat2, mat3, mat4);
}
transformMatrix4x4_SSE(this, mat1, mat2, mat3, mat4);
}
// =============================================================================
@@ -153,22 +148,14 @@ fn worldUpdateDetour(frame_count: u32) callconv(hook.cc.fastcall) void {
}
// =============================================================================
// Teardown hook (0x491180) — protect bone SSE during logout cleanup
// SSE JMP patches — binary patches at game function addresses
// =============================================================================
const TeardownFn = fn () callconv(.{ .x86_stdcall = .{} }) void;
var teardown_hook: hook.Detour(TeardownFn) = .{};
fn teardownDetour() callconv(.{ .x86_stdcall = .{} }) void {
teardown_active = true;
teardown_hook.callOriginal(.{});
teardown_active = false;
}
// =============================================================================
// Silicon SSE JMP patches — binary patches at game function addresses
// =============================================================================
// cull_sse.zig
extern fn performSpatialCulling(u32, u32, u32) callconv(.{ .x86_thiscall = .{} }) u32;
extern fn performCollisionDetectionSSE(u32, u32, u32) callconv(.{ .x86_thiscall = .{} }) u32;
// silicon_sse.zig
const sse = struct {
extern fn si_normalizeVec3() callconv(.naked) void;
extern fn si_mulMat3x4(u32, u32, u32) callconv(.{ .x86_fastcall = .{} }) u32;
@@ -236,6 +223,8 @@ fn installPatches() u32 {
.{ .target = 0x686820, .replacement = @intFromPtr(&sse.si_translateBoundingVol), .name = "translateBoundingVol" },
.{ .target = 0x6ABC40, .replacement = @intFromPtr(&sse.si_processLinkedListCollision), .name = "processLinkedListCollision" },
.{ .target = 0x686000, .replacement = @intFromPtr(&sse.si_frustumCullBBox), .name = "frustumCullBBox" },
.{ .target = 0x6B8C60, .replacement = @intFromPtr(&performSpatialCulling), .name = "PerformSpatialCulling" },
.{ .target = 0x6B88E0, .replacement = @intFromPtr(&performCollisionDetectionSSE), .name = "performCollisionDetection" },
};
var count: u32 = 0;
@@ -275,9 +264,6 @@ pub fn installHooks() void {
// Per-frame cache reset
if (world_update_hook.attach(0x482EA0, &worldUpdateDetour) == .ok) installed += 1;
// Teardown guard
if (teardown_hook.attach(0x491180, &teardownDetour) == .ok) installed += 1;
// Silicon SSE binary patches
_ = installPatches();
@@ -299,7 +285,6 @@ pub fn removeHooks() void {
particle_hook.detach();
glyph_hook.detach();
world_update_hook.detach();
teardown_hook.detach();
log.close();
mod_mutex.release(&g_mutex);
}