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
This commit is contained in:
@@ -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 {
|
||||
|
||||
+7
-1
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
// =========================================================================
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user