1 // Copyright 2008 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4
5 #include <algorithm>
6
7 #include "Common/CPUDetect.h"
8 #include "Common/CommonTypes.h"
9 #include "Common/StringUtil.h"
10 #include "Core/Config/GraphicsSettings.h"
11 #include "Core/ConfigManager.h"
12 #include "Core/Core.h"
13 #include "Core/Movie.h"
14 #include "VideoCommon/OnScreenDisplay.h"
15 #include "VideoCommon/VideoCommon.h"
16 #include "VideoCommon/VideoConfig.h"
17
18 VideoConfig g_Config;
19 VideoConfig g_ActiveConfig;
20 static bool s_has_registered_callback = false;
21
IsVSyncActive(bool enabled)22 static bool IsVSyncActive(bool enabled)
23 {
24 // Vsync is disabled when the throttler is disabled by the tab key.
25 return enabled && !Core::GetIsThrottlerTempDisabled() &&
26 SConfig::GetInstance().m_EmulationSpeed == 1.0;
27 }
28
UpdateActiveConfig()29 void UpdateActiveConfig()
30 {
31 if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
32 Movie::SetGraphicsConfig();
33 g_ActiveConfig = g_Config;
34 g_ActiveConfig.bVSyncActive = IsVSyncActive(g_ActiveConfig.bVSync);
35 }
36
VideoConfig()37 VideoConfig::VideoConfig()
38 {
39 // Needed for the first frame, I think
40 fAspectRatioHackW = 1;
41 fAspectRatioHackH = 1;
42
43 // disable all features by default
44 backend_info.api_type = APIType::Nothing;
45 backend_info.MaxTextureSize = 16384;
46 backend_info.bSupportsExclusiveFullscreen = false;
47 backend_info.bSupportsMultithreading = false;
48 backend_info.bSupportsST3CTextures = false;
49 backend_info.bSupportsBPTCTextures = false;
50
51 bEnableValidationLayer = false;
52
53 #if defined(ANDROID)
54 bBackendMultithreading = false;
55 #else
56 bBackendMultithreading = true;
57 #endif
58 }
59
Refresh()60 void VideoConfig::Refresh()
61 {
62 if (!s_has_registered_callback)
63 {
64 // There was a race condition between the video thread and the host thread here, if
65 // corrections need to be made by VerifyValidity(). Briefly, the config will contain
66 // invalid values. Instead, pause emulation first, which will flush the video thread,
67 // update the config and correct it, then resume emulation, after which the video
68 // thread will detect the config has changed and act accordingly.
69 Config::AddConfigChangedCallback([]() { Core::RunAsCPUThread([]() { g_Config.Refresh(); }); });
70 s_has_registered_callback = true;
71 }
72
73 bVSync = Config::Get(Config::GFX_VSYNC);
74 iAdapter = Config::Get(Config::GFX_ADAPTER);
75
76 bWidescreenHack = Config::Get(Config::GFX_WIDESCREEN_HACK);
77 aspect_mode = Config::Get(Config::GFX_ASPECT_RATIO);
78 suggested_aspect_mode = Config::Get(Config::GFX_SUGGESTED_ASPECT_RATIO);
79 bCrop = Config::Get(Config::GFX_CROP);
80 iSafeTextureCache_ColorSamples = Config::Get(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES);
81 bShowFPS = Config::Get(Config::GFX_SHOW_FPS);
82 bShowNetPlayPing = Config::Get(Config::GFX_SHOW_NETPLAY_PING);
83 bShowNetPlayMessages = Config::Get(Config::GFX_SHOW_NETPLAY_MESSAGES);
84 bLogRenderTimeToFile = Config::Get(Config::GFX_LOG_RENDER_TIME_TO_FILE);
85 bOverlayStats = Config::Get(Config::GFX_OVERLAY_STATS);
86 bOverlayProjStats = Config::Get(Config::GFX_OVERLAY_PROJ_STATS);
87 bDumpTextures = Config::Get(Config::GFX_DUMP_TEXTURES);
88 bDumpMipmapTextures = Config::Get(Config::GFX_DUMP_MIP_TEXTURES);
89 bDumpBaseTextures = Config::Get(Config::GFX_DUMP_BASE_TEXTURES);
90 bHiresTextures = Config::Get(Config::GFX_HIRES_TEXTURES);
91 bCacheHiresTextures = Config::Get(Config::GFX_CACHE_HIRES_TEXTURES);
92 bDumpEFBTarget = Config::Get(Config::GFX_DUMP_EFB_TARGET);
93 bDumpXFBTarget = Config::Get(Config::GFX_DUMP_XFB_TARGET);
94 bDumpFramesAsImages = Config::Get(Config::GFX_DUMP_FRAMES_AS_IMAGES);
95 bFreeLook = Config::Get(Config::GFX_FREE_LOOK);
96 iFreelookControlType = Config::Get(Config::GFX_FREE_LOOK_CONTROL_TYPE);
97 bUseFFV1 = Config::Get(Config::GFX_USE_FFV1);
98 sDumpFormat = Config::Get(Config::GFX_DUMP_FORMAT);
99 sDumpCodec = Config::Get(Config::GFX_DUMP_CODEC);
100 sDumpEncoder = Config::Get(Config::GFX_DUMP_ENCODER);
101 sDumpPath = Config::Get(Config::GFX_DUMP_PATH);
102 iBitrateKbps = Config::Get(Config::GFX_BITRATE_KBPS);
103 bInternalResolutionFrameDumps = Config::Get(Config::GFX_INTERNAL_RESOLUTION_FRAME_DUMPS);
104 bEnableGPUTextureDecoding = Config::Get(Config::GFX_ENABLE_GPU_TEXTURE_DECODING);
105 bEnablePixelLighting = Config::Get(Config::GFX_ENABLE_PIXEL_LIGHTING);
106 bFastDepthCalc = Config::Get(Config::GFX_FAST_DEPTH_CALC);
107 iMultisamples = Config::Get(Config::GFX_MSAA);
108 bSSAA = Config::Get(Config::GFX_SSAA);
109 iEFBScale = Config::Get(Config::GFX_EFB_SCALE);
110 bTexFmtOverlayEnable = Config::Get(Config::GFX_TEXFMT_OVERLAY_ENABLE);
111 bTexFmtOverlayCenter = Config::Get(Config::GFX_TEXFMT_OVERLAY_CENTER);
112 bWireFrame = Config::Get(Config::GFX_ENABLE_WIREFRAME);
113 bDisableFog = Config::Get(Config::GFX_DISABLE_FOG);
114 bBorderlessFullscreen = Config::Get(Config::GFX_BORDERLESS_FULLSCREEN);
115 bEnableValidationLayer = Config::Get(Config::GFX_ENABLE_VALIDATION_LAYER);
116 bBackendMultithreading = Config::Get(Config::GFX_BACKEND_MULTITHREADING);
117 iCommandBufferExecuteInterval = Config::Get(Config::GFX_COMMAND_BUFFER_EXECUTE_INTERVAL);
118 bShaderCache = Config::Get(Config::GFX_SHADER_CACHE);
119 bWaitForShadersBeforeStarting = Config::Get(Config::GFX_WAIT_FOR_SHADERS_BEFORE_STARTING);
120 iShaderCompilationMode = Config::Get(Config::GFX_SHADER_COMPILATION_MODE);
121 iShaderCompilerThreads = Config::Get(Config::GFX_SHADER_COMPILER_THREADS);
122 iShaderPrecompilerThreads = Config::Get(Config::GFX_SHADER_PRECOMPILER_THREADS);
123
124 bZComploc = Config::Get(Config::GFX_SW_ZCOMPLOC);
125 bZFreeze = Config::Get(Config::GFX_SW_ZFREEZE);
126 bDumpObjects = Config::Get(Config::GFX_SW_DUMP_OBJECTS);
127 bDumpTevStages = Config::Get(Config::GFX_SW_DUMP_TEV_STAGES);
128 bDumpTevTextureFetches = Config::Get(Config::GFX_SW_DUMP_TEV_TEX_FETCHES);
129 drawStart = Config::Get(Config::GFX_SW_DRAW_START);
130 drawEnd = Config::Get(Config::GFX_SW_DRAW_END);
131
132 bForceFiltering = Config::Get(Config::GFX_ENHANCE_FORCE_FILTERING);
133 iMaxAnisotropy = Config::Get(Config::GFX_ENHANCE_MAX_ANISOTROPY);
134 sPostProcessingShader = Config::Get(Config::GFX_ENHANCE_POST_SHADER);
135 bForceTrueColor = Config::Get(Config::GFX_ENHANCE_FORCE_TRUE_COLOR);
136 bDisableCopyFilter = Config::Get(Config::GFX_ENHANCE_DISABLE_COPY_FILTER);
137 bArbitraryMipmapDetection = Config::Get(Config::GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION);
138 fArbitraryMipmapDetectionThreshold =
139 Config::Get(Config::GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION_THRESHOLD);
140
141 stereo_mode = Config::Get(Config::GFX_STEREO_MODE);
142 iStereoDepth = Config::Get(Config::GFX_STEREO_DEPTH);
143 iStereoConvergencePercentage = Config::Get(Config::GFX_STEREO_CONVERGENCE_PERCENTAGE);
144 bStereoSwapEyes = Config::Get(Config::GFX_STEREO_SWAP_EYES);
145 iStereoConvergence = Config::Get(Config::GFX_STEREO_CONVERGENCE);
146 bStereoEFBMonoDepth = Config::Get(Config::GFX_STEREO_EFB_MONO_DEPTH);
147 iStereoDepthPercentage = Config::Get(Config::GFX_STEREO_DEPTH_PERCENTAGE);
148
149 bEFBAccessEnable = Config::Get(Config::GFX_HACK_EFB_ACCESS_ENABLE);
150 bEFBAccessDeferInvalidation = Config::Get(Config::GFX_HACK_EFB_DEFER_INVALIDATION);
151 bBBoxEnable = Config::Get(Config::GFX_HACK_BBOX_ENABLE);
152 bForceProgressive = Config::Get(Config::GFX_HACK_FORCE_PROGRESSIVE);
153 bSkipEFBCopyToRam = Config::Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM);
154 bSkipXFBCopyToRam = Config::Get(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM);
155 bDisableCopyToVRAM = Config::Get(Config::GFX_HACK_DISABLE_COPY_TO_VRAM);
156 bDeferEFBCopies = Config::Get(Config::GFX_HACK_DEFER_EFB_COPIES);
157 bImmediateXFB = Config::Get(Config::GFX_HACK_IMMEDIATE_XFB);
158 bSkipPresentingDuplicateXFBs = Config::Get(Config::GFX_HACK_SKIP_DUPLICATE_XFBS);
159 bCopyEFBScaled = Config::Get(Config::GFX_HACK_COPY_EFB_SCALED);
160 bEFBEmulateFormatChanges = Config::Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES);
161 bVertexRounding = Config::Get(Config::GFX_HACK_VERTEX_ROUDING);
162 iEFBAccessTileSize = Config::Get(Config::GFX_HACK_EFB_ACCESS_TILE_SIZE);
163
164 bPerfQueriesEnable = Config::Get(Config::GFX_PERF_QUERIES_ENABLE);
165
166 VerifyValidity();
167 }
168
VerifyValidity()169 void VideoConfig::VerifyValidity()
170 {
171 // TODO: Check iMaxAnisotropy value
172 if (iAdapter < 0 || iAdapter > ((int)backend_info.Adapters.size() - 1))
173 iAdapter = 0;
174
175 if (std::find(backend_info.AAModes.begin(), backend_info.AAModes.end(), iMultisamples) ==
176 backend_info.AAModes.end())
177 iMultisamples = 1;
178
179 if (stereo_mode != StereoMode::Off)
180 {
181 if (!backend_info.bSupportsGeometryShaders)
182 {
183 OSD::AddMessage(
184 "Stereoscopic 3D isn't supported by your GPU, support for OpenGL 3.2 is required.",
185 10000);
186 stereo_mode = StereoMode::Off;
187 }
188 }
189 }
190
UsingUberShaders() const191 bool VideoConfig::UsingUberShaders() const
192 {
193 return iShaderCompilationMode == ShaderCompilationMode::SynchronousUberShaders ||
194 iShaderCompilationMode == ShaderCompilationMode::AsynchronousUberShaders;
195 }
196
GetNumAutoShaderCompilerThreads()197 static u32 GetNumAutoShaderCompilerThreads()
198 {
199 // Automatic number. We use clamp(cpus - 3, 1, 4).
200 return static_cast<u32>(std::min(std::max(cpu_info.num_cores - 3, 1), 4));
201 }
202
GetShaderCompilerThreads() const203 u32 VideoConfig::GetShaderCompilerThreads() const
204 {
205 if (!backend_info.bSupportsBackgroundCompiling)
206 return 0;
207
208 if (iShaderCompilerThreads >= 0)
209 return static_cast<u32>(iShaderCompilerThreads);
210 else
211 return GetNumAutoShaderCompilerThreads();
212 }
213
GetShaderPrecompilerThreads() const214 u32 VideoConfig::GetShaderPrecompilerThreads() const
215 {
216 // When using background compilation, always keep the same thread count.
217 if (!bWaitForShadersBeforeStarting)
218 return GetShaderCompilerThreads();
219
220 if (!backend_info.bSupportsBackgroundCompiling)
221 return 0;
222
223 if (iShaderPrecompilerThreads >= 0)
224 return static_cast<u32>(iShaderPrecompilerThreads);
225 else
226 return GetNumAutoShaderCompilerThreads();
227 }
228