Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/Modules/MaterialSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class MemTexRegen : public ITextureRegenerator {
};

REDECL(MaterialSystem::UncacheUnusedMaterials);
REDECL(MaterialSystem::CacheUsedMaterials);
REDECL(MaterialSystem::CreateMaterial);

DETOUR(MaterialSystem::UncacheUnusedMaterials, bool bRecomputeStateSnapshots) {
Expand All @@ -56,6 +57,22 @@ DETOUR(MaterialSystem::UncacheUnusedMaterials, bool bRecomputeStateSnapshots) {
return result;
}

// CacheUsedMaterials ends in CTextureManager::ForceAllTexturesIntoHardware,
// which queues a draw of every listed texture without referencing it. When an
// entity released its last reference to a texture earlier in the frame (the
// client runs this after every full update, which recreates all entities), the
// render thread frees that texture before it gets to the preload draw, which
// then crashes. `record` right after a load hits this on maps with a playing
// movie screen (mp_coop_wall_5). Turning threading off for the call runs the
// pending queue first, like the engine does around screenshots.
DETOUR(MaterialSystem::CacheUsedMaterials) {
auto AllowThreading = materialSystem->materials->Original<_AllowThreading>(Offsets::AllowThreading);
bool allowed = AllowThreading(thisptr, false, 0);
auto result = MaterialSystem::CacheUsedMaterials(thisptr);
AllowThreading(thisptr, allowed, 0);
return result;
}

DETOUR_T(IMaterial *, MaterialSystem::CreateMaterial, const char *pMaterialName, void *pVMTKeyValues) {
if (sar.game->Is(SourceGame_Portal2 | SourceGame_Portal2_2011 | SourceGame_PortalReloaded | SourceGame_PortalStoriesMel)) {
// Patched by Valve, no need for us to do it again
Expand Down Expand Up @@ -88,6 +105,9 @@ bool MaterialSystem::Init() {
if (this->materials) {
this->materials->Hook(MaterialSystem::UncacheUnusedMaterials_Hook, MaterialSystem::UncacheUnusedMaterials, Offsets::UncacheUnusedMaterials);
this->materials->Hook(MaterialSystem::CreateMaterial_Hook, MaterialSystem::CreateMaterial, Offsets::CreateMaterial);
if (Offsets::CacheUsedMaterials) {
this->materials->Hook(MaterialSystem::CacheUsedMaterials_Hook, MaterialSystem::CacheUsedMaterials, Offsets::CacheUsedMaterials);
}

this->RemoveMaterial = this->materials->Original<_RemoveMaterial>(Offsets::RemoveMaterial);

Expand Down
3 changes: 3 additions & 0 deletions src/Modules/MaterialSystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ class MaterialSystem : public Module {
using _KeyValues_SetString = void(__rescall*)(void* thisptr, const char *key, const char *val);
_KeyValues_SetString KeyValues_SetString = nullptr;

using _AllowThreading = bool(__rescall *)(void *thisptr, bool bAllow, int nServiceThread);

public:
DECL_DETOUR(UncacheUnusedMaterials, bool bRecomputeStateSnapshots);
DECL_DETOUR(CacheUsedMaterials);
DECL_DETOUR_T(IMaterial *, CreateMaterial, const char *pMaterialName, void *pVMTKeyValues);

bool Init() override;
Expand Down
2 changes: 2 additions & 0 deletions src/Offsets/Portal 2 10090.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ OFFSET_DEFAULT(snd_p, 98, 116)
OFFSET_DEFAULT(snd_vol, 108, 122)
OFFSET_DEFAULT(StartTouch, 102, 103)
OFFSET_DEFAULT(UncacheUnusedMaterials, 77, 77)
OFFSET_DEFAULT(CacheUsedMaterials, 78, 78) // client -> "LevelInitPreEntity - CacheUsedMaterials - Start" xref -> CPrecacheRegister::LevelInitPreEntity() -> following vtable call -> CMaterialSystem::CacheUsedMaterials
OFFSET_DEFAULT(AllowThreading, 135, 135) // materialsystem -> "Queued Material System: ENABLED!\n" xref -> CMaterialSystem::AllowThreading -> vtable index
OFFSET_DEFAULT(CreateMaterial, 81, 81)
OFFSET_DEFAULT(FindMaterial, 82, 82)
OFFSET_DEFAULT(CreateProceduralTexture, 91, 91)
Expand Down
3 changes: 3 additions & 0 deletions src/Offsets/Portal 2 8151.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "Offsets/Portal 2 10090.hpp"
// Portal Stories: Mel, Reloaded

OFFSET_DEFAULT(CacheUsedMaterials, 0, 0) // texture preload fix only verified on Portal 2 10090
OFFSET_DEFAULT(AllowThreading, 0, 0)

OFFSET_LINUX(tickcount, 74)
OFFSET_LINUX(interval_per_tick, 82)
OFFSET_LINUX(demoplayer, 92)
Expand Down
Loading