From 4acee1d8c6d66223061d919c9a57aac24b515073 Mon Sep 17 00:00:00 2001 From: Mithrand Date: Wed, 11 Mar 2026 10:41:16 +0100 Subject: [PATCH 1/2] Fix to disable options that crash on AMD Navi 32 and Navi 48 Fixes #1001 --- .../swarm/vgui/rd_vgui_settings_video.cpp | 87 ++++++++++++++++++- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/src/game/client/swarm/vgui/rd_vgui_settings_video.cpp b/src/game/client/swarm/vgui/rd_vgui_settings_video.cpp index 77df1fd6c..1aff59005 100644 --- a/src/game/client/swarm/vgui/rd_vgui_settings_video.cpp +++ b/src/game/client/swarm/vgui/rd_vgui_settings_video.cpp @@ -8,6 +8,61 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +static ConVar rd_debug_amd_shadow_workaround("rd_debug_amd_shadow_workaround", "-1", FCVAR_NONE, "Disables some video crashes on specific AMD GPUs [0 = disable (possibly crash), 1 = enable, -1 auto detect] "); + +inline bool IsAffectedByAmdShadowBug() +{ + if (rd_debug_amd_shadow_workaround.GetInt() == -1) { + + MaterialAdapterInfo_t info; + g_pMaterialSystem->GetDisplayAdapterInfo(0, info); + + // XXX: debug + //const char* driverName = "AMD Radeon RX 7900 XTX"; + const char* driverName = info.m_pDriverName; + + DevMsg("Detected GPU: %s\n", info.m_pDriverName); + + // if AMD + if (info.m_VendorID == 0x1002) { + // navi 32 + if (strstr(driverName, "7700") != null) return true; + if (strstr(driverName, "7800") != null) return true; + if (strstr(driverName, "7900") != null) return true; + // navi 48 + if (strstr(driverName, "9070") != null) return true; + // navi 48 pro + if (strstr(driverName, "R9600") != null) return true; + if (strstr(driverName, "R9700") != null) return true; + } + + return false; + } + + return rd_debug_amd_shadow_workaround.GetBool(); +} + +inline void DebugAmdShadowCrash() +{ + DevWarning("Enabling settings to reproduce crash on AMD GPUs...\n"); + + DevMsg("Disabling workaround..\n"); + rd_debug_amd_shadow_workaround.SetValue(0); + + DevMsg("Setting [rd_env_projectedtexture_enabled] to 1\n"); + ConVarRef rd_env_projectedtexture_enabled("rd_env_projectedtexture_enabled"); + rd_env_projectedtexture_enabled.SetValue(1); + + DevMsg("Setting [rd_flashlightshadows] to 1\n"); + ConVarRef rd_flashlightshadows("rd_flashlightshadows"); + rd_flashlightshadows.SetValue(1); + + DevMsg("Conditions set, now load a game or lobby to trigger the crash.\n"); +} + +static ConCommand rd_debug_amd_shadow_crash("rd_debug_amd_shadow_crash", DebugAmdShadowCrash, "Forces the game to set exact conditions to test the AMD shadow crash. Debug only", FCVAR_NONE); + + static class CRD_VideoConfigVariableListHack : public CAutoGameSystem { public: @@ -15,6 +70,22 @@ static class CRD_VideoConfigVariableListHack : public CAutoGameSystem { } + virtual bool Init() override + { + if (IsAffectedByAmdShadowBug()) { + Warning("Your GPU is affected by a shadow bug, disabling some video options to prevent a crash..\n"); + + DevMsg("Setting [rd_env_projectedtexture_enabled] to 0\n"); + ConVarRef rd_env_projectedtexture_enabled("rd_env_projectedtexture_enabled"); + rd_env_projectedtexture_enabled.SetValue(0); + + DevMsg("Setting [rd_flashlightshadows] to 0\n"); + ConVarRef rd_flashlightshadows("rd_flashlightshadows"); + rd_flashlightshadows.SetValue(0); + } + return true; + } + void PostInit() override { // videocfg.lib is statically linked, but the variable we need is marked as static, so we can't reference it using an extern. @@ -206,6 +277,8 @@ static void GenerateWindowedModes( CUtlVector< vmode_t > &windowedModes, int nCo CRD_VGUI_Settings_Video::CRD_VGUI_Settings_Video( vgui::Panel *parent, const char *panelName ) : BaseClass( parent, panelName ) { + bool amdBugAffectedGpu = IsAffectedByAmdShadowBug(); + m_pSettingScreenResolution = new CRD_VGUI_Option( this, "SettingScreenResolution", "#rd_video_screen_resolution", CRD_VGUI_Option::MODE_DROPDOWN ); m_pSettingScreenResolution->AddActionSignalTarget( this ); m_pSettingDisplayMode = new CRD_VGUI_Option( this, "SettingDisplayMode", "#rd_video_display_mode", CRD_VGUI_Option::MODE_DROPDOWN ); @@ -295,13 +368,21 @@ CRD_VGUI_Settings_Video::CRD_VGUI_Settings_Video( vgui::Panel *parent, const cha m_pSettingBloomScale->SetDefaultHint( "#rd_video_bloom_scale_hint" ); m_pSettingBloomScale->LinkToConVar( "mat_bloom_scalefactor_scalar", false ); m_pSettingProjectedTextures = new CRD_VGUI_Option( this, "SettingProjectedTextures", "#rd_video_projected_textures", CRD_VGUI_Option::MODE_DROPDOWN ); - m_pSettingProjectedTextures->AddOption( 0, "#rd_video_effect_disabled", "#rd_video_projected_textures_hint" ); - m_pSettingProjectedTextures->AddOption( 1, "#rd_video_effect_enabled", "#rd_video_projected_textures_hint" ); + m_pSettingProjectedTextures->AddOption(0, "#rd_video_effect_disabled", "#rd_video_projected_textures_hint"); + + if (!amdBugAffectedGpu) { + m_pSettingProjectedTextures->AddOption(1, "#rd_video_effect_enabled", "#rd_video_projected_textures_hint"); + } + m_pSettingProjectedTextures->SetDefaultHint( "#rd_video_projected_textures_hint" ); m_pSettingProjectedTextures->LinkToConVar( "rd_env_projectedtexture_enabled", false ); m_pSettingFlashlightShadows = new CRD_VGUI_Option( this, "SettingFlashlightShadows", "#rd_video_flashlight_shadows", CRD_VGUI_Option::MODE_DROPDOWN ); m_pSettingFlashlightShadows->AddOption( 0, "#rd_video_effect_disabled", "#rd_video_flashlight_shadows_hint" ); - m_pSettingFlashlightShadows->AddOption( 1, "#rd_video_effect_enabled", "#rd_video_flashlight_shadows_hint" ); + + if (!amdBugAffectedGpu) { + m_pSettingFlashlightShadows->AddOption(1, "#rd_video_effect_enabled", "#rd_video_flashlight_shadows_hint"); + } + m_pSettingFlashlightShadows->SetDefaultHint( "#rd_video_flashlight_shadows_hint" ); m_pSettingFlashlightShadows->LinkToConVar( "rd_flashlightshadows", false ); m_pSettingFlashlightLightSpill = new CRD_VGUI_Option( this, "SettingFlashlightLightSpill", "#rd_video_flashlight_light_spill", CRD_VGUI_Option::MODE_DROPDOWN ); From e83d6ec6cb34932f37639650c08dd93548ecb83a Mon Sep 17 00:00:00 2001 From: Mithrand Date: Sat, 28 Mar 2026 11:49:19 +0100 Subject: [PATCH 2/2] replace null in check --- .../client/swarm/vgui/rd_vgui_settings_video.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/game/client/swarm/vgui/rd_vgui_settings_video.cpp b/src/game/client/swarm/vgui/rd_vgui_settings_video.cpp index 1aff59005..f6246c883 100644 --- a/src/game/client/swarm/vgui/rd_vgui_settings_video.cpp +++ b/src/game/client/swarm/vgui/rd_vgui_settings_video.cpp @@ -26,14 +26,14 @@ inline bool IsAffectedByAmdShadowBug() // if AMD if (info.m_VendorID == 0x1002) { // navi 32 - if (strstr(driverName, "7700") != null) return true; - if (strstr(driverName, "7800") != null) return true; - if (strstr(driverName, "7900") != null) return true; + if (strstr(driverName, "7700")) return true; + if (strstr(driverName, "7800")) return true; + if (strstr(driverName, "7900")) return true; // navi 48 - if (strstr(driverName, "9070") != null) return true; + if (strstr(driverName, "9070")) return true; // navi 48 pro - if (strstr(driverName, "R9600") != null) return true; - if (strstr(driverName, "R9700") != null) return true; + if (strstr(driverName, "R9600")) return true; + if (strstr(driverName, "R9700")) return true; } return false;