summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/core/file_sys/control_metadata.cpp3
-rw-r--r--src/core/file_sys/control_metadata.h3
-rw-r--r--src/core/hle/kernel/k_scheduler.h5
-rw-r--r--src/core/hle/kernel/svc.cpp17
-rw-r--r--src/core/hle/result.h28
-rw-r--r--src/core/hle/service/ns/language.cpp26
-rw-r--r--src/core/hle/service/ns/language.h1
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_image.cpp21
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp15
-rw-r--r--src/yuzu/CMakeLists.txt5
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp7
-rw-r--r--src/yuzu/configuration/configure_per_game.cpp2
-rw-r--r--src/yuzu/configuration/configure_per_game.ui8
-rw-r--r--src/yuzu/configuration/configure_profile_manager.cpp11
-rw-r--r--src/yuzu/main.cpp19
16 files changed, 153 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 d30755b7e..c43135856 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -890,7 +890,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/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp
index 99d5f4686..78b6374c0 100644
--- a/src/yuzu/configuration/configure_profile_manager.cpp
+++ b/src/yuzu/configuration/configure_profile_manager.cpp
@@ -306,6 +306,17 @@ void ConfigureProfileManager::SetUserImage() {
return;
}
+ // Some games crash when the profile image is too big. Resize any image bigger than 256x256
+ QImage image(image_path);
+ if (image.width() > 256 || image.height() > 256) {
+ image = image.scaled(256, 256, Qt::KeepAspectRatio);
+ if (!image.save(image_path)) {
+ QMessageBox::warning(this, tr("Error resizing user image"),
+ tr("Unable to resize image"));
+ return;
+ }
+ }
+
const auto username = GetAccountUsername(*profile_manager, *uuid);
item_model->setItem(index, 0,
new QStandardItem{GetIcon(*uuid), FormatUserEntryText(username, *uuid)});
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
}