|
8 | 8 | // memdbgon must be the last include file in a .cpp file!!! |
9 | 9 | #include "tier0/memdbgon.h" |
10 | 10 |
|
| 11 | +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] "); |
| 12 | + |
| 13 | +inline bool IsAffectedByAmdShadowBug() |
| 14 | +{ |
| 15 | + if (rd_debug_amd_shadow_workaround.GetInt() == -1) { |
| 16 | + |
| 17 | + MaterialAdapterInfo_t info; |
| 18 | + g_pMaterialSystem->GetDisplayAdapterInfo(0, info); |
| 19 | + |
| 20 | + // XXX: debug |
| 21 | + //const char* driverName = "AMD Radeon RX 7900 XTX"; |
| 22 | + const char* driverName = info.m_pDriverName; |
| 23 | + |
| 24 | + DevMsg("Detected GPU: %s\n", info.m_pDriverName); |
| 25 | + |
| 26 | + // if AMD |
| 27 | + if (info.m_VendorID == 0x1002) { |
| 28 | + // navi 32 |
| 29 | + if (strstr(driverName, "7700") != null) return true; |
| 30 | + if (strstr(driverName, "7800") != null) return true; |
| 31 | + if (strstr(driverName, "7900") != null) return true; |
| 32 | + // navi 48 |
| 33 | + if (strstr(driverName, "9070") != null) return true; |
| 34 | + // navi 48 pro |
| 35 | + if (strstr(driverName, "R9600") != null) return true; |
| 36 | + if (strstr(driverName, "R9700") != null) return true; |
| 37 | + } |
| 38 | + |
| 39 | + return false; |
| 40 | + } |
| 41 | + |
| 42 | + return rd_debug_amd_shadow_workaround.GetBool(); |
| 43 | +} |
| 44 | + |
| 45 | +inline void DebugAmdShadowCrash() |
| 46 | +{ |
| 47 | + DevWarning("Enabling settings to reproduce crash on AMD GPUs...\n"); |
| 48 | + |
| 49 | + DevMsg("Disabling workaround..\n"); |
| 50 | + rd_debug_amd_shadow_workaround.SetValue(0); |
| 51 | + |
| 52 | + DevMsg("Setting [rd_env_projectedtexture_enabled] to 1\n"); |
| 53 | + ConVarRef rd_env_projectedtexture_enabled("rd_env_projectedtexture_enabled"); |
| 54 | + rd_env_projectedtexture_enabled.SetValue(1); |
| 55 | + |
| 56 | + DevMsg("Setting [rd_flashlightshadows] to 1\n"); |
| 57 | + ConVarRef rd_flashlightshadows("rd_flashlightshadows"); |
| 58 | + rd_flashlightshadows.SetValue(1); |
| 59 | + |
| 60 | + DevMsg("Conditions set, now load a game or lobby to trigger the crash.\n"); |
| 61 | +} |
| 62 | + |
| 63 | +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); |
| 64 | + |
| 65 | + |
11 | 66 | static class CRD_VideoConfigVariableListHack : public CAutoGameSystem |
12 | 67 | { |
13 | 68 | public: |
14 | 69 | CRD_VideoConfigVariableListHack() : CAutoGameSystem{ "CRD_VideoConfigVariableListHack" } |
15 | 70 | { |
16 | 71 | } |
17 | 72 |
|
| 73 | + virtual bool Init() override |
| 74 | + { |
| 75 | + if (IsAffectedByAmdShadowBug()) { |
| 76 | + Warning("Your GPU is affected by a shadow bug, disabling some video options to prevent a crash..\n"); |
| 77 | + |
| 78 | + DevMsg("Setting [rd_env_projectedtexture_enabled] to 0\n"); |
| 79 | + ConVarRef rd_env_projectedtexture_enabled("rd_env_projectedtexture_enabled"); |
| 80 | + rd_env_projectedtexture_enabled.SetValue(0); |
| 81 | + |
| 82 | + DevMsg("Setting [rd_flashlightshadows] to 0\n"); |
| 83 | + ConVarRef rd_flashlightshadows("rd_flashlightshadows"); |
| 84 | + rd_flashlightshadows.SetValue(0); |
| 85 | + } |
| 86 | + return true; |
| 87 | + } |
| 88 | + |
18 | 89 | void PostInit() override |
19 | 90 | { |
20 | 91 | // 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 |
206 | 277 | CRD_VGUI_Settings_Video::CRD_VGUI_Settings_Video( vgui::Panel *parent, const char *panelName ) : |
207 | 278 | BaseClass( parent, panelName ) |
208 | 279 | { |
| 280 | + bool amdBugAffectedGpu = IsAffectedByAmdShadowBug(); |
| 281 | + |
209 | 282 | m_pSettingScreenResolution = new CRD_VGUI_Option( this, "SettingScreenResolution", "#rd_video_screen_resolution", CRD_VGUI_Option::MODE_DROPDOWN ); |
210 | 283 | m_pSettingScreenResolution->AddActionSignalTarget( this ); |
211 | 284 | 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 |
295 | 368 | m_pSettingBloomScale->SetDefaultHint( "#rd_video_bloom_scale_hint" ); |
296 | 369 | m_pSettingBloomScale->LinkToConVar( "mat_bloom_scalefactor_scalar", false ); |
297 | 370 | m_pSettingProjectedTextures = new CRD_VGUI_Option( this, "SettingProjectedTextures", "#rd_video_projected_textures", CRD_VGUI_Option::MODE_DROPDOWN ); |
298 | | - m_pSettingProjectedTextures->AddOption( 0, "#rd_video_effect_disabled", "#rd_video_projected_textures_hint" ); |
299 | | - m_pSettingProjectedTextures->AddOption( 1, "#rd_video_effect_enabled", "#rd_video_projected_textures_hint" ); |
| 371 | + m_pSettingProjectedTextures->AddOption(0, "#rd_video_effect_disabled", "#rd_video_projected_textures_hint"); |
| 372 | + |
| 373 | + if (!amdBugAffectedGpu) { |
| 374 | + m_pSettingProjectedTextures->AddOption(1, "#rd_video_effect_enabled", "#rd_video_projected_textures_hint"); |
| 375 | + } |
| 376 | + |
300 | 377 | m_pSettingProjectedTextures->SetDefaultHint( "#rd_video_projected_textures_hint" ); |
301 | 378 | m_pSettingProjectedTextures->LinkToConVar( "rd_env_projectedtexture_enabled", false ); |
302 | 379 | m_pSettingFlashlightShadows = new CRD_VGUI_Option( this, "SettingFlashlightShadows", "#rd_video_flashlight_shadows", CRD_VGUI_Option::MODE_DROPDOWN ); |
303 | 380 | m_pSettingFlashlightShadows->AddOption( 0, "#rd_video_effect_disabled", "#rd_video_flashlight_shadows_hint" ); |
304 | | - m_pSettingFlashlightShadows->AddOption( 1, "#rd_video_effect_enabled", "#rd_video_flashlight_shadows_hint" ); |
| 381 | + |
| 382 | + if (!amdBugAffectedGpu) { |
| 383 | + m_pSettingFlashlightShadows->AddOption(1, "#rd_video_effect_enabled", "#rd_video_flashlight_shadows_hint"); |
| 384 | + } |
| 385 | + |
305 | 386 | m_pSettingFlashlightShadows->SetDefaultHint( "#rd_video_flashlight_shadows_hint" ); |
306 | 387 | m_pSettingFlashlightShadows->LinkToConVar( "rd_flashlightshadows", false ); |
307 | 388 | m_pSettingFlashlightLightSpill = new CRD_VGUI_Option( this, "SettingFlashlightLightSpill", "#rd_video_flashlight_light_spill", CRD_VGUI_Option::MODE_DROPDOWN ); |
|
0 commit comments