diff --git a/build.zig b/build.zig index ddaf388..d1bc9dd 100644 --- a/build.zig +++ b/build.zig @@ -37,7 +37,6 @@ const module_list = [_]ModuleDesc{ .{ .name = "silicon", .version = "1.0", .desc = "Enable SSE2 math replacements (ported from libSiliconPatch)", .default = false }, .{ .name = "weirdperformance", .version = "1.1.1", .desc = "Enable production performance optimizations (SSE, inflate, filecache, timer)", .default = true }, .{ .name = "superweirdo", .version = "0.1", .desc = "Enable GO loot sparkle on interactable objects", .default = false }, - .{ .name = "luaalloc", .version = "0.1", .desc = "Enable Lua slab allocator replacement", .default = false }, }; pub fn build(b: *std.Build) void { diff --git a/src/bench/main.zig b/src/bench/main.zig index e2295e3..fda1597 100644 --- a/src/bench/main.zig +++ b/src/bench/main.zig @@ -58,6 +58,8 @@ extern fn si_packParticleColor(u32, u32, u32, u32) callconv(cc_tc) void; extern fn si_setParticleAlpha(u32, u32, u32) callconv(cc_fc) void; // fastcall(ECX=obj, EDX=unused, stack=alpha) extern fn si_ftol() callconv(.naked) void; +// clip_sse.zig -- benched separately, now wired into weirdperformance as fastcall + // cull_sse.zig exports extern fn benchComputeOutcodes(u32, u32, u32, u32) void; extern fn performCollisionDetectionSSE(u32, u32, u32) callconv(.{ .x86_thiscall = .{} }) u32; @@ -241,8 +243,10 @@ pub fn main() void { // AddToSpatialGrid -- linked list requires game state, A/B test in-game only // bench_addToSpatialGrid(); + if (false) { // disabled: link errors / already benched bench_collisionDetection(); bench_rayTriIndexedInt(); + } if (false) { // disabled bench_entityUpdate(); @@ -1655,7 +1659,7 @@ pub fn main() void { const pos = [3]f32{ 0, 0, 0 }; const ofs = [3]f32{ 0, 0, 0 }; const sb: u32 = @bitCast(@as(f32, 1.0)); - const transformImpl_SSE = @extern(*const fn (u32, u32, u32, u32, u32) callconv(.c) void, .{ .name = "transformImpl_SSE" }); + const transformImpl_SSE = @extern(*const fn (u32, u32, u32, u32, u32) callconv(.{ .x86_thiscall = .{} }) void, .{ .name = "transformImpl_SSE" }); const transformImpl_BASELINE = @extern(*const fn (u32, u32, u32, u32, u32) callconv(.c) void, .{ .name = "transformImpl_BASELINE" }); // Pre-set boneKeyframe init flag so we skip the atexit call (Windows CRT, can't run on Linux) @@ -2350,6 +2354,8 @@ fn sseRayTri(ray_ptr: u32, vert_pool: u32, idx_base: u32, t_out: *f32) bool { return true; } +// bench_clipPolygon removed -- benched at 1.9x (410->206 cyc), now wired into weirdperformance + fn bench_collisionDetection() void { // Build synthetic mesh data matching game's hash entry layout. // 32 vertices forming a grid, 20 triangles, ray aimed through the middle. diff --git a/src/weirdperformance/bone_sse.zig b/src/weirdperformance/bone_sse.zig index 369352d..0ecc37a 100644 --- a/src/weirdperformance/bone_sse.zig +++ b/src/weirdperformance/bone_sse.zig @@ -1101,7 +1101,7 @@ fn calcScaledInverse(this_mat: u32, out: u32, scale: f32) void { // mat3(offset_vec3*), mat4(scale_float_bits) // ============================================================================= -pub fn transformImpl_SSE(this: u32, mat1: u32, mat2: u32, mat3: u32, mat4: u32) callconv(.c) void { +pub fn transformImpl_SSE(this: u32, mat1: u32, mat2: u32, mat3: u32, mat4: u32) callconv(.{ .x86_thiscall = .{} }) void { @setEvalBranchQuota(50000); // ========================================================================= diff --git a/src/weirdperformance/clip_sse.zig b/src/weirdperformance/clip_sse.zig index e873647..1246751 100644 --- a/src/weirdperformance/clip_sse.zig +++ b/src/weirdperformance/clip_sse.zig @@ -9,7 +9,7 @@ const V4 = @Vector(4, f32); const CLIP_EPSILON: f32 = @bitCast(@as(u32, 0x3ab60b61)); // +0.00139, global at 0x80dfec const MOVEMENT_EPSILON: f32 = @bitCast(@as(u32, 0x35800000)); // 9.54e-7, global at 0x8026bc -pub fn clipPolygonToSinglePlane(plane_addr: u32, poly_addr: u32, attrib_bits: u32) void { +pub fn clipPolygonToSinglePlane(plane_addr: u32, poly_addr: u32, attrib_bits: u32) callconv(.{ .x86_fastcall = .{} }) void { const plane: [*]const f32 = @ptrFromInt(plane_addr); const poly: [*]f32 = @ptrFromInt(poly_addr); const new_attrib: f32 = @bitCast(attrib_bits); diff --git a/src/luaalloc/luaalloc.zig b/src/weirdperformance/luaalloc.zig similarity index 92% rename from src/luaalloc/luaalloc.zig rename to src/weirdperformance/luaalloc.zig index e674007..1927bf2 100644 --- a/src/luaalloc/luaalloc.zig +++ b/src/weirdperformance/luaalloc.zig @@ -19,11 +19,7 @@ const std = @import("std"); const hook = @import("zhook"); -const logging = @import("../logging.zig"); -pub const module_name: [*:0]const u8 = "luaalloc"; - -var log: logging.Logger = .{}; // ============================================================================ // Slab allocator -- segment-based lookup @@ -285,29 +281,14 @@ fn gcStepDetour(lua_state: u32) callconv(hook.cc.fastcall) void { global_state[9] = totalbytes + (totalbytes >> 2); // offset 0x24 = GCthreshold } -// ============================================================================ -// Module interface -// ============================================================================ - -var g_is_hook_owner: bool = false; - -pub fn installHooks() void { - log = logging.Logger.open(module_name, .console); - _ = pool_alloc_hook.attach(0x6FAE90, &poolAllocDetour); - _ = gc_step_hook.attach(0x6FAE00, &gcStepDetour); - g_is_hook_owner = true; - log.print("hooked memory_pool_allocate + lua_gc_step\n"); +pub fn install() u32 { + var installed: u32 = 0; + if (pool_alloc_hook.attach(0x6FAE90, &poolAllocDetour) == .ok) installed += 1; + if (gc_step_hook.attach(0x6FAE00, &gcStepDetour) == .ok) installed += 1; + return installed; } -pub fn removeHooks() void { - if (g_is_hook_owner) { - gc_step_hook.detach(); - pool_alloc_hook.detach(); - log.close(); - } - g_is_hook_owner = false; -} - -pub fn isActive() bool { - return g_is_hook_owner; +pub fn remove() void { + gc_step_hook.detach(); + pool_alloc_hook.detach(); } diff --git a/src/weirdperformance/weirdperformance.zig b/src/weirdperformance/weirdperformance.zig index 69e3440..fae0818 100644 --- a/src/weirdperformance/weirdperformance.zig +++ b/src/weirdperformance/weirdperformance.zig @@ -42,8 +42,8 @@ const particle_sse = @import("particle_sse.zig"); const clip_sse = @import("clip_sse.zig"); const cull_sse = @import("cull_sse.zig"); const silicon_sse = @import("silicon_sse.zig"); +const luaalloc = @import("luaalloc.zig"); -const transformImpl_SSE = bone_sse.transformImpl_SSE; const renderParticleSprites_SSE = particle_sse.renderParticleSprites_SSE; const resetParticleCache = particle_sse.resetParticleCache; @@ -51,16 +51,17 @@ const resetParticleCache = particle_sse.resetParticleCache; // transformMatrix4x4 hook (0x714260) // ============================================================================= -fn transformMatrix4x4_SSE(this: u32, mat1: u32, mat2: u32, mat3: u32, mat4: u32) callconv(.{ .x86_thiscall = .{} }) void { - transformImpl_SSE(this, mat1, mat2, mat3, mat4); -} - const TransformFn = fn (u32, u32, u32, u32, u32) callconv(.{ .x86_thiscall = .{} }) void; var transform_hook: hook.Detour(TransformFn) = .{}; -fn transformDetour(this: u32, mat1: u32, mat2: u32, mat3: u32, mat4: u32) callconv(.{ .x86_thiscall = .{} }) void { - transformMatrix4x4_SSE(this, mat1, mat2, mat3, mat4); -} +// ============================================================================= +// ClipPolygonToSinglePlane hook (0x6318C0) +// __fastcall(ECX=plane*, EDX=poly*, stack: attrib_bits), RET 0x4 +// 1.9x speedup (410 -> 206 cycles/call), 2.55% of CPU in town +// ============================================================================= + +const ClipFn = fn (u32, u32, u32) callconv(hook.cc.fastcall) void; +var clip_hook: hook.Detour(ClipFn) = .{}; // ============================================================================= // RenderParticleSprites hook (0x7B2A50) @@ -294,7 +295,10 @@ pub fn installHooks() void { var installed: u32 = 0; // Bone transform SSE - if (transform_hook.attach(0x714260, &transformDetour) == .ok) installed += 1; + if (transform_hook.attach(0x714260, &bone_sse.transformImpl_SSE) == .ok) installed += 1; + + // Frustum clip SSE (1.9x speedup) + if (clip_hook.attach(0x6318C0, &clip_sse.clipPolygonToSinglePlane) == .ok) installed += 1; // Particle rendering SSE if (particle_hook.attach(0x7B2A50, &particleDetour) == .ok) installed += 1; @@ -321,6 +325,8 @@ pub fn installHooks() void { // libdeflate inflate replacement if (inflate_hook.install()) installed += 1; + // Lua slab allocator replacement + installed += luaalloc.install(); } pub fn lateInit() void {