mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-24 13:36:18 +02:00
Descriptor heaps: dense custom maps no longer overflow the GPU's descriptor heap and crash it
The renderer gives each frame 131,072 shader-visible descriptors past a persistent 120,000, in heaps of 333,333. Dense custom maps (the Los Santos City sublevels, San Andreas) draw more than that in a frame, and the renderer wrote past the end of the heap: shaders read garbage descriptors, which faulted or hung the GPU (page faults at nonsense addresses, in draws, texture fetches and ray tracing alike). ReSkate now patches the device setup at boot so each heap is D3D12's 1,000,000 and a frame may use 524,288; heaps are 644,288 descriptors. LS-B2, LS-B3 and San Andreas (210,000 a frame at its peak) now hold. Also in this change: - Memory: perf memory owners/heap/gpu/report, a ledger of who commits the game's RAM; the render-resource pool no longer allocates its 115 MB twice; the EadpErrorsData arena is capped at 32 MiB (EA's error reporting is blocked anyway). - Crash reports: tagged with the map, destination, graphics card and driver version (protocol v3), so Sentry can group GPU hangs by map and card. - GPU diagnostics (--gpu-diagnostics): a fuller DRED report, the device-removal and video memory watches, a large-draw watch, a record of which game code made and freed each GPU heap and resource, checks of every GPU address bound, and a meter of each descriptor heap's use. - World pools: peak use of entity pages, render instances and spatial blocks in the log. - dingosdk_mod_mesh_check: checks every MeshSet a mod ships against its geometry; the MeshSet reader now knows static meshes' layout.
This commit is contained in:
1 parent
67d84d5bd7
commit
164fdffbd0
34 files changed
+2968
-216
No files matched your search
@@ -3,10 +3,13 @@
|
||||
#include "Engine/Core/Hooks/hooks.h"
|
||||
#include "Engine/Core/Platform/launcher_support.h"
|
||||
#include "Extension/Boot/startup_interventions.h"
|
||||
#include "Extension/Console/commands.h"
|
||||
#include "Extension/Boot/steam_restart_guard.h"
|
||||
#include "Extension/Boot/user_data_redirect.h"
|
||||
#include "Extension/Boot/ea_app_block.h"
|
||||
#include "Extension/Boot/ea_service_block.h"
|
||||
#include "Extension/Boot/descriptor_heap_size.h"
|
||||
#include "Extension/Boot/eadp_errors_arena.h"
|
||||
#include "Extension/Assets/native_patch_support.h"
|
||||
#include "Extension/Assets/mod_layers.h"
|
||||
#include "Extension/Assets/loose_files.h"
|
||||
@@ -17,6 +20,7 @@
|
||||
#include "Extension/Rendering/display_startup.h"
|
||||
#include "Extension/World/native_route_lookahead.h"
|
||||
#include "Extension/World/native_entity_pages.h"
|
||||
#include "Extension/World/world_pool_usage.h"
|
||||
#include "Extension/World/physics_world_size.h"
|
||||
#include <string>
|
||||
|
||||
@@ -40,6 +44,9 @@ bool initialize_bootstrap(std::uintptr_t base) {
|
||||
return false;
|
||||
}
|
||||
logging::write(logging::Level::info, Channel::hooks, "Microsoft Detours hook service ready.");
|
||||
// The memory ledger, when RESKATE_MEMORY_TRACE asks for it: here, while the game is still
|
||||
// suspended and before the pools below are enlarged, so it sees who makes all of them.
|
||||
console::start_memory_trace_from_environment();
|
||||
error.clear(); ready = start_native_patch_support(base, error);
|
||||
if (!stage(Channel::assets, "Native InitFS/package support", ready, error)) return false;
|
||||
error.clear(); ready = start_mod_layers(base, error);
|
||||
@@ -57,6 +64,9 @@ bool initialize_bootstrap(std::uintptr_t base) {
|
||||
if (!stage(Channel::assets, "Native render-resource pools", ready, error)) return false;
|
||||
error.clear(); ready = start_native_entity_pages(base, error);
|
||||
if (!stage(Channel::world, "Native entity pages (524288 entity/update slots, 1048576 render slots, 16384 spatial blocks/bucket, 128 MiB arena minimum)", ready, error)) return false;
|
||||
// (Diagnostics only: how full those pools get. A mismatch leaves the game as it is.)
|
||||
error.clear(); ready = start_world_pool_usage(base, error);
|
||||
(void)stage(Channel::world, "World pool usage watch", ready, error);
|
||||
error.clear(); ready = start_physics_world_size(base, error);
|
||||
if (!stage(Channel::world, "Physics world pools (65000 static bodies)", ready, error)) return false;
|
||||
error.clear(); ready = start_native_route_lookahead(base, error);
|
||||
@@ -66,12 +76,19 @@ bool initialize_bootstrap(std::uintptr_t base) {
|
||||
// left registered it kept the level from ever finishing its unload (a map change that never
|
||||
// ends, which is worse than the crash). It goes back in once it can release what it skips.
|
||||
if (!stage(Channel::graphics, "Display startup settings", start_display_settings(base), {})) return false;
|
||||
// (Not needed for the game to run: a mismatch leaves the heaps at the game's size, and only
|
||||
// the densest levels outgrow them.)
|
||||
error.clear(); ready = start_descriptor_heap_size(base, error);
|
||||
(void)stage(Channel::graphics, "Descriptor heaps: 1,000,000, with 524,288 a frame", ready, error);
|
||||
error.clear(); ready = start_user_data_redirect(error);
|
||||
if (!stage(Channel::runtime, "Separate game user data", ready, error)) return false;
|
||||
error.clear(); ready = start_ea_app_block(error);
|
||||
if (!stage(Channel::runtime, "EA app launch block", ready, error)) return false;
|
||||
error.clear(); ready = start_ea_service_block(error);
|
||||
if (!stage(Channel::runtime, "EA online services block", ready, error)) return false;
|
||||
// (Not needed for the game to run: a mismatch leaves the arena at the game's size.)
|
||||
error.clear(); ready = start_eadp_errors_arena(base, error);
|
||||
(void)stage(Channel::runtime, "EA error-report arena capped at 32 MiB", ready, error);
|
||||
error.clear(); ready = start_steam_restart_guard(error);
|
||||
return stage(Channel::runtime, launcher::offline_mode() ? "Offline Steam" : "Steam restart guard", ready, error);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user