diff options
-rw-r--r-- | src/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/core/file_sys/control_metadata.cpp | 3 | ||||
-rw-r--r-- | src/core/file_sys/control_metadata.h | 3 | ||||
-rw-r--r-- | src/core/hle/kernel/k_scheduler.h | 5 | ||||
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 17 | ||||
-rw-r--r-- | src/core/hle/result.h | 28 | ||||
-rw-r--r-- | src/core/hle/service/ns/language.cpp | 26 | ||||
-rw-r--r-- | src/core/hle/service/ns/language.h | 1 | ||||
-rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | 21 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_device.cpp | 15 | ||||
-rw-r--r-- | src/yuzu/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_dialog.cpp | 7 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_per_game.cpp | 2 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_per_game.ui | 8 | ||||
-rw-r--r-- | src/yuzu/main.cpp | 19 |
15 files changed, 142 insertions, 24 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6e66dc1df..63dd9febf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,6 +32,7 @@ if (MSVC) # /Zc:externConstexpr - Allow extern constexpr variables to have external linkage, like the standard mandates # /Zc:inline - Let codegen omit inline functions in object files # /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null + # /GT - Supports fiber safety for data allocated using static thread-local storage add_compile_options( /MP /Zi @@ -44,6 +45,7 @@ if (MSVC) /Zc:externConstexpr /Zc:inline /Zc:throwingNew + /GT # External headers diagnostics /experimental:external # Enables the external headers options. This option isn't required in Visual Studio 2019 version 16.10 and later @@ -69,6 +71,10 @@ if (MSVC) /we5038 # data member 'member1' will be initialized after data member 'member2' ) + if (ARCHITECTURE_x86_64) + add_compile_options(/QIntel-jcc-erratum) + endif() + # /GS- - No stack buffer overflow checks add_compile_options("$<$<CONFIG:Release>:/GS->") diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp index f66759815..05936f3c3 100644 --- a/src/core/file_sys/control_metadata.cpp +++ b/src/core/file_sys/control_metadata.cpp @@ -9,7 +9,7 @@ namespace FileSys { -const std::array<const char*, 15> LANGUAGE_NAMES{{ +const std::array<const char*, 16> LANGUAGE_NAMES{{ "AmericanEnglish", "BritishEnglish", "Japanese", @@ -25,6 +25,7 @@ const std::array<const char*, 15> LANGUAGE_NAMES{{ "Korean", "Taiwanese", "Chinese", + "BrazilianPortuguese", }}; std::string LanguageEntry::GetApplicationName() const { diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h index dd9837cf5..af2b723df 100644 --- a/src/core/file_sys/control_metadata.h +++ b/src/core/file_sys/control_metadata.h @@ -88,11 +88,12 @@ enum class Language : u8 { Korean = 12, Taiwanese = 13, Chinese = 14, + BrazilianPortuguese = 15, Default = 255, }; -extern const std::array<const char*, 15> LANGUAGE_NAMES; +extern const std::array<const char*, 16> LANGUAGE_NAMES; // A class representing the format used by NX metadata files, typically named Control.nacp. // These store application name, dev name, title id, and other miscellaneous data. diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h index c8ccc1ae4..7df288438 100644 --- a/src/core/hle/kernel/k_scheduler.h +++ b/src/core/hle/kernel/k_scheduler.h @@ -49,6 +49,11 @@ public: /// Gets the current running thread [[nodiscard]] KThread* GetCurrentThread() const; + /// Gets the idle thread + [[nodiscard]] KThread* GetIdleThread() const { + return idle_thread; + } + /// Returns true if the scheduler is idle [[nodiscard]] bool IsIdle() const { return GetCurrentThread() == idle_thread; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index f98f24a60..7f38ade1c 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -886,7 +886,24 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle *result = out_ticks; return ResultSuccess; } + case GetInfoType::IdleTickCount: { + if (handle == 0) { + LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", + static_cast<Handle>(handle)); + return ResultInvalidHandle; + } + if (info_sub_id != 0xFFFFFFFFFFFFFFFF && info_sub_id != system.CurrentCoreIndex()) { + LOG_ERROR(Kernel_SVC, "Core is not the current core, got {}", info_sub_id); + return ResultInvalidCombination; + } + + const auto& scheduler = *system.Kernel().CurrentScheduler(); + const auto* const idle_thread = scheduler.GetIdleThread(); + + *result = idle_thread->GetCpuTime(); + return ResultSuccess; + } default: LOG_ERROR(Kernel_SVC, "Unimplemented svcGetInfo id=0x{:016X}", info_id); return ResultInvalidEnumValue; diff --git a/src/core/hle/result.h b/src/core/hle/result.h index a755008d5..2c6b24848 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -206,7 +206,7 @@ public: return result; } - ResultVal(const ResultVal& o) : result_code(o.result_code) { + ResultVal(const ResultVal& o) noexcept : result_code(o.result_code) { if (!o.empty()) { new (&object) T(o.object); } @@ -224,7 +224,7 @@ public: } } - ResultVal& operator=(const ResultVal& o) { + ResultVal& operator=(const ResultVal& o) noexcept { if (this == &o) { return *this; } @@ -244,6 +244,26 @@ public: return *this; } + ResultVal& operator=(ResultVal&& o) noexcept { + if (this == &o) { + return *this; + } + if (!empty()) { + if (!o.empty()) { + object = std::move(o.object); + } else { + object.~T(); + } + } else { + if (!o.empty()) { + new (&object) T(std::move(o.object)); + } + } + result_code = o.result_code; + + return *this; + } + /** * Replaces the current result with a new constructed result value in-place. The code must not * be an error code. @@ -329,8 +349,8 @@ template <typename T, typename... Args> * copy or move constructing. */ template <typename Arg> -[[nodiscard]] ResultVal<std::remove_reference_t<Arg>> MakeResult(Arg&& arg) { - return ResultVal<std::remove_reference_t<Arg>>::WithCode(ResultSuccess, std::forward<Arg>(arg)); +[[nodiscard]] ResultVal<std::remove_cvref_t<Arg>> MakeResult(Arg&& arg) { + return ResultVal<std::remove_cvref_t<Arg>>::WithCode(ResultSuccess, std::forward<Arg>(arg)); } /** diff --git a/src/core/hle/service/ns/language.cpp b/src/core/hle/service/ns/language.cpp index 7d9e4a20b..e01c6be47 100644 --- a/src/core/hle/service/ns/language.cpp +++ b/src/core/hle/service/ns/language.cpp @@ -277,6 +277,25 @@ constexpr ApplicationLanguagePriorityList priority_list_simplified_chinese = {{ ApplicationLanguage::Korean, }}; +constexpr ApplicationLanguagePriorityList priority_list_brazilian_portuguese = {{ + ApplicationLanguage::BrazilianPortuguese, + ApplicationLanguage::Portuguese, + ApplicationLanguage::LatinAmericanSpanish, + ApplicationLanguage::AmericanEnglish, + ApplicationLanguage::BritishEnglish, + ApplicationLanguage::Japanese, + ApplicationLanguage::French, + ApplicationLanguage::German, + ApplicationLanguage::Spanish, + ApplicationLanguage::Italian, + ApplicationLanguage::Dutch, + ApplicationLanguage::CanadianFrench, + ApplicationLanguage::Russian, + ApplicationLanguage::Korean, + ApplicationLanguage::SimplifiedChinese, + ApplicationLanguage::TraditionalChinese, +}}; + const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList( const ApplicationLanguage lang) { switch (lang) { @@ -310,6 +329,8 @@ const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList( return &priority_list_traditional_chinese; case ApplicationLanguage::SimplifiedChinese: return &priority_list_simplified_chinese; + case ApplicationLanguage::BrazilianPortuguese: + return &priority_list_brazilian_portuguese; default: return nullptr; } @@ -339,7 +360,6 @@ std::optional<ApplicationLanguage> ConvertToApplicationLanguage( case Set::LanguageCode::FR_CA: return ApplicationLanguage::CanadianFrench; case Set::LanguageCode::PT: - case Set::LanguageCode::PT_BR: return ApplicationLanguage::Portuguese; case Set::LanguageCode::RU: return ApplicationLanguage::Russian; @@ -351,6 +371,8 @@ std::optional<ApplicationLanguage> ConvertToApplicationLanguage( case Set::LanguageCode::ZH_CN: case Set::LanguageCode::ZH_HANS: return ApplicationLanguage::SimplifiedChinese; + case Set::LanguageCode::PT_BR: + return ApplicationLanguage::BrazilianPortuguese; default: return std::nullopt; } @@ -388,6 +410,8 @@ std::optional<Set::LanguageCode> ConvertToLanguageCode(const ApplicationLanguage return Set::LanguageCode::ZH_HANT; case ApplicationLanguage::SimplifiedChinese: return Set::LanguageCode::ZH_HANS; + case ApplicationLanguage::BrazilianPortuguese: + return Set::LanguageCode::PT_BR; default: return std::nullopt; } diff --git a/src/core/hle/service/ns/language.h b/src/core/hle/service/ns/language.h index e9829f9d2..d84c3f277 100644 --- a/src/core/hle/service/ns/language.h +++ b/src/core/hle/service/ns/language.h @@ -30,6 +30,7 @@ enum class ApplicationLanguage : u8 { Korean, TraditionalChinese, SimplifiedChinese, + BrazilianPortuguese, Count }; using ApplicationLanguagePriorityList = diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 3588f052b..1d5364309 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -355,11 +355,22 @@ Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id dref, Id bias_lc, const IR::Value& offset) { const auto info{inst->Flags<IR::TextureInstInfo>()}; - const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0, bias_lc, - offset); - return Emit(&EmitContext::OpImageSparseSampleDrefImplicitLod, - &EmitContext::OpImageSampleDrefImplicitLod, ctx, inst, ctx.F32[1], - Texture(ctx, info, index), coords, dref, operands.MaskOptional(), operands.Span()); + if (ctx.stage == Stage::Fragment) { + const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0, + bias_lc, offset); + return Emit(&EmitContext::OpImageSparseSampleDrefImplicitLod, + &EmitContext::OpImageSampleDrefImplicitLod, ctx, inst, ctx.F32[1], + Texture(ctx, info, index), coords, dref, operands.MaskOptional(), + operands.Span()); + } else { + // Implicit lods in compute behave on hardware as if sampling from LOD 0. + // This check is to ensure all drivers behave this way. + const Id lod{ctx.Const(0.0f)}; + const ImageOperands operands(ctx, false, true, false, lod, offset); + return Emit(&EmitContext::OpImageSparseSampleDrefExplicitLod, + &EmitContext::OpImageSampleDrefExplicitLod, ctx, inst, ctx.F32[1], + Texture(ctx, info, index), coords, dref, operands.Mask(), operands.Span()); + } } Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index 1e1d1d020..0764ea6e0 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp @@ -181,6 +181,21 @@ Device::Device() { LOG_ERROR(Render_OpenGL, "Assembly shaders enabled but not supported"); shader_backend = Settings::ShaderBackend::GLSL; } + + if (shader_backend == Settings::ShaderBackend::GLSL && is_nvidia && + !Settings::values.renderer_debug) { + const std::string_view driver_version = version.substr(13); + const int version_major = + std::atoi(driver_version.substr(0, driver_version.find(".")).data()); + + if (version_major >= 495) { + LOG_WARNING(Render_OpenGL, "NVIDIA drivers 495 and later causes significant problems " + "with yuzu. Forcing GLASM as a mitigation."); + shader_backend = Settings::ShaderBackend::GLASM; + use_assembly_shaders = true; + } + } + // Blocks AMD and Intel OpenGL drivers on Windows from using asynchronous shader compilation. use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue() && !(is_amd || (is_intel && !is_linux)); diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 402be6a78..d62fd566f 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -299,6 +299,11 @@ if (YUZU_USE_BUNDLED_QT) copy_yuzu_Qt5_deps(yuzu) endif() +if (ENABLE_SDL2) + target_link_libraries(yuzu PRIVATE SDL2) + target_compile_definitions(yuzu PRIVATE HAVE_SDL2) +endif() + if (MSVC) include(CopyYuzuSDLDeps) include(CopyYuzuFFmpegDeps) diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index 4fa0c4a43..642a5f966 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -81,8 +81,11 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, SetConfiguration(); PopulateSelectionList(); - connect(ui->tabWidget, &QTabWidget::currentChanged, this, - [this]() { debug_tab_tab->SetCurrentIndex(0); }); + connect(ui->tabWidget, &QTabWidget::currentChanged, this, [this](int index) { + if (index != -1) { + debug_tab_tab->SetCurrentIndex(0); + } + }); connect(ui_tab.get(), &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged); connect(ui->selectorList, &QListWidget::itemSelectionChanged, this, &ConfigureDialog::UpdateVisibleTabs); diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index 1031399e1..12699c126 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -66,7 +66,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id, const std::str ui->tabWidget->addTab(system_tab.get(), tr("System")); ui->tabWidget->addTab(cpu_tab.get(), tr("CPU")); ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics")); - ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("GraphicsAdvanced")); + ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics")); ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); setFocusPolicy(Qt::ClickFocus); diff --git a/src/yuzu/configuration/configure_per_game.ui b/src/yuzu/configuration/configure_per_game.ui index 60efdbf21..85c86e107 100644 --- a/src/yuzu/configuration/configure_per_game.ui +++ b/src/yuzu/configuration/configure_per_game.ui @@ -2,14 +2,6 @@ <ui version="4.0"> <class>ConfigurePerGame</class> <widget class="QDialog" name="ConfigurePerGame"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>900</width> - <height>630</height> - </rect> - </property> <property name="minimumSize"> <size> <width>900</width> diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 2af582fe5..e871fee36 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -66,6 +66,10 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include <QUrl> #include <QtConcurrent/QtConcurrent> +#ifdef HAVE_SDL2 +#include <SDL.h> // For SDL ScreenSaver functions +#endif + #include <fmt/format.h> #include "common/detached_tasks.h" #include "common/fs/fs.h" @@ -287,6 +291,14 @@ GMainWindow::GMainWindow() ui->action_Fullscreen->setChecked(false); +#if defined(HAVE_SDL2) && !defined(_WIN32) + SDL_InitSubSystem(SDL_INIT_VIDEO); + // SDL disables the screen saver by default, and setting the hint + // SDL_HINT_VIDEO_ALLOW_SCREENSAVER doesn't seem to work, so we just enable the screen saver + // for now. + SDL_EnableScreenSaver(); +#endif + QStringList args = QApplication::arguments(); if (args.size() < 2) { @@ -357,8 +369,9 @@ GMainWindow::GMainWindow() GMainWindow::~GMainWindow() { // will get automatically deleted otherwise - if (render_window->parent() == nullptr) + if (render_window->parent() == nullptr) { delete render_window; + } } void GMainWindow::RegisterMetaTypes() { @@ -1223,12 +1236,16 @@ void GMainWindow::OnDisplayTitleBars(bool show) { void GMainWindow::PreventOSSleep() { #ifdef _WIN32 SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED); +#elif defined(HAVE_SDL2) + SDL_DisableScreenSaver(); #endif } void GMainWindow::AllowOSSleep() { #ifdef _WIN32 SetThreadExecutionState(ES_CONTINUOUS); +#elif defined(HAVE_SDL2) + SDL_EnableScreenSaver(); #endif } |