mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-04-09 02:41:26 -06:00
Merge 367a38bdea into c650473fdc
This commit is contained in:
commit
c76cbcdb12
@ -40,6 +40,7 @@ foreach(KEY IN ITEMS
|
||||
"use_disk_shader_cache"
|
||||
"shaders_accurate_mul"
|
||||
"use_vsync"
|
||||
"use_skip_duplicate_frames"
|
||||
"use_display_refresh_rate_detection"
|
||||
"use_shader_jit"
|
||||
"resolution_factor"
|
||||
|
||||
@ -38,6 +38,7 @@ object SettingKeys {
|
||||
external fun use_disk_shader_cache(): String
|
||||
external fun shaders_accurate_mul(): String
|
||||
external fun use_vsync(): String
|
||||
external fun use_skip_duplicate_frames(): String
|
||||
external fun use_shader_jit(): String
|
||||
external fun resolution_factor(): String
|
||||
external fun frame_limit(): String
|
||||
|
||||
@ -152,6 +152,7 @@ void Config::ReadValues() {
|
||||
ReadSetting("Renderer", Settings::values.resolution_factor);
|
||||
ReadSetting("Renderer", Settings::values.use_disk_shader_cache);
|
||||
ReadSetting("Renderer", Settings::values.use_vsync);
|
||||
ReadSetting("Renderer", Settings::values.use_skip_duplicate_frames);
|
||||
ReadSetting("Renderer", Settings::values.texture_filter);
|
||||
ReadSetting("Renderer", Settings::values.texture_sampling);
|
||||
ReadSetting("Renderer", Settings::values.turbo_limit);
|
||||
|
||||
@ -127,6 +127,10 @@ static const char* android_config_default_file_content = (BOOST_HANA_STRING(R"(
|
||||
# 0 (default): Off, 1: On
|
||||
)") DECLARE_KEY(use_vsync) BOOST_HANA_STRING(R"(
|
||||
|
||||
# Skips display of duplicated frames in 30 fps games
|
||||
# 0 (default): Off, 1: On
|
||||
)") DECLARE_KEY(use_skip_duplicate_frames) BOOST_HANA_STRING(R"(
|
||||
|
||||
# Reduce stuttering by storing and loading generated shaders to disk
|
||||
# 0: Off, 1 (default. On)
|
||||
)") DECLARE_KEY(use_disk_shader_cache) BOOST_HANA_STRING(R"(
|
||||
|
||||
@ -706,6 +706,7 @@ void QtConfig::ReadRendererValues() {
|
||||
ReadGlobalSetting(Settings::values.shaders_accurate_mul);
|
||||
ReadGlobalSetting(Settings::values.use_disk_shader_cache);
|
||||
ReadGlobalSetting(Settings::values.use_vsync);
|
||||
ReadGlobalSetting(Settings::values.use_skip_duplicate_frames);
|
||||
ReadGlobalSetting(Settings::values.use_display_refresh_rate_detection);
|
||||
ReadGlobalSetting(Settings::values.resolution_factor);
|
||||
ReadGlobalSetting(Settings::values.use_integer_scaling);
|
||||
@ -1250,6 +1251,7 @@ void QtConfig::SaveRendererValues() {
|
||||
WriteGlobalSetting(Settings::values.shaders_accurate_mul);
|
||||
WriteGlobalSetting(Settings::values.use_disk_shader_cache);
|
||||
WriteGlobalSetting(Settings::values.use_vsync);
|
||||
WriteGlobalSetting(Settings::values.use_skip_duplicate_frames);
|
||||
WriteGlobalSetting(Settings::values.use_display_refresh_rate_detection);
|
||||
WriteGlobalSetting(Settings::values.resolution_factor);
|
||||
WriteGlobalSetting(Settings::values.use_integer_scaling);
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include "citra_qt/configuration/configuration_shared.h"
|
||||
#include "citra_qt/configuration/configure_graphics.h"
|
||||
#include "common/settings.h"
|
||||
#include "configuration/ui_configure_graphics.h"
|
||||
#include "ui_configure_graphics.h"
|
||||
#ifdef ENABLE_VULKAN
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
@ -144,6 +145,7 @@ void ConfigureGraphics::SetConfiguration() {
|
||||
ui->toggle_accurate_mul->setChecked(Settings::values.shaders_accurate_mul.GetValue());
|
||||
ui->toggle_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue());
|
||||
ui->toggle_vsync->setChecked(Settings::values.use_vsync.GetValue());
|
||||
ui->toggle_skip_duplicate_frames->setChecked(Settings::values.use_skip_duplicate_frames.GetValue());
|
||||
ui->spirv_shader_gen->setChecked(Settings::values.spirv_shader_gen.GetValue());
|
||||
ui->disable_spirv_optimizer->setChecked(Settings::values.disable_spirv_optimizer.GetValue());
|
||||
ui->toggle_async_shaders->setChecked(Settings::values.async_shader_compilation.GetValue());
|
||||
@ -179,6 +181,8 @@ void ConfigureGraphics::ApplyConfiguration() {
|
||||
ui->toggle_disk_shader_cache, use_disk_shader_cache);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->toggle_vsync,
|
||||
use_vsync);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_skip_duplicate_frames, ui->toggle_skip_duplicate_frames,
|
||||
use_skip_duplicate_frames);
|
||||
ConfigurationShared::ApplyPerGameSetting(
|
||||
&Settings::values.delay_game_render_thread_us, ui->delay_render_combo,
|
||||
[this](s32) { return ui->delay_render_slider->value(); });
|
||||
@ -204,6 +208,8 @@ void ConfigureGraphics::SetupPerGameUI() {
|
||||
Settings::values.use_disk_shader_cache.UsingGlobal());
|
||||
ui->toggle_vsync->setEnabled(ui->toggle_vsync->isEnabled() &&
|
||||
Settings::values.use_vsync.UsingGlobal());
|
||||
ui->toggle_skip_duplicate_frames->setEnabled(ui->toggle_skip_duplicate_frames->isEnabled() &&
|
||||
Settings::values.use_skip_duplicate_frames.UsingGlobal());
|
||||
ui->toggle_async_shaders->setEnabled(
|
||||
Settings::values.async_shader_compilation.UsingGlobal());
|
||||
ui->widget_texture_sampling->setEnabled(Settings::values.texture_sampling.UsingGlobal());
|
||||
@ -244,6 +250,8 @@ void ConfigureGraphics::SetupPerGameUI() {
|
||||
use_disk_shader_cache);
|
||||
ConfigurationShared::SetColoredTristate(ui->toggle_vsync, Settings::values.use_vsync,
|
||||
use_vsync);
|
||||
ConfigurationShared::SetColoredTristate(ui->toggle_skip_duplicate_frames, Settings::values.use_skip_duplicate_frames,
|
||||
use_skip_duplicate_frames);
|
||||
ConfigurationShared::SetColoredTristate(ui->toggle_async_shaders,
|
||||
Settings::values.async_shader_compilation,
|
||||
async_shader_compilation);
|
||||
|
||||
@ -39,6 +39,7 @@ private:
|
||||
ConfigurationShared::CheckState shaders_accurate_mul;
|
||||
ConfigurationShared::CheckState use_disk_shader_cache;
|
||||
ConfigurationShared::CheckState use_vsync;
|
||||
ConfigurationShared::CheckState use_skip_duplicate_frames;
|
||||
ConfigurationShared::CheckState use_display_refresh_rate_detection;
|
||||
ConfigurationShared::CheckState async_shader_compilation;
|
||||
ConfigurationShared::CheckState async_presentation;
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>509</height>
|
||||
<height>559</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
@ -138,12 +138,12 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="disable_spirv_optimizer">
|
||||
<property name="text">
|
||||
<string>Disable GLSL -> SPIR-V optimizer</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Disables the SPIR-V optimization pass, reducing stuttering considerably while barely affecting performance.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disable GLSL -> SPIR-V optimizer</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -317,6 +317,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_skip_duplicate_frames">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>This detects and skips the presentation of frames that are not unique. It also allows external frame generation tools to work correctly with 30fps games. Works in OpenGL and Vulkan.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Skip Presenting Duplicate Frames</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_display_refresh_rate_detection">
|
||||
<property name="toolTip">
|
||||
@ -328,81 +338,81 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="delay_render_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="delay_render_layout_inner">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
<widget class="QWidget" name="delay_render_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="delay_render_layout_inner">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QComboBox" name="delay_render_combo">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use global</string>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use per-application</string>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QComboBox" name="delay_render_combo">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use global</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use per-application</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_delay_render">
|
||||
<property name="text">
|
||||
<string>Delay Application Render Thread</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Delays the emulated application render thread the specified amount of milliseconds every time it submits render commands to the GPU.</p><p>Adjust this feature in the (very few) dynamic framerate applications to fix performance issues.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="delay_render_slider">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>16000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>250</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="delay_render_display_label">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_delay_render">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Delays the emulated application render thread the specified amount of milliseconds every time it submits render commands to the GPU.</p><p>Adjust this feature in the (very few) dynamic framerate applications to fix performance issues.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delay Application Render Thread</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="delay_render_slider">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>16000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>250</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TickPosition::TicksBelow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="delay_render_display_label">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@ -410,7 +420,7 @@
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
||||
@ -100,6 +100,7 @@ void LogSettings() {
|
||||
log_setting("Renderer_UseIntegerScaling", values.use_integer_scaling.GetValue());
|
||||
log_setting("Renderer_FrameLimit", values.frame_limit.GetValue());
|
||||
log_setting("Renderer_VSyncNew", values.use_vsync.GetValue());
|
||||
log_setting("Renderer_SkipDuplicateFrames", values.use_skip_duplicate_frames.GetValue());
|
||||
log_setting("Renderer_PostProcessingShader", values.pp_shader_name.GetValue());
|
||||
log_setting("Renderer_FilterMode", values.filter_mode.GetValue());
|
||||
log_setting("Renderer_TextureFilter", GetTextureFilterName(values.texture_filter.GetValue()));
|
||||
@ -209,6 +210,7 @@ void RestoreGlobalState(bool is_powered_on) {
|
||||
values.use_disk_shader_cache.SetGlobal(true);
|
||||
values.shaders_accurate_mul.SetGlobal(true);
|
||||
values.use_vsync.SetGlobal(true);
|
||||
values.use_skip_duplicate_frames.SetGlobal(true);
|
||||
values.resolution_factor.SetGlobal(true);
|
||||
values.use_integer_scaling.SetGlobal(true);
|
||||
values.frame_limit.SetGlobal(true);
|
||||
|
||||
@ -524,6 +524,7 @@ struct Values {
|
||||
SwitchableSetting<bool> async_presentation{true, Keys::async_presentation};
|
||||
SwitchableSetting<bool> use_hw_shader{true, Keys::use_hw_shader};
|
||||
SwitchableSetting<bool> use_disk_shader_cache{true, Keys::use_disk_shader_cache};
|
||||
SwitchableSetting<bool> use_skip_duplicate_frames{true, Keys::use_skip_duplicate_frames};
|
||||
SwitchableSetting<bool> shaders_accurate_mul{true, Keys::shaders_accurate_mul};
|
||||
#ifdef ANDROID // TODO: Fuck this -OS
|
||||
SwitchableSetting<bool> use_vsync{false, Keys::use_vsync};
|
||||
|
||||
@ -29,6 +29,8 @@ constexpr std::size_t IgnoreFrames = 5;
|
||||
|
||||
namespace Core {
|
||||
|
||||
bool PerfStats::game_frames_updated = true;
|
||||
|
||||
PerfStats::PerfStats(u64 title_id) : title_id(title_id) {}
|
||||
|
||||
PerfStats::~PerfStats() {
|
||||
@ -109,6 +111,7 @@ void PerfStats::EndGameFrame() {
|
||||
std::scoped_lock lock{object_mutex};
|
||||
|
||||
game_frames += 1;
|
||||
PerfStats::game_frames_updated = true;
|
||||
}
|
||||
|
||||
double PerfStats::GetMeanFrametime() const {
|
||||
|
||||
@ -120,6 +120,8 @@ public:
|
||||
artic_events.Set(event, set);
|
||||
}
|
||||
}
|
||||
/// Boolean representing whether game_frames has been updated since last time it was presented
|
||||
static bool game_frames_updated;
|
||||
|
||||
private:
|
||||
mutable std::mutex object_mutex;
|
||||
|
||||
@ -196,6 +196,7 @@ void RendererOpenGL::PrepareRendertarget() {
|
||||
void RendererOpenGL::RenderToMailbox(const Layout::FramebufferLayout& layout,
|
||||
std::unique_ptr<Frontend::TextureMailbox>& mailbox,
|
||||
bool flipped) {
|
||||
if ((Core::PerfStats::game_frames_updated && Settings::values.use_skip_duplicate_frames.GetValue()) || !Settings::values.use_skip_duplicate_frames.GetValue()){
|
||||
|
||||
Frontend::Frame* frame;
|
||||
{
|
||||
@ -241,6 +242,9 @@ void RendererOpenGL::RenderToMailbox(const Layout::FramebufferLayout& layout,
|
||||
glFlush();
|
||||
mailbox->ReleaseRenderFrame(frame);
|
||||
}
|
||||
|
||||
Core::PerfStats::game_frames_updated = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -24,7 +24,6 @@
|
||||
#include "video_core/host_shaders/vulkan_cursor_vert.h"
|
||||
|
||||
#include <vk_mem_alloc.h>
|
||||
|
||||
#if defined(__APPLE__) && !defined(HAVE_LIBRETRO)
|
||||
#include "common/apple_utils.h"
|
||||
#endif
|
||||
@ -237,23 +236,26 @@ void RendererVulkan::PrepareDraw(Frame* frame, const Layout::FramebufferLayout&
|
||||
|
||||
void RendererVulkan::RenderToWindow(PresentWindow& window, const Layout::FramebufferLayout& layout,
|
||||
bool flipped) {
|
||||
Frame* frame = window.GetRenderFrame();
|
||||
|
||||
if (layout.width != frame->width || layout.height != frame->height) {
|
||||
window.WaitPresent();
|
||||
scheduler.Finish();
|
||||
window.RecreateFrame(frame, layout.width, layout.height);
|
||||
if ((Core::PerfStats::game_frames_updated && Settings::values.use_skip_duplicate_frames.GetValue()) || !Settings::values.use_skip_duplicate_frames.GetValue()){
|
||||
Frame* frame = window.GetRenderFrame();
|
||||
|
||||
if (layout.width != frame->width || layout.height != frame->height) {
|
||||
window.WaitPresent();
|
||||
scheduler.Finish();
|
||||
window.RecreateFrame(frame, layout.width, layout.height);
|
||||
}
|
||||
|
||||
clear_color.float32[0] = Settings::values.bg_red.GetValue();
|
||||
clear_color.float32[1] = Settings::values.bg_green.GetValue();
|
||||
clear_color.float32[2] = Settings::values.bg_blue.GetValue();
|
||||
clear_color.float32[3] = 1.0f;
|
||||
|
||||
DrawScreens(frame, layout, flipped);
|
||||
scheduler.Flush(frame->render_ready);
|
||||
window.Present(frame);
|
||||
Core::PerfStats::game_frames_updated = false;
|
||||
}
|
||||
|
||||
clear_color.float32[0] = Settings::values.bg_red.GetValue();
|
||||
clear_color.float32[1] = Settings::values.bg_green.GetValue();
|
||||
clear_color.float32[2] = Settings::values.bg_blue.GetValue();
|
||||
clear_color.float32[3] = 1.0f;
|
||||
|
||||
DrawScreens(frame, layout, flipped);
|
||||
scheduler.Flush(frame->render_ready);
|
||||
|
||||
window.Present(frame);
|
||||
}
|
||||
|
||||
void RendererVulkan::LoadFBToScreenInfo(const Pica::FramebufferConfig& framebuffer,
|
||||
|
||||
@ -134,7 +134,6 @@ private:
|
||||
DescriptorUpdateQueue update_queue;
|
||||
RasterizerVulkan rasterizer;
|
||||
std::unique_ptr<PresentWindow> secondary_present_window_ptr;
|
||||
|
||||
DescriptorHeap present_heap;
|
||||
vk::UniquePipelineLayout present_pipeline_layout;
|
||||
std::array<vk::Pipeline, PRESENT_PIPELINES> present_pipelines;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user