UI: clean up config graphics

This commit is contained in:
N3xoX1 2025-08-22 10:27:31 +09:30
parent 82b74c0202
commit c05b6c1eee
10 changed files with 355 additions and 51 deletions

2
external/sciterui vendored

@ -1 +1 @@
Subproject commit e070d9827a9342f64623a2503d898180447ceeeb
Subproject commit b831d458cdc12c55b62d6c122a4b2ca2ec9ae5e8

View File

@ -1,3 +1,13 @@
popup.tooltip
{
background: #4f6459;
border: 1px solid #6a6a6a;
padding: 0.5rem;
color: #eff0f1;
font-family: 'Segoe UI', Arial, sans-serif;
font-size: 0.8rem;
}
button
{
color: #eff0f1;

View File

@ -246,7 +246,7 @@ PageNav.page_tabs page.active {
</window-buttons>
</header>
<body>
<div id="SettingsPage">
<div id="SettingsPage" tooltip-host>
<PageNav target="ConfigContents" id="MainTabNav">
<Page contents="system_config_graphics.html" label="Graphics" Name="Graphics" />
<Page contents="system_config_audio.html" label="Audio" Name="Audio" />

View File

@ -4,48 +4,48 @@
<div class="group-title">API Settings</div>
<div class="form-row">
<div class="left"><label for="GraphicsAPI">API:</label></div>
<div class="right"><ComboBox id="GraphicsAPI" /></div>
<div class="right"><ComboBox id="GraphicsAPI" tooltip="Switches between the available graphics APIs.\nVulkan is recommended in most cases." /></div>
</div>
<div class="form-row" id="ShaderBackendRow">
<div class="left"><label for="ShaderBackend">Shader Backend:</label></div>
<div class="right"><ComboBox id="ShaderBackend" /></div>
<div class="right"><ComboBox id="ShaderBackend" tooltip="The shader backend to use for the OpenGL renderer.\nGLSL is the fastest in performance and the best in rendering accuracy.\nGLASM is a deprecated NVIDIA-only backend that offers much better shader building performance at the cost of FPS and rendering accuracy.\nSPIR-V compiles the fastest, but yields poor results on most GPU drivers."/></div>
</div>
<div class="form-row" id="VulkanDevicesRow">
<div class="left"><label for="VulkanDevices">Device:</label></div>
<div class="right"><ComboBox id="VulkanDevices" /></div>
<div class="right"><ComboBox id="VulkanDevices" tooltip="This setting selects the GPU to use with the Vulkan backend." /></div>
</div>
</div>
<div class="input-group">
<div class="group-title">Graphics Settings</div>
<div class="form-row checkbox-row">
<div class="checkbox"><input type="checkbox" id="UseDiskPipelineCache"><label for="UseDiskPipelineCache">Use disk pipeline cache</label></div>
<div class="checkbox"><input type="checkbox" id="UseDiskPipelineCache" tooltip="Allows saving shaders to storage for faster loading on following game boots.\nDisabling it is only intended for debugging."><label for="UseDiskPipelineCache">Use disk pipeline cache</label></div>
</div>
<div class="form-row checkbox-row">
<div class="checkbox"><input type="checkbox" id="UseAsynchronousGPUEmulation"><label for="UseAsynchronousGPUEmulation">Use asynchronous GPU emulation</label></div>
<div class="checkbox"><input type="checkbox" id="UseAsynchronousGPUEmulation" tooltip="Uses an extra CPU thread for rendering.\nThis option should always remain enabled."><label for="UseAsynchronousGPUEmulation">Use asynchronous GPU emulation</label></div>
</div>
<div class="form-row">
<div class="left"><label for="AstcDecodeMode">ASTC Decoding Method:</label></div>
<div class="right"><ComboBox id="AstcDecodeMode" /></div>
<div class="right"><ComboBox id="AstcDecodeMode" tooltip="This option controls how ASTC textures should be decoded.\nCPU: Use the CPU for decoding, slowest but safest method.\nGPU: Use the GPU's compute shaders to decode ASTC textures, recommended for most games and users.\nCPU Asynchronously: Use the CPU to decode ASTC textures as they arrive. Completely eliminates ASTC decoding\nstuttering at the cost of rendering issues while the texture is being decoded." /></div>
</div>
<div class="form-row">
<div class="left"><label for="VSyncMode">VSync Mode:</label></div>
<div class="right"><ComboBox id="VSyncMode" /></div>
<div class="right"><ComboBox id="VSyncMode" tooltip="FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen refresh rate.\nFIFO Relaxed is similar to FIFO but allows tearing as it recovers from a slow down.\nMailbox can have lower latency than FIFO and does not tear but may drop frames.\nImmediate (no synchronization) just presents whatever is available and can exhibit tearing." /></div>
</div>
<div class="form-row">
<div class="left"><label for="NvdecEmulation">NVDEC emulation:</label></div>
<div class="right"><ComboBox id="NvdecEmulation" /></div>
<div class="right"><ComboBox id="NvdecEmulation" tooltip="Specifies how videos should be decoded.\nIt can either use the CPU or the GPU for decoding, or perform no decoding at all (black screen on videos).\nIn most cases, GPU decoding provides the best performance."/></div>
</div>
<div class="form-row">
<div class="left"><label for="FullscreenMode">Fullscreen Mode:</label></div>
<div class="right"><ComboBox id="FullscreenMode" /></div>
<div class="right"><ComboBox id="FullscreenMode" tooltip="The method used to render the window in fullscreen.\nBorderless offers the best compatibility with the on-screen keyboard that some games request for input.\nExclusive fullscreen may offer better performance and better Freesync/Gsync support." /></div>
</div>
<div class="form-row">
<div class="left"><label for="AspectRatio">Aspect Ratio:</label></div>
<div class="right"><ComboBox id="AspectRatio" /></div>
<div class="right"><ComboBox id="AspectRatio" tooltip="Stretches the game to fit the specified aspect ratio.\nSwitch games only support 16:9, so custom game mods are required to get other ratios.\nAlso controls the aspect ratio of captured screenshots."/></div>
</div>
<div class="form-row">
<div class="left"><label for="ResolutionSetup">Resolution:</label></div>
<div class="right"><ComboBox id="ResolutionSetup" /></div>
<div class="right"><ComboBox id="ResolutionSetup" tooltip="Forces the game to render at a different resolution.\nHigher resolutions require much more VRAM and bandwidth.\nOptions lower than 1X can cause rendering issues." /></div>
</div>
<div class="form-row">
<div class="left"><label for="ScalingFilter">Window Adapting Filter:</label></div>
@ -53,7 +53,7 @@
</div>
<div class="form-row">
<div class="left"><label for="AntiAliasing">Anti-Aliasing Method:</label></div>
<div class="right"><ComboBox id="AntiAliasing" /></div>
<div class="right"><ComboBox id="AntiAliasing" tooltip="The anti-aliasing method to use.\nSMAA offers the best quality.\nFXAA has a lower performance impact and can produce a better and more stable picture under very low resolutions."/></div>
</div>
<div class="form-row slider-row">
<div class="left"><label for="FSPSharpness">FSP Sharpness:</label></div>
@ -66,43 +66,43 @@
<div class="group-title">Advanced Graphics Settings</div>
<div class="form-row">
<div class="left"><label for="AccuracyLevel">Accuracy Level:</label></div>
<div class="right"><ComboBox id="AccuracyLevel" /></div>
<div class="right"><ComboBox id="AccuracyLevel" tooltip="GPU emulation accuracy.\nMost games render fine with Normal, but High is still required for some.\nParticles tend to only render correctly with High accuracy.\nExtreme should only be used for debugging.\nThis option can be changed while playing.\nSome games may require booting on high to render properly."/></div>
</div>
<div class="form-row">
<div class="left"><label for="AnisotropicFiltering">Anisotropic Filtering:</label></div>
<div class="right"><ComboBox id="AnisotropicFiltering" /></div>
<div class="right"><ComboBox id="AnisotropicFiltering" tooltip="Controls the quality of texture rendering at oblique angles.\nIt’s a light setting and safe to set at 16x on most GPUs."/></div>
</div>
<div class="form-row">
<div class="left"><label for="ASTCRecompressionMethod">ASTC Recompression Method:</label></div>
<div class="right"><ComboBox id="ASTCRecompressionMethod" /></div>
<div class="right"><ComboBox id="ASTCRecompressionMethod" tooltip="Almost all desktop and laptop dedicated GPUs lack support for ASTC textures, forcing the emulator to decompress to an intermediate format any card supports, RGBA8.\nThis option recompresses RGBA8 to either the BC1 or BC3 format, saving VRAM but negatively affecting image quality." /></div>
</div>
<div class="form-row">
<div class="left"><label for="VRAMUsageMode">VRAM Usage Mode:</label></div>
<div class="right"><ComboBox id="VRAMUsageMode" /></div>
<div class="right"><ComboBox id="VRAMUsageMode" tooltip="Selects whether the emulator should prefer to conserve memory or make maximum usage of available video memory for performance. Has no effect on integrated graphics. Aggressive mode may severely impact the performance of other applications such as recording software."/></div>
</div>
<div class="form-row checkbox-row">
<div class="checkbox"><input type="checkbox" id="EnableAsynchronousPresentation"><label for="EnableAsynchronousPresentation">Enable asynchronous presentation (Vulkan only)</label></div>
<div class="checkbox"><input type="checkbox" id="EnableAsynchronousPresentation" tooltip="Slightly improves performance by moving presentation to a separate CPU thread."><label for="EnableAsynchronousPresentation">Enable asynchronous presentation (Vulkan only)</label></div>
</div>
<div class="form-row checkbox-row">
<div class="checkbox"><input type="checkbox" id="ForceMaximumClocks"><label for="ForceMaximumClocks">Force maximum clocks (Vulkan only)</label></div>
<div class="checkbox"><input type="checkbox" id="ForceMaximumClocks" tooltip="Runs work in the background while waiting for graphics commands to keep the GPU from lowering its clock speed."><label for="ForceMaximumClocks">Force maximum clocks (Vulkan only)</label></div>
</div>
<div class="form-row checkbox-row">
<div class="checkbox"><input type="checkbox" id="EnableReactiveFlushing"><label for="EnableReactiveFlushing">Enable Reactive Flushing</label></div>
<div class="checkbox"><input type="checkbox" id="EnableReactiveFlushing"><label for="EnableReactiveFlushing" tooltip="Uses reactive flushing instead of predictive flushing, allowing more accurate memory syncing.">Enable Reactive Flushing</label></div>
</div>
<div class="form-row checkbox-row">
<div class="checkbox"><input type="checkbox" id="UseAsynchronousShaderBuilding"><label for="UseAsynchronousShaderBuilding">Use asynchronous shader building (Hack)</label></div>
<div class="checkbox"><input type="checkbox" id="UseAsynchronousShaderBuilding"><label for="UseAsynchronousShaderBuilding" tooltip="Enables asynchronous shader compilation, which may reduce shader stutter.\nThis feature is experimental.">Use asynchronous shader building (Hack)</label></div>
</div>
<div class="form-row checkbox-row">
<div class="checkbox"><input type="checkbox" id="FastGPUTime"><label for="FastGPUTime">Fast GPU Time (Hack)</label></div>
<div class="checkbox"><input type="checkbox" id="FastGPUTime" tooltip="Enables Fast GPU Time. This option will force most games to run at their highest native resolution."><label for="FastGPUTime">Fast GPU Time (Hack)</label></div>
</div>
<div class="form-row checkbox-row">
<div class="checkbox"><input type="checkbox" id="UseVulkanPipelineCache"><label for="UseVulkanPipelineCache">Use Vulkan pipeline cache</label></div>
<div class="checkbox"><input type="checkbox" id="UseVulkanPipelineCache" tooltip="Enables GPU vendor-specific pipeline cache.\nThis option can improve shader loading time significantly in cases where the Vulkan driver does not store pipeline cache files internally."><label for="UseVulkanPipelineCache">Use Vulkan pipeline cache</label></div>
</div>
<div class="form-row checkbox-row">
<div class="checkbox"><input type="checkbox" id="SyncToFramerateOfVideoPlayback"><label for="SyncToFramerateOfVideoPlayback">Sync to framerate of video playback</label></div>
<div class="checkbox"><input type="checkbox" id="SyncToFramerateOfVideoPlayback" tooltip="Run the game at normal speed during video playback, even when the framerate is unlocked."><label for="SyncToFramerateOfVideoPlayback">Sync to framerate of video playback</label></div>
</div>
<div class="form-row checkbox-row">
<div class="checkbox"><input type="checkbox" id="BarrierFeedbackLoops"><label for="BarrierFeedbackLoops">Barrier feedback loops</label></div>
<div class="checkbox"><input type="checkbox" id="BarrierFeedbackLoops" tooltip="Improves rendering of transparency effects in specific games."><label for="BarrierFeedbackLoops">Barrier feedback loops</label></div>
</div>
</div>
</page>

View File

@ -17,13 +17,18 @@ namespace
IntValueRanged,
RendererBackend,
ShaderBackend,
AstcDecodeMode,
AstcDecodeMode,
VSyncMode,
NvdecEmulation,
FullscreenMode,
AspectRatio,
ResolutionSetup,
ScalingFilter,
AntiAliasing,
GpuAccuracy,
AnisotropyMode,
AstcRecompression,
VramUsageMode,
};
class VideoSetting
@ -35,12 +40,17 @@ namespace
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::RendererBackend, true> * val);
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::ShaderBackend, true> * val);
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::AstcDecodeMode, true> * val);
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::VSyncMode, true> * val);
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::NvdecEmulation> * val);
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::FullscreenMode, true> * val);
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::AspectRatio, true> * val);
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::ResolutionSetup> * val);
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::ScalingFilter> * val);
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::AntiAliasing> * val);
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::GpuAccuracy, true> * val);
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::AnisotropyMode, true> * val);
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::AstcRecompression, true> * val);
VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::VramUsageMode, true> * val);
const char * identifier;
const char * json_section;
@ -54,12 +64,17 @@ namespace
Settings::SwitchableSetting<Settings::RendererBackend, true>* rendererBackend;
Settings::SwitchableSetting<Settings::ShaderBackend, true> * shaderBackend;
Settings::SwitchableSetting<Settings::AstcDecodeMode, true> * astcDecodeMode;
Settings::SwitchableSetting<Settings::VSyncMode, true> * vSyncMode;
Settings::SwitchableSetting<Settings::NvdecEmulation> * nvdecEmulation;
Settings::SwitchableSetting<Settings::FullscreenMode, true> * fullscreenMode;
Settings::SwitchableSetting<Settings::AspectRatio, true> * aspectRatio;
Settings::SwitchableSetting<Settings::ResolutionSetup> * resolutionSetup;
Settings::SwitchableSetting<Settings::ScalingFilter> * scalingFilter;
Settings::SwitchableSetting<Settings::AntiAliasing> * antiAliasing;
Settings::SwitchableSetting<Settings::GpuAccuracy, true> * gpuAccuracy;
Settings::SwitchableSetting<Settings::AnisotropyMode, true> * anisotropyMode;
Settings::SwitchableSetting<Settings::AstcRecompression, true> * astcRecompression;
Settings::SwitchableSetting<Settings::VramUsageMode, true> * vramUsageMode;
} setting;
};
@ -70,6 +85,7 @@ namespace
{ NXVideoSetting::UseDiskPipelineCache, "video", "use_disk_shader_cache", &Settings::values.use_disk_shader_cache },
{ NXVideoSetting::UseAsynchronousGPUEmulation, "video", "use_asynchronous_gpu_emulation", &Settings::values.use_asynchronous_gpu_emulation },
{ NXVideoSetting::AstcDecodeMode, "video", "astc_decode_mode", &Settings::values.accelerate_astc },
{ NXVideoSetting::VSyncMode, "video", "vsync_mode", &Settings::values.vsync_mode },
{ NXVideoSetting::NvdecEmulation, "video", "nvdec_emulation", &Settings::values.nvdec_emulation },
{ NXVideoSetting::FullscreenMode, "video", "fullscreen_mode", &Settings::values.fullscreen_mode },
{ NXVideoSetting::AspectRatio, "video", "aspect_ratio", &Settings::values.aspect_ratio },
@ -85,6 +101,10 @@ namespace
{ NXVideoSetting::UseVulkanPipelineCache, "video", "use_vulkan_driver_pipeline_cache", &Settings::values.use_vulkan_driver_pipeline_cache },
{ NXVideoSetting::SyncToFramerateOfVideoPlayback, "video", "use_video_framerate", &Settings::values.use_video_framerate },
{ NXVideoSetting::BarrierFeedbackLoops, "video", "barrier_feedback_loops", &Settings::values.barrier_feedback_loops },
{ NXVideoSetting::AccuracyLevel, "video", "accuracy_level", &Settings::values.gpu_accuracy },
{ NXVideoSetting::AnisotropicFiltering, "video", "anisotropic_filtering", &Settings::values.max_anisotropy },
{ NXVideoSetting::ASTCRecompressionMethod, "video", "astc_recompression_method", &Settings::values.astc_recompression },
{ NXVideoSetting::VRAMUsageMode, "video", "vram_usage_mode", &Settings::values.vram_usage_mode },
};
}
@ -116,6 +136,9 @@ void VideoSettingChanged(const char * setting, void * /*userData*/)
case SettingType::AstcDecodeMode:
videoSetting.setting.astcDecodeMode->SetValue((Settings::AstcDecodeMode)g_settings->GetInt(setting));
break;
case SettingType::VSyncMode:
videoSetting.setting.vSyncMode->SetValue((Settings::VSyncMode)g_settings->GetInt(setting));
break;
case SettingType::NvdecEmulation:
videoSetting.setting.nvdecEmulation->SetValue((Settings::NvdecEmulation)g_settings->GetInt(setting));
break;
@ -134,6 +157,18 @@ void VideoSettingChanged(const char * setting, void * /*userData*/)
case SettingType::AntiAliasing:
videoSetting.setting.antiAliasing->SetValue((Settings::AntiAliasing)g_settings->GetInt(setting));
break;
case SettingType::GpuAccuracy:
videoSetting.setting.gpuAccuracy->SetValue((Settings::GpuAccuracy)g_settings->GetInt(setting));
break;
case SettingType::AnisotropyMode:
videoSetting.setting.anisotropyMode->SetValue((Settings::AnisotropyMode)g_settings->GetInt(setting));
break;
case SettingType::AstcRecompression:
videoSetting.setting.astcRecompression->SetValue((Settings::AstcRecompression)g_settings->GetInt(setting));
break;
case SettingType::VramUsageMode:
videoSetting.setting.vramUsageMode->SetValue((Settings::VramUsageMode)g_settings->GetInt(setting));
break;
default:
UNIMPLEMENTED();
}
@ -164,6 +199,9 @@ void SetupVideoSetting(void)
case SettingType::AstcDecodeMode:
videoSetting.setting.astcDecodeMode->SetValue(videoSetting.setting.astcDecodeMode->GetDefault());
break;
case SettingType::VSyncMode:
videoSetting.setting.vSyncMode->SetValue(videoSetting.setting.vSyncMode->GetDefault());
break;
case SettingType::NvdecEmulation:
videoSetting.setting.nvdecEmulation->SetValue(videoSetting.setting.nvdecEmulation->GetDefault());
break;
@ -182,6 +220,18 @@ void SetupVideoSetting(void)
case SettingType::AntiAliasing:
videoSetting.setting.antiAliasing->SetValue(videoSetting.setting.antiAliasing->GetDefault());
break;
case SettingType::GpuAccuracy:
videoSetting.setting.gpuAccuracy->SetValue(videoSetting.setting.gpuAccuracy->GetDefault());
break;
case SettingType::AnisotropyMode:
videoSetting.setting.anisotropyMode->SetValue(videoSetting.setting.anisotropyMode->GetDefault());
break;
case SettingType::AstcRecompression:
videoSetting.setting.astcRecompression->SetValue(videoSetting.setting.astcRecompression->GetDefault());
break;
case SettingType::VramUsageMode:
videoSetting.setting.vramUsageMode->SetValue(videoSetting.setting.vramUsageMode->GetDefault());
break;
default:
UNIMPLEMENTED();
}
@ -239,6 +289,12 @@ void SetupVideoSetting(void)
videoSetting.setting.astcDecodeMode->SetValue(Settings::ToEnum<Settings::AstcDecodeMode>(value.asString()));
}
break;
case SettingType::VSyncMode:
if (value.isString())
{
videoSetting.setting.vSyncMode->SetValue(Settings::ToEnum<Settings::VSyncMode>(value.asString()));
}
break;
case SettingType::NvdecEmulation:
if (value.isString())
{
@ -275,6 +331,30 @@ void SetupVideoSetting(void)
videoSetting.setting.antiAliasing->SetValue(Settings::ToEnum<Settings::AntiAliasing>(value.asString()));
}
break;
case SettingType::GpuAccuracy:
if (value.isString())
{
videoSetting.setting.gpuAccuracy->SetValue(Settings::ToEnum<Settings::GpuAccuracy>(value.asString()));
}
break;
case SettingType::AnisotropyMode:
if (value.isString())
{
videoSetting.setting.anisotropyMode->SetValue(Settings::ToEnum<Settings::AnisotropyMode>(value.asString()));
}
break;
case SettingType::AstcRecompression:
if (value.isString())
{
videoSetting.setting.astcRecompression->SetValue(Settings::ToEnum<Settings::AstcRecompression>(value.asString()));
}
break;
case SettingType::VramUsageMode:
if (value.isString())
{
videoSetting.setting.vramUsageMode->SetValue(Settings::ToEnum<Settings::VramUsageMode>(value.asString()));
}
break;
default:
UNIMPLEMENTED();
}
@ -309,6 +389,10 @@ void SetupVideoSetting(void)
g_settings->SetDefaultInt(videoSetting.identifier, (int32_t)videoSetting.setting.astcDecodeMode->GetDefault());
g_settings->SetInt(videoSetting.identifier, (int32_t)videoSetting.setting.astcDecodeMode->GetValue());
break;
case SettingType::VSyncMode:
g_settings->SetDefaultInt(videoSetting.identifier, (int32_t)videoSetting.setting.vSyncMode->GetDefault());
g_settings->SetInt(videoSetting.identifier, (int32_t)videoSetting.setting.vSyncMode->GetValue());
break;
case SettingType::NvdecEmulation:
g_settings->SetDefaultInt(videoSetting.identifier, (int32_t)videoSetting.setting.nvdecEmulation->GetDefault());
g_settings->SetInt(videoSetting.identifier, (int32_t)videoSetting.setting.nvdecEmulation->GetValue());
@ -333,6 +417,22 @@ void SetupVideoSetting(void)
g_settings->SetDefaultInt(videoSetting.identifier, (int32_t)videoSetting.setting.antiAliasing->GetDefault());
g_settings->SetInt(videoSetting.identifier, (int32_t)videoSetting.setting.antiAliasing->GetValue());
break;
case SettingType::GpuAccuracy:
g_settings->SetDefaultInt(videoSetting.identifier, (int32_t)videoSetting.setting.gpuAccuracy->GetDefault());
g_settings->SetInt(videoSetting.identifier, (int32_t)videoSetting.setting.gpuAccuracy->GetValue());
break;
case SettingType::AnisotropyMode:
g_settings->SetDefaultInt(videoSetting.identifier, (int32_t)videoSetting.setting.anisotropyMode->GetDefault());
g_settings->SetInt(videoSetting.identifier, (int32_t)videoSetting.setting.anisotropyMode->GetValue());
break;
case SettingType::AstcRecompression:
g_settings->SetDefaultInt(videoSetting.identifier, (int32_t)videoSetting.setting.astcRecompression->GetDefault());
g_settings->SetInt(videoSetting.identifier, (int32_t)videoSetting.setting.astcRecompression->GetValue());
break;
case SettingType::VramUsageMode:
g_settings->SetDefaultInt(videoSetting.identifier, (int32_t)videoSetting.setting.vramUsageMode->GetDefault());
g_settings->SetInt(videoSetting.identifier, (int32_t)videoSetting.setting.vramUsageMode->GetValue());
break;
default:
UNIMPLEMENTED();
}
@ -385,6 +485,12 @@ void SaveVideoSettings(void)
sections[videoSetting.json_section][videoSetting.json_key] = Settings::CanonicalizeEnum(videoSetting.setting.astcDecodeMode->GetValue());
}
break;
case SettingType::VSyncMode:
if (videoSetting.setting.vSyncMode->GetValue() != videoSetting.setting.vSyncMode->GetDefault())
{
sections[videoSetting.json_section][videoSetting.json_key] = Settings::CanonicalizeEnum(videoSetting.setting.vSyncMode->GetValue());
}
break;
case SettingType::NvdecEmulation:
if (videoSetting.setting.nvdecEmulation->GetValue() != videoSetting.setting.nvdecEmulation->GetDefault())
{
@ -421,6 +527,30 @@ void SaveVideoSettings(void)
sections[videoSetting.json_section][videoSetting.json_key] = Settings::CanonicalizeEnum(videoSetting.setting.antiAliasing->GetValue());
}
break;
case SettingType::GpuAccuracy:
if (videoSetting.setting.gpuAccuracy->GetValue() != videoSetting.setting.gpuAccuracy->GetDefault())
{
sections[videoSetting.json_section][videoSetting.json_key] = Settings::CanonicalizeEnum(videoSetting.setting.gpuAccuracy->GetValue());
}
break;
case SettingType::AnisotropyMode:
if (videoSetting.setting.anisotropyMode->GetValue() != videoSetting.setting.anisotropyMode->GetDefault())
{
sections[videoSetting.json_section][videoSetting.json_key] = Settings::CanonicalizeEnum(videoSetting.setting.anisotropyMode->GetValue());
}
break;
case SettingType::AstcRecompression:
if (videoSetting.setting.astcRecompression->GetValue() != videoSetting.setting.astcRecompression->GetDefault())
{
sections[videoSetting.json_section][videoSetting.json_key] = Settings::CanonicalizeEnum(videoSetting.setting.astcRecompression->GetValue());
}
break;
case SettingType::VramUsageMode:
if (videoSetting.setting.vramUsageMode->GetValue() != videoSetting.setting.vramUsageMode->GetDefault())
{
sections[videoSetting.json_section][videoSetting.json_key] = Settings::CanonicalizeEnum(videoSetting.setting.vramUsageMode->GetValue());
}
break;
default:
UNIMPLEMENTED();
}
@ -493,6 +623,15 @@ namespace
setting.astcDecodeMode = val;
}
VideoSetting::VideoSetting(const char* id, const char * section, const char * key, Settings::SwitchableSetting<Settings::VSyncMode, true> * val) :
identifier(id),
json_section(section),
json_key(key),
settingType(SettingType::VSyncMode)
{
setting.vSyncMode = val;
}
VideoSetting::VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::NvdecEmulation> * val) :
identifier(id),
json_section(section),
@ -546,4 +685,40 @@ namespace
{
setting.antiAliasing = val;
}
VideoSetting::VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::GpuAccuracy, true> * val) :
identifier(id),
json_section(section),
json_key(key),
settingType(SettingType::GpuAccuracy)
{
setting.gpuAccuracy = val;
}
VideoSetting::VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::AnisotropyMode, true> * val) :
identifier(id),
json_section(section),
json_key(key),
settingType(SettingType::AnisotropyMode)
{
setting.anisotropyMode = val;
}
VideoSetting::VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::AstcRecompression, true> * val) :
identifier(id),
json_section(section),
json_key(key),
settingType(SettingType::AstcRecompression)
{
setting.astcRecompression = val;
}
VideoSetting::VideoSetting(const char * id, const char * section, const char * key, Settings::SwitchableSetting<Settings::VramUsageMode, true> * val) :
identifier(id),
json_section(section),
json_key(key),
settingType(SettingType::VramUsageMode)
{
setting.vramUsageMode = val;
}
}

View File

@ -8,6 +8,7 @@ namespace NXVideoSetting
constexpr const char * UseDiskPipelineCache = "nxvideo:UseDiskPipelineCache";
constexpr const char * UseAsynchronousGPUEmulation = "nxvideo:UseAsynchronousGPUEmulation";
constexpr const char * AstcDecodeMode = "nxvideo:AstcDecodeMode";
constexpr const char * VSyncMode = "nxvideo:VSyncMode";
constexpr const char * NvdecEmulation = "nxvideo:NvdecEmulation";
constexpr const char * FullscreenMode = "nxvideo:FullscreenMode";
constexpr const char * AspectRatio = "nxvideo:AspectRatio";
@ -23,5 +24,9 @@ namespace NXVideoSetting
constexpr const char * UseVulkanPipelineCache = "nxvideo:UseVulkanPipelineCache";
constexpr const char * SyncToFramerateOfVideoPlayback = "nxvideo:SyncToFramerateOfVideoPlayback";
constexpr const char * BarrierFeedbackLoops = "nxvideo:BarrierFeedbackLoops";
constexpr const char * AccuracyLevel = "nxvideo:AccuracyLevel";
constexpr const char * AnisotropicFiltering = "nxvideo:AnisotropicFiltering";
constexpr const char * ASTCRecompressionMethod = "nxvideo:ASTCRecompressionMethod";
constexpr const char * VRAMUsageMode = "nxvideo:VRAMUsageMode";
} // namespace NXVideoSetting

View File

@ -10,6 +10,7 @@
#include <widgets/combo_box.h>
#include <widgets/menubar.h>
#include <widgets/page_nav.h>
#include <widgets/tooltip_host.h>
#include <windows.h>
void RegisterWidgets(ISciterUI & sciterUI)
@ -17,6 +18,7 @@ void RegisterWidgets(ISciterUI & sciterUI)
Register_WidgetComboBox(sciterUI);
Register_WidgetMenuBar(sciterUI);
Register_WidgetPageNav(sciterUI);
Register_WidgetToolTipHost(sciterUI);
}
int WINAPI WinMain(_In_ HINSTANCE /*hInstance*/, _In_opt_ HINSTANCE /*hPrevInstance*/, _In_ LPSTR /*lpszArgs*/, _In_ int /*nWinMode*/)

View File

@ -321,8 +321,28 @@ void SystemConfig::InitializeTranslations()
{(uint32_t)Settings::AntiAliasing::Fxaa, "FXAA"},
{(uint32_t)Settings::AntiAliasing::Smaa, "SMAA"},
}});
m_settingTranslations.insert({ Settings::EnumMetadata<Settings::GpuAccuracy>::Index(), {
{(uint32_t)Settings::GpuAccuracy::Normal, "Normal"},
{(uint32_t)Settings::GpuAccuracy::High, "High"},
{(uint32_t)Settings::GpuAccuracy::Extreme, "Extreme"},
}});
m_settingTranslations.insert({ Settings::EnumMetadata<Settings::AnisotropyMode>::Index(), {
{(uint32_t)Settings::AnisotropyMode::Automatic, "Automatic"},
{(uint32_t)Settings::AnisotropyMode::Default, "Default"},
{(uint32_t)Settings::AnisotropyMode::X2, "2x"},
{(uint32_t)Settings::AnisotropyMode::X4, "4x"},
{(uint32_t)Settings::AnisotropyMode::X8, "8x"},
{(uint32_t)Settings::AnisotropyMode::X16, "16x"},
}});
m_settingTranslations.insert({ Settings::EnumMetadata<Settings::AstcRecompression>::Index(), {
{(uint32_t)Settings::AstcRecompression::Uncompressed, "Uncompressed (Best quality)"},
{(uint32_t)Settings::AstcRecompression::Bc1, "BC1 (Low quality)"},
{(uint32_t)Settings::AstcRecompression::Bc3, "BC3 (Medium quality)"},
}});
m_settingTranslations.insert({ Settings::EnumMetadata<Settings::VramUsageMode>::Index(), {
{(uint32_t)Settings::VramUsageMode::Conservative, "Conservative"},
{(uint32_t)Settings::VramUsageMode::Aggressive, "Aggressive"},
}});
SettingTranslationList vulkanDeviceTranslations;
for (size_t i = 0; i < m_vkDeviceRecords.size(); ++i)
{

View File

@ -3,6 +3,7 @@
#include "system_config.h"
#include <common/std_string.h>
#include <yuzu_common/settings_enums.h>
#include <nxemu-core/settings/settings.h>
#include <nxemu-video/video_settings_identifiers.h>
#include <widgets/combo_box.h>
@ -15,6 +16,7 @@ namespace
ConfigSetting(ConfigSetting::CheckBox, "UseDiskPipelineCache", NXVideoSetting::UseDiskPipelineCache),
ConfigSetting(ConfigSetting::CheckBox, "UseAsynchronousGPUEmulation", NXVideoSetting::UseAsynchronousGPUEmulation),
ConfigSetting(ConfigSetting::ComboBox, "AstcDecodeMode", Settings::EnumMetadata<Settings::AstcDecodeMode>::Index(), NXVideoSetting::AstcDecodeMode),
ConfigSetting(ConfigSetting::ComboBox, "VSyncMode", Settings::EnumMetadata<Settings::VSyncMode>::Index(), NXVideoSetting::VSyncMode),
ConfigSetting(ConfigSetting::ComboBox, "NvdecEmulation", Settings::EnumMetadata<Settings::NvdecEmulation>::Index(), NXVideoSetting::NvdecEmulation),
ConfigSetting(ConfigSetting::ComboBox, "FullscreenMode", Settings::EnumMetadata<Settings::FullscreenMode>::Index(), NXVideoSetting::FullscreenMode),
ConfigSetting(ConfigSetting::ComboBox, "AspectRatio", Settings::EnumMetadata<Settings::AspectRatio>::Index(), NXVideoSetting::AspectRatio),
@ -25,6 +27,10 @@ namespace
};
static ConfigSetting advancedSettings[] = {
ConfigSetting(ConfigSetting::ComboBox, "AccuracyLevel", Settings::EnumMetadata<Settings::GpuAccuracy>::Index(), NXVideoSetting::AccuracyLevel),
ConfigSetting(ConfigSetting::ComboBox, "AnisotropicFiltering", Settings::EnumMetadata<Settings::AnisotropyMode>::Index(), NXVideoSetting::AnisotropicFiltering),
ConfigSetting(ConfigSetting::ComboBox, "ASTCRecompressionMethod", Settings::EnumMetadata<Settings::AstcRecompression>::Index(), NXVideoSetting::ASTCRecompressionMethod),
ConfigSetting(ConfigSetting::ComboBox, "VRAMUsageMode", Settings::EnumMetadata<Settings::VramUsageMode>::Index(), NXVideoSetting::VRAMUsageMode),
ConfigSetting(ConfigSetting::CheckBox, "EnableAsynchronousPresentation", NXVideoSetting::EnableAsynchronousPresentation),
ConfigSetting(ConfigSetting::CheckBox, "ForceMaximumClocks", NXVideoSetting::ForceMaximumClocks),
ConfigSetting(ConfigSetting::CheckBox, "EnableReactiveFlushing", NXVideoSetting::EnableReactiveFlushing),
@ -34,6 +40,29 @@ namespace
ConfigSetting(ConfigSetting::CheckBox, "SyncToFramerateOfVideoPlayback", NXVideoSetting::SyncToFramerateOfVideoPlayback),
ConfigSetting(ConfigSetting::CheckBox, "BarrierFeedbackLoops", NXVideoSetting::BarrierFeedbackLoops),
};
Settings::RendererBackend RendererModeSelcted(ISciterUI & sciterUI, SciterElement & graphicsPage)
{
std::shared_ptr<void> interfacePtr = graphicsPage ? sciterUI.GetElementInterface(graphicsPage.GetElementByID("GraphicsAPI"), IID_ICOMBOBOX) : nullptr;
if (!interfacePtr)
{
return Settings::RendererBackend::Null;
}
std::shared_ptr<IComboBox> comboBox = std::static_pointer_cast<IComboBox>(interfacePtr);
SciterElement element = comboBox->GetSelectedItem();
if (!element)
{
return Settings::RendererBackend::Null;
}
std::string value = element.GetAttribute("value");
if (value.empty())
{
return Settings::RendererBackend::Null;
}
Settings::RendererBackend backend = (Settings::RendererBackend)std::stoi(value.c_str());
return backend;
}
}
SystemConfigGraphics::SystemConfigGraphics(ISciterUI & sciterUI, SystemConfig & config, HWINDOW parent, SciterElement page) :
@ -97,6 +126,7 @@ bool SystemConfigGraphics::OnStateChange(SCITER_ELEMENT elem, uint32_t /*eventRe
if (m_graphicsPage && elem == m_graphicsPage.GetElementByID("GraphicsAPI"))
{
UpdateGraphicsAPI();
UpdateVSyncMode();
}
else if (m_graphicsPage && elem == m_graphicsPage.GetElementByID("FSPSharpness"))
{
@ -117,48 +147,29 @@ void SystemConfigGraphics::SetupGraphicsPage(SciterElement page)
m_config.SetupPage(page, graphicsSettings, sizeof(graphicsSettings) / sizeof(graphicsSettings[0]));
m_sciterUI.AttachHandler(page.GetElementByID("GraphicsAPI"), IID_ISTATECHANGESINK, (IStateChangeSink*)this);
UpdateGraphicsAPI();
UpdateVSyncMode();
UpdateFSPSharpnessDisplay();
}
void SystemConfigGraphics::UpdateGraphicsAPI()
{
std::shared_ptr<void> interfacePtr = m_graphicsPage ? m_sciterUI.GetElementInterface(m_graphicsPage.GetElementByID("GraphicsAPI"), IID_ICOMBOBOX) : nullptr;
if (!interfacePtr)
{
return;
}
std::shared_ptr<IComboBox> comboBox = std::static_pointer_cast<IComboBox>(interfacePtr);
SciterElement element = comboBox->GetSelectedItem();
if (!element)
{
return;
}
std::string value = element.GetAttribute("value");
if (value.empty())
{
return;
}
SciterElement ShaderBackend = m_graphicsPage.GetElementByID("ShaderBackendRow");
SciterElement VulkanDevices = m_graphicsPage.GetElementByID("VulkanDevicesRow");
SciterElement VSyncMode = m_graphicsPage.GetElementByID("VSyncMode");
Settings::RendererBackend backend = (Settings::RendererBackend)std::stoi(value.c_str());
Settings::RendererBackend backend = RendererModeSelcted(m_sciterUI, m_graphicsPage);
switch (backend)
{
case Settings::RendererBackend::OpenGL:
ShaderBackend.SetStyleAttribute("display", "block");
VulkanDevices.SetStyleAttribute("display", "none");
VSyncMode.RemoveAttribute("disabled");
break;
case Settings::RendererBackend::Vulkan:
ShaderBackend.SetStyleAttribute("display", "none");
VulkanDevices.SetStyleAttribute("display", "block");
VSyncMode.RemoveAttribute("disabled");
break;
case Settings::RendererBackend::Null:
ShaderBackend.SetStyleAttribute("display", "none");
VulkanDevices.SetStyleAttribute("display", "none");
VSyncMode.SetAttribute("disabled", "");
break;
}
}
@ -181,4 +192,84 @@ void SystemConfigGraphics::UpdateFSPSharpnessDisplay()
fspSharpnessDisplay.SetHTML((const uint8_t*)text.c_str(), text.size());
}
}
}
void SystemConfigGraphics::UpdateVSyncMode()
{
Settings::RendererBackend backend = RendererModeSelcted(m_sciterUI, m_graphicsPage);
SciterElement vsyncMode = m_graphicsPage.GetElementByID("VSyncMode");
std::shared_ptr<void> interfacePtr = m_graphicsPage ? m_sciterUI.GetElementInterface(vsyncMode, IID_ICOMBOBOX) : nullptr;
if (!interfacePtr)
{
return;
}
std::shared_ptr<IComboBox> comboBox = std::static_pointer_cast<IComboBox>(interfacePtr);
SciterElement currentItem = comboBox->GetSelectedItem();
std::string currentValue;
if (currentItem)
{
currentValue = currentItem.GetAttribute("value");
}
SettingsStore & settingsStore = SettingsStore::GetInstance();
int32_t settingValue = settingsStore.GetInt(NXVideoSetting::VSyncMode);
int32_t defaultSettingValue = settingsStore.GetDefaultInt(NXVideoSetting::VSyncMode);
SciterElement element = comboBox->GetSelectedItem();
if (element)
{
std::string value = element.GetAttribute("value");
if (value.size() > 0)
{
settingValue = std::stoi(value.c_str());
}
}
std::vector<std::pair<int32_t, std::string>> vsyncOptions;
switch (backend)
{
case Settings::RendererBackend::OpenGL:
vsyncOptions.push_back({(int)Settings::VSyncMode::Immediate, "Off"});
vsyncOptions.push_back({(int)Settings::VSyncMode::Fifo, "On"});
break;
case Settings::RendererBackend::Vulkan:
vsyncOptions.push_back({ (int)Settings::VSyncMode::Immediate, "Immediate (VSync Off)" });
vsyncOptions.push_back({ (int)Settings::VSyncMode::Mailbox, "Mailbox (Recommended)" });
vsyncOptions.push_back({ (int)Settings::VSyncMode::Fifo, "FIFO (VSync On)" });
vsyncOptions.push_back({ (int)Settings::VSyncMode::FifoRelaxed, "FIFO Relaxed" });
break;
case Settings::RendererBackend::Null:
break;
}
comboBox->ClearContents();
int32_t selectedIndex = -1, defaultSelectedIndex = -1;
if (vsyncOptions.size() > 0)
{
vsyncMode.RemoveAttribute("disabled");
}
else
{
vsyncMode.SetAttribute("disabled", "");
}
for (size_t i = 0; i < vsyncOptions.size(); i++)
{
int32_t index = comboBox->AddItem(vsyncOptions[i].second.c_str(), stdstr_f("%d", vsyncOptions[i].first).c_str());
if (settingValue == vsyncOptions[i].first)
{
selectedIndex = index;
}
if (defaultSettingValue == vsyncOptions[i].first)
{
defaultSelectedIndex = index;
}
}
if (selectedIndex >= 0)
{
comboBox->SelectItem(selectedIndex);
}
else if (defaultSelectedIndex >= 0)
{
comboBox->SelectItem(defaultSelectedIndex);
}
}

View File

@ -34,6 +34,7 @@ private:
void SetupGraphicsPage(SciterElement page);
void UpdateGraphicsAPI();
void UpdateFSPSharpnessDisplay();
void UpdateVSyncMode();
ISciterUI & m_sciterUI;
SystemConfig & m_config;