mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-26 03:01:17 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 87d2f03c39 | |||
| bebc19da32 | |||
| 99bf8cf51a | |||
| dbeb73ee01 |
@@ -16,12 +16,16 @@ import java.io.FileOutputStream
|
|||||||
import java.security.KeyStore
|
import java.security.KeyStore
|
||||||
import javax.net.ssl.TrustManagerFactory
|
import javax.net.ssl.TrustManagerFactory
|
||||||
import javax.net.ssl.X509TrustManager
|
import javax.net.ssl.X509TrustManager
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import android.os.LocaleList
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
||||||
import org.yuzu.yuzu_emu.utils.DocumentsTree
|
import org.yuzu.yuzu_emu.utils.DocumentsTree
|
||||||
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
||||||
import org.yuzu.yuzu_emu.utils.Log
|
import org.yuzu.yuzu_emu.utils.Log
|
||||||
import org.yuzu.yuzu_emu.utils.PowerStateUpdater
|
import org.yuzu.yuzu_emu.utils.PowerStateUpdater
|
||||||
import org.yuzu.yuzu_emu.utils.ControllerNavigationGlobalHook
|
import org.yuzu.yuzu_emu.utils.ControllerNavigationGlobalHook
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
fun Context.getPublicFilesDir(): File = getExternalFilesDir(null) ?: filesDir
|
fun Context.getPublicFilesDir(): File = getExternalFilesDir(null) ?: filesDir
|
||||||
|
|
||||||
@@ -80,5 +84,38 @@ class YuzuApplication : Application() {
|
|||||||
|
|
||||||
val appContext: Context
|
val appContext: Context
|
||||||
get() = application.applicationContext
|
get() = application.applicationContext
|
||||||
|
|
||||||
|
private val LANGUAGE_CODES = arrayOf(
|
||||||
|
"system", "en", "es", "fr", "de", "it", "pt", "pt-BR", "ru", "ja", "ko",
|
||||||
|
"zh-CN", "zh-TW", "pl", "cs", "nb", "hu", "uk", "vi", "id", "ar", "ckb", "fa", "he", "sr"
|
||||||
|
)
|
||||||
|
|
||||||
|
fun applyLanguage(context: Context): Context {
|
||||||
|
val languageIndex = IntSetting.APP_LANGUAGE.getInt()
|
||||||
|
val langCode = if (languageIndex in LANGUAGE_CODES.indices) {
|
||||||
|
LANGUAGE_CODES[languageIndex]
|
||||||
|
} else {
|
||||||
|
"system"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (langCode == "system") {
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
val locale = when {
|
||||||
|
langCode.contains("-") -> {
|
||||||
|
val parts = langCode.split("-")
|
||||||
|
Locale.Builder().setLanguage(parts[0]).setRegion(parts[1]).build()
|
||||||
|
}
|
||||||
|
else -> Locale.Builder().setLanguage(langCode).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
Locale.setDefault(locale)
|
||||||
|
|
||||||
|
val config = Configuration(context.resources.configuration)
|
||||||
|
config.setLocales(LocaleList(locale))
|
||||||
|
|
||||||
|
return context.createConfigurationContext(config)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,10 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||||||
mainHandler.postDelayed(romSwapStopTimeoutRunnable, ROM_SWAP_STOP_TIMEOUT_MS)
|
mainHandler.postDelayed(romSwapStopTimeoutRunnable, ROM_SWAP_STOP_TIMEOUT_MS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun attachBaseContext(base: Context) {
|
||||||
|
super.attachBaseContext(YuzuApplication.applyLanguage(base))
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
Log.gameLaunched = true
|
Log.gameLaunched = true
|
||||||
ThemeHelper.setTheme(this)
|
ThemeHelper.setTheme(this)
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
|
|||||||
THEME("theme"),
|
THEME("theme"),
|
||||||
THEME_MODE("theme_mode"),
|
THEME_MODE("theme_mode"),
|
||||||
STATIC_THEME_COLOR("static_theme_color"),
|
STATIC_THEME_COLOR("static_theme_color"),
|
||||||
|
APP_LANGUAGE("app_language"),
|
||||||
OVERLAY_SCALE("control_scale"),
|
OVERLAY_SCALE("control_scale"),
|
||||||
OVERLAY_OPACITY("control_opacity"),
|
OVERLAY_OPACITY("control_opacity"),
|
||||||
LOCK_DRAWER("lock_drawer"),
|
LOCK_DRAWER("lock_drawer"),
|
||||||
|
|||||||
+9
@@ -997,6 +997,15 @@ abstract class SettingsItem(
|
|||||||
descriptionId = R.string.enable_qlaunch_button_description,
|
descriptionId = R.string.enable_qlaunch_button_description,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
put(
|
||||||
|
SingleChoiceSetting(
|
||||||
|
IntSetting.APP_LANGUAGE,
|
||||||
|
titleId = R.string.app_language,
|
||||||
|
descriptionId = R.string.app_language_description,
|
||||||
|
choicesId = R.array.appLanguageNames,
|
||||||
|
valuesId = R.array.appLanguageValues
|
||||||
|
)
|
||||||
|
)
|
||||||
put(
|
put(
|
||||||
SwitchSetting(
|
SwitchSetting(
|
||||||
BooleanSetting.RENDERER_DEBUG,
|
BooleanSetting.RENDERER_DEBUG,
|
||||||
|
|||||||
+17
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.ui
|
package org.yuzu.yuzu_emu.features.settings.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup.MarginLayoutParams
|
import android.view.ViewGroup.MarginLayoutParams
|
||||||
@@ -27,6 +29,7 @@ import org.yuzu.yuzu_emu.features.input.NativeInput
|
|||||||
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
||||||
import org.yuzu.yuzu_emu.fragments.ResetSettingsDialogFragment
|
import org.yuzu.yuzu_emu.fragments.ResetSettingsDialogFragment
|
||||||
import org.yuzu.yuzu_emu.utils.*
|
import org.yuzu.yuzu_emu.utils.*
|
||||||
|
import org.yuzu.yuzu_emu.utils.collect
|
||||||
|
|
||||||
class SettingsActivity : AppCompatActivity() {
|
class SettingsActivity : AppCompatActivity() {
|
||||||
private lateinit var binding: ActivitySettingsBinding
|
private lateinit var binding: ActivitySettingsBinding
|
||||||
@@ -35,6 +38,10 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private val settingsViewModel: SettingsViewModel by viewModels()
|
private val settingsViewModel: SettingsViewModel by viewModels()
|
||||||
|
|
||||||
|
override fun attachBaseContext(base: Context) {
|
||||||
|
super.attachBaseContext(YuzuApplication.applyLanguage(base))
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
ThemeHelper.setTheme(this)
|
ThemeHelper.setTheme(this)
|
||||||
|
|
||||||
@@ -141,6 +148,16 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
NativeConfig.savePerGameConfig()
|
NativeConfig.savePerGameConfig()
|
||||||
NativeConfig.unloadPerGameConfig()
|
NativeConfig.unloadPerGameConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settingsViewModel.shouldRecreateForLanguageChange.value) {
|
||||||
|
settingsViewModel.setShouldRecreateForLanguageChange(false)
|
||||||
|
val relaunchIntent = packageManager?.getLaunchIntentForPackage(packageName)
|
||||||
|
if (relaunchIntent != null) {
|
||||||
|
relaunchIntent.addFlags(android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK or android.content.Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
startActivity(relaunchIntent)
|
||||||
|
android.os.Process.killProcess(android.os.Process.myPid())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
@@ -482,6 +482,14 @@ class SettingsAdapter(
|
|||||||
position
|
position
|
||||||
).show(fragment.childFragmentManager, SettingsDialogFragment.TAG)
|
).show(fragment.childFragmentManager, SettingsDialogFragment.TAG)
|
||||||
|
|
||||||
|
// reset language if detected
|
||||||
|
if (item.setting.key == "app_language") {
|
||||||
|
// recreate page apply language change instantly
|
||||||
|
fragment.requireActivity().recreate()
|
||||||
|
|
||||||
|
settingsViewModel.setShouldRecreateForLanguageChange(true)
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
@@ -387,6 +387,12 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
|
|||||||
) {
|
) {
|
||||||
settingsViewModel.setShouldReloadSettingsList(true)
|
settingsViewModel.setShouldReloadSettingsList(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scSetting.setting.key == "app_language") {
|
||||||
|
settingsViewModel.setShouldRecreateForLanguageChange(true)
|
||||||
|
// recreate page apply language change instantly
|
||||||
|
requireActivity().recreate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is StringSingleChoiceSetting -> {
|
is StringSingleChoiceSetting -> {
|
||||||
|
|||||||
+3
-1
@@ -1345,8 +1345,10 @@ class SettingsFragmentPresenter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add(HeaderSetting(R.string.app_settings))
|
||||||
|
add(IntSetting.APP_LANGUAGE.key)
|
||||||
|
|
||||||
if (NativeLibrary.isUpdateCheckerEnabled()) {
|
if (NativeLibrary.isUpdateCheckerEnabled()) {
|
||||||
add(HeaderSetting(R.string.app_settings))
|
|
||||||
add(BooleanSetting.ENABLE_UPDATE_CHECKS.key)
|
add(BooleanSetting.ENABLE_UPDATE_CHECKS.key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
@@ -44,6 +44,10 @@ class SettingsSubscreenActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private val args by navArgs<SettingsSubscreenActivityArgs>()
|
private val args by navArgs<SettingsSubscreenActivityArgs>()
|
||||||
|
|
||||||
|
override fun attachBaseContext(base: Context) {
|
||||||
|
super.attachBaseContext(YuzuApplication.applyLanguage(base))
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
ThemeHelper.setTheme(this)
|
ThemeHelper.setTheme(this)
|
||||||
|
|
||||||
|
|||||||
+8
-1
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
@@ -57,6 +57,9 @@ class SettingsViewModel : ViewModel() {
|
|||||||
private val _shouldShowResetInputDialog = MutableStateFlow(false)
|
private val _shouldShowResetInputDialog = MutableStateFlow(false)
|
||||||
val shouldShowResetInputDialog = _shouldShowResetInputDialog.asStateFlow()
|
val shouldShowResetInputDialog = _shouldShowResetInputDialog.asStateFlow()
|
||||||
|
|
||||||
|
private val _shouldRecreateForLanguageChange = MutableStateFlow(false)
|
||||||
|
val shouldRecreateForLanguageChange = _shouldRecreateForLanguageChange.asStateFlow()
|
||||||
|
|
||||||
private val _shouldShowPathPicker = MutableStateFlow(false)
|
private val _shouldShowPathPicker = MutableStateFlow(false)
|
||||||
val shouldShowPathPicker = _shouldShowPathPicker.asStateFlow()
|
val shouldShowPathPicker = _shouldShowPathPicker.asStateFlow()
|
||||||
|
|
||||||
@@ -115,6 +118,10 @@ class SettingsViewModel : ViewModel() {
|
|||||||
_shouldShowResetInputDialog.value = value
|
_shouldShowResetInputDialog.value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setShouldRecreateForLanguageChange(value: Boolean) {
|
||||||
|
_shouldRecreateForLanguageChange.value = value
|
||||||
|
}
|
||||||
|
|
||||||
fun setShouldShowPathPicker(value: Boolean) {
|
fun setShouldShowPathPicker(value: Boolean) {
|
||||||
_shouldShowPathPicker.value = value
|
_shouldShowPathPicker.value = value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
package org.yuzu.yuzu_emu.ui.main
|
package org.yuzu.yuzu_emu.ui.main
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -70,6 +71,10 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
private val CHECKED_DECRYPTION = "CheckedDecryption"
|
private val CHECKED_DECRYPTION = "CheckedDecryption"
|
||||||
private var checkedDecryption = false
|
private var checkedDecryption = false
|
||||||
|
|
||||||
|
override fun attachBaseContext(base: Context) {
|
||||||
|
super.attachBaseContext(YuzuApplication.applyLanguage(base))
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
val splashScreen = installSplashScreen()
|
val splashScreen = installSplashScreen()
|
||||||
splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }
|
splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ namespace AndroidSettings {
|
|||||||
Settings::Setting<s32> static_theme_color{linkage, 0, "static_theme_color", Settings::Category::Android};
|
Settings::Setting<s32> static_theme_color{linkage, 0, "static_theme_color", Settings::Category::Android};
|
||||||
Settings::Setting<bool> black_backgrounds{linkage, false, "black_backgrounds",
|
Settings::Setting<bool> black_backgrounds{linkage, false, "black_backgrounds",
|
||||||
Settings::Category::Android};
|
Settings::Category::Android};
|
||||||
|
Settings::Setting<s32> app_language{linkage, 0, "app_language", Settings::Category::Android};
|
||||||
Settings::Setting<bool> enable_update_checks{linkage, true, "enable_update_checks",
|
Settings::Setting<bool> enable_update_checks{linkage, true, "enable_update_checks",
|
||||||
Settings::Category::Android};
|
Settings::Category::Android};
|
||||||
Settings::Setting<bool> enable_folder_button{linkage, true, "enable_folder_button",
|
Settings::Setting<bool> enable_folder_button{linkage, true, "enable_folder_button",
|
||||||
|
|||||||
@@ -409,6 +409,62 @@
|
|||||||
<item>2</item>
|
<item>2</item>
|
||||||
</integer-array>
|
</integer-array>
|
||||||
|
|
||||||
|
<string-array name="appLanguageNames">
|
||||||
|
<item>@string/app_language_system</item>
|
||||||
|
<item>@string/app_language_english</item>
|
||||||
|
<item>@string/app_language_spanish</item>
|
||||||
|
<item>@string/app_language_french</item>
|
||||||
|
<item>@string/app_language_german</item>
|
||||||
|
<item>@string/app_language_italian</item>
|
||||||
|
<item>@string/app_language_portuguese</item>
|
||||||
|
<item>@string/app_language_brazilian_portuguese</item>
|
||||||
|
<item>@string/app_language_russian</item>
|
||||||
|
<item>@string/app_language_japanese</item>
|
||||||
|
<item>@string/app_language_korean</item>
|
||||||
|
<item>@string/app_language_simplified_chinese</item>
|
||||||
|
<item>@string/app_language_traditional_chinese</item>
|
||||||
|
<item>@string/app_language_polish</item>
|
||||||
|
<item>@string/app_language_czech</item>
|
||||||
|
<item>@string/app_language_norwegian</item>
|
||||||
|
<item>@string/app_language_hungarian</item>
|
||||||
|
<item>@string/app_language_ukrainian</item>
|
||||||
|
<item>@string/app_language_vietnamese</item>
|
||||||
|
<item>@string/app_language_indonesian</item>
|
||||||
|
<item>@string/app_language_arabic</item>
|
||||||
|
<item>@string/app_language_central_kurdish</item>
|
||||||
|
<item>@string/app_language_persian</item>
|
||||||
|
<item>@string/app_language_hebrew</item>
|
||||||
|
<item>@string/app_language_serbian</item>
|
||||||
|
<item>@string/app_language_thai</item>
|
||||||
|
</string-array>
|
||||||
|
<integer-array name="appLanguageValues">
|
||||||
|
<item>0</item>
|
||||||
|
<item>1</item>
|
||||||
|
<item>2</item>
|
||||||
|
<item>3</item>
|
||||||
|
<item>4</item>
|
||||||
|
<item>5</item>
|
||||||
|
<item>6</item>
|
||||||
|
<item>7</item>
|
||||||
|
<item>8</item>
|
||||||
|
<item>9</item>
|
||||||
|
<item>10</item>
|
||||||
|
<item>11</item>
|
||||||
|
<item>12</item>
|
||||||
|
<item>13</item>
|
||||||
|
<item>14</item>
|
||||||
|
<item>15</item>
|
||||||
|
<item>16</item>
|
||||||
|
<item>17</item>
|
||||||
|
<item>18</item>
|
||||||
|
<item>19</item>
|
||||||
|
<item>20</item>
|
||||||
|
<item>21</item>
|
||||||
|
<item>22</item>
|
||||||
|
<item>23</item>
|
||||||
|
<item>24</item>
|
||||||
|
</integer-array>
|
||||||
|
|
||||||
<string-array name="outputEngineEntries">
|
<string-array name="outputEngineEntries">
|
||||||
<item>@string/auto</item>
|
<item>@string/auto</item>
|
||||||
<item>@string/sdl3</item>
|
<item>@string/sdl3</item>
|
||||||
|
|||||||
@@ -1281,6 +1281,36 @@
|
|||||||
<string name="enable_qlaunch_button">QLaunch</string>
|
<string name="enable_qlaunch_button">QLaunch</string>
|
||||||
<string name="enable_qlaunch_button_description">Show the button to launch QLaunch</string>
|
<string name="enable_qlaunch_button_description">Show the button to launch QLaunch</string>
|
||||||
|
|
||||||
|
<!-- App Language -->
|
||||||
|
<string name="app_language">App Language</string>
|
||||||
|
<string name="app_language_description">Change the language of the app interface</string>
|
||||||
|
<string name="app_language_system">Follow System</string>
|
||||||
|
<string name="app_language_english" translatable="false">English</string>
|
||||||
|
<string name="app_language_spanish" translatable="false">Español</string>
|
||||||
|
<string name="app_language_french" translatable="false">Français</string>
|
||||||
|
<string name="app_language_german" translatable="false">Deutsch</string>
|
||||||
|
<string name="app_language_italian" translatable="false">Italiano</string>
|
||||||
|
<string name="app_language_portuguese" translatable="false">Português</string>
|
||||||
|
<string name="app_language_brazilian_portuguese" translatable="false">Português do Brasil</string>
|
||||||
|
<string name="app_language_russian" translatable="false">Русский</string>
|
||||||
|
<string name="app_language_japanese" translatable="false">日本語</string>
|
||||||
|
<string name="app_language_korean" translatable="false">한국어</string>
|
||||||
|
<string name="app_language_simplified_chinese" translatable="false">简体中文</string>
|
||||||
|
<string name="app_language_traditional_chinese" translatable="false">繁體中文</string>
|
||||||
|
<string name="app_language_polish" translatable="false">Polski</string>
|
||||||
|
<string name="app_language_czech" translatable="false">Čeština</string>
|
||||||
|
<string name="app_language_norwegian" translatable="false">Norsk bokmål</string>
|
||||||
|
<string name="app_language_hungarian" translatable="false">Magyar</string>
|
||||||
|
<string name="app_language_ukrainian" translatable="false">Українська</string>
|
||||||
|
<string name="app_language_vietnamese" translatable="false">Tiếng Việt</string>
|
||||||
|
<string name="app_language_indonesian" translatable="false">Bahasa Indonesia</string>
|
||||||
|
<string name="app_language_arabic" translatable="false">العربية</string>
|
||||||
|
<string name="app_language_central_kurdish" translatable="false">کوردیی ناوەندی</string>
|
||||||
|
<string name="app_language_persian" translatable="false">فارسی</string>
|
||||||
|
<string name="app_language_hebrew" translatable="false">עברית</string>
|
||||||
|
<string name="app_language_serbian" translatable="false">Српски</string>
|
||||||
|
<string name="app_language_thai" translatable="false">แบบไทย</string>
|
||||||
|
|
||||||
<!-- Static Themes -->
|
<!-- Static Themes -->
|
||||||
<string name="static_theme_color">Theme Color</string>
|
<string name="static_theme_color">Theme Color</string>
|
||||||
<string name="eden_theme">Eden</string>
|
<string name="eden_theme">Eden</string>
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ add_library(
|
|||||||
logging.h
|
logging.h
|
||||||
lz4_compression.cpp
|
lz4_compression.cpp
|
||||||
lz4_compression.h
|
lz4_compression.h
|
||||||
make_unique_for_overwrite.h
|
|
||||||
math_util.h
|
math_util.h
|
||||||
memory_detect.cpp
|
memory_detect.cpp
|
||||||
memory_detect.h
|
memory_detect.h
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace Common {
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
requires(!std::is_array_v<T>)
|
|
||||||
std::unique_ptr<T> make_unique_for_overwrite() {
|
|
||||||
return std::unique_ptr<T>(new T);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
requires std::is_unbounded_array_v<T>
|
|
||||||
std::unique_ptr<T> make_unique_for_overwrite(std::size_t n) {
|
|
||||||
return std::unique_ptr<T>(new std::remove_extent_t<T>[n]);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class... Args>
|
|
||||||
requires std::is_bounded_array_v<T>
|
|
||||||
void make_unique_for_overwrite(Args&&...) = delete;
|
|
||||||
|
|
||||||
} // namespace Common
|
|
||||||
@@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
#include "common/make_unique_for_overwrite.h"
|
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
@@ -38,8 +37,9 @@ public:
|
|||||||
ScratchBuffer() = default;
|
ScratchBuffer() = default;
|
||||||
|
|
||||||
explicit ScratchBuffer(size_type initial_capacity)
|
explicit ScratchBuffer(size_type initial_capacity)
|
||||||
: last_requested_size{initial_capacity}, buffer_capacity{initial_capacity},
|
: last_requested_size{initial_capacity}
|
||||||
buffer{Common::make_unique_for_overwrite<T[]>(initial_capacity)} {}
|
, buffer_capacity{initial_capacity}
|
||||||
|
, buffer{std::make_unique_for_overwrite<T[]>(initial_capacity)} {}
|
||||||
|
|
||||||
~ScratchBuffer() = default;
|
~ScratchBuffer() = default;
|
||||||
ScratchBuffer(const ScratchBuffer&) = delete;
|
ScratchBuffer(const ScratchBuffer&) = delete;
|
||||||
@@ -64,7 +64,7 @@ public:
|
|||||||
/// The previously held data will remain intact.
|
/// The previously held data will remain intact.
|
||||||
void resize(size_type size) {
|
void resize(size_type size) {
|
||||||
if (size > buffer_capacity) {
|
if (size > buffer_capacity) {
|
||||||
auto new_buffer = Common::make_unique_for_overwrite<T[]>(size);
|
auto new_buffer = std::make_unique_for_overwrite<T[]>(size);
|
||||||
std::memcpy(new_buffer.get(), buffer.get(), buffer_capacity * sizeof(T));
|
std::memcpy(new_buffer.get(), buffer.get(), buffer_capacity * sizeof(T));
|
||||||
buffer = std::move(new_buffer);
|
buffer = std::move(new_buffer);
|
||||||
buffer_capacity = size;
|
buffer_capacity = size;
|
||||||
@@ -77,7 +77,7 @@ public:
|
|||||||
void resize_destructive(size_type size) {
|
void resize_destructive(size_type size) {
|
||||||
if (size > buffer_capacity) {
|
if (size > buffer_capacity) {
|
||||||
buffer_capacity = size;
|
buffer_capacity = size;
|
||||||
buffer = Common::make_unique_for_overwrite<T[]>(buffer_capacity);
|
buffer = std::make_unique_for_overwrite<T[]>(buffer_capacity);
|
||||||
}
|
}
|
||||||
last_requested_size = size;
|
last_requested_size = size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,8 +109,7 @@ VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::op
|
|||||||
auto reference = std::make_unique<FileReference>();
|
auto reference = std::make_unique<FileReference>();
|
||||||
this->InsertReferenceIntoListLocked(*reference);
|
this->InsertReferenceIntoListLocked(*reference);
|
||||||
|
|
||||||
auto file = std::shared_ptr<RealVfsFile>(
|
auto file = std::make_shared<RealVfsFile>(*this, std::move(reference), path, perms, size, std::move(parent_path));
|
||||||
new RealVfsFile(*this, std::move(reference), path, perms, size, std::move(parent_path)));
|
|
||||||
cache[path] = file;
|
cache[path] = file;
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
@@ -177,7 +176,7 @@ bool RealVfsFilesystem::DeleteFile(std::string_view path_) {
|
|||||||
|
|
||||||
VirtualDir RealVfsFilesystem::OpenDirectory(std::string_view path_, OpenMode perms) {
|
VirtualDir RealVfsFilesystem::OpenDirectory(std::string_view path_, OpenMode perms) {
|
||||||
const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
|
const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
|
||||||
return std::shared_ptr<RealVfsDirectory>(new RealVfsDirectory(*this, path, perms));
|
return std::make_shared<RealVfsDirectory>(*this, path, perms);
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualDir RealVfsFilesystem::CreateDirectory(std::string_view path_, OpenMode perms) {
|
VirtualDir RealVfsFilesystem::CreateDirectory(std::string_view path_, OpenMode perms) {
|
||||||
@@ -185,7 +184,7 @@ VirtualDir RealVfsFilesystem::CreateDirectory(std::string_view path_, OpenMode p
|
|||||||
if (!FS::CreateDirs(path)) {
|
if (!FS::CreateDirs(path)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return std::shared_ptr<RealVfsDirectory>(new RealVfsDirectory(*this, path, perms));
|
return std::make_shared<RealVfsDirectory>(*this, path, perms);
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualDir RealVfsFilesystem::CopyDirectory(std::string_view old_path_,
|
VirtualDir RealVfsFilesystem::CopyDirectory(std::string_view old_path_,
|
||||||
|
|||||||
@@ -82,6 +82,9 @@ class RealVfsFile : public VfsFile {
|
|||||||
friend class RealVfsFilesystem;
|
friend class RealVfsFilesystem;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference,
|
||||||
|
const std::string& path, OpenMode perms = OpenMode::Read,
|
||||||
|
std::optional<u64> size = {}, std::optional<std::string> parent_path = {});
|
||||||
~RealVfsFile() override;
|
~RealVfsFile() override;
|
||||||
|
|
||||||
std::string GetName() const override;
|
std::string GetName() const override;
|
||||||
@@ -95,9 +98,6 @@ public:
|
|||||||
bool Rename(std::string_view name) override;
|
bool Rename(std::string_view name) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference,
|
|
||||||
const std::string& path, OpenMode perms = OpenMode::Read,
|
|
||||||
std::optional<u64> size = {}, std::optional<std::string> parent_path = {});
|
|
||||||
|
|
||||||
RealVfsFilesystem& base;
|
RealVfsFilesystem& base;
|
||||||
std::unique_ptr<FileReference> reference;
|
std::unique_ptr<FileReference> reference;
|
||||||
@@ -113,6 +113,8 @@ class RealVfsDirectory : public VfsDirectory {
|
|||||||
friend class RealVfsFilesystem;
|
friend class RealVfsFilesystem;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
RealVfsDirectory(RealVfsFilesystem& base, const std::string& path,
|
||||||
|
OpenMode perms = OpenMode::Read);
|
||||||
~RealVfsDirectory() override;
|
~RealVfsDirectory() override;
|
||||||
|
|
||||||
VirtualFile GetFileRelative(std::string_view relative_path) const override;
|
VirtualFile GetFileRelative(std::string_view relative_path) const override;
|
||||||
@@ -138,9 +140,6 @@ public:
|
|||||||
std::map<std::string, VfsEntryType, std::less<>> GetEntries() const override;
|
std::map<std::string, VfsEntryType, std::less<>> GetEntries() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RealVfsDirectory(RealVfsFilesystem& base, const std::string& path,
|
|
||||||
OpenMode perms = OpenMode::Read);
|
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T, typename R>
|
||||||
std::vector<std::shared_ptr<R>> IterateEntries() const;
|
std::vector<std::shared_ptr<R>> IterateEntries() const;
|
||||||
|
|
||||||
|
|||||||
@@ -517,7 +517,7 @@ void WindowSystem::UpdateAppletStateLocked(Applet* applet, bool is_foreground, b
|
|||||||
// Layer ordering. Composition sorts back-to-front. Now with enums for calrity.
|
// Layer ordering. Composition sorts back-to-front. Now with enums for calrity.
|
||||||
s32 z_index = Background;
|
s32 z_index = Background;
|
||||||
if (is_overlay) {
|
if (is_overlay) {
|
||||||
z_index = Overlay;
|
z_index = this->IsOverlayOpenLocked(*applet) ? Overlay : Background;
|
||||||
} else if (inherited_foreground) {
|
} else if (inherited_foreground) {
|
||||||
z_index = is_obscured ? Foreground : ForegroundVisible;
|
z_index = is_obscured ? Foreground : ForegroundVisible;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
@@ -24,7 +24,7 @@ IReceiverService::~IReceiverService() = default;
|
|||||||
|
|
||||||
Result IReceiverService::OpenReceiver(Out<SharedPointer<IReceiver>> out_receiver) {
|
Result IReceiverService::OpenReceiver(Out<SharedPointer<IReceiver>> out_receiver) {
|
||||||
LOG_DEBUG(Service_PSC, "called");
|
LOG_DEBUG(Service_PSC, "called");
|
||||||
*out_receiver = std::shared_ptr<IReceiver>(new IReceiver(system));
|
*out_receiver = std::make_shared<IReceiver>(system);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -761,9 +761,6 @@ void EmulatedController::StartMotionCalibration() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index, Common::UUID uuid) {
|
void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index, Common::UUID uuid) {
|
||||||
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
|
|
||||||
const auto& player = Settings::values.players.GetValue()[player_index];
|
|
||||||
|
|
||||||
if (index >= controller.button_values.size()) {
|
if (index >= controller.button_values.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -916,21 +913,10 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_connected) {
|
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
|
||||||
if (npad_type == NpadStyleIndex::Handheld) {
|
const auto& player = Settings::values.players.GetValue()[player_index];
|
||||||
if (npad_id_type == NpadIdType::Handheld) {
|
if (player.connected) {
|
||||||
Connect();
|
Connect();
|
||||||
controller_connected[player_index] = true;
|
|
||||||
}
|
|
||||||
} else if (npad_type != NpadStyleIndex::Handheld) {
|
|
||||||
if (npad_id_type == NpadIdType::Player1) {
|
|
||||||
Connect();
|
|
||||||
controller_connected[player_index] = true;
|
|
||||||
} else if (player.connected && !controller_connected[player_index]) {
|
|
||||||
Connect();
|
|
||||||
controller_connected[player_index] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TriggerOnChange(ControllerTriggerType::Button, true);
|
TriggerOnChange(ControllerTriggerType::Button, true);
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/vector_math.h"
|
#include "common/vector_math.h"
|
||||||
#include "hid_core/frontend/motion_input.h"
|
#include "hid_core/frontend/motion_input.h"
|
||||||
#include "hid_core/hid_core.h"
|
|
||||||
#include "hid_core/hid_types.h"
|
#include "hid_core/hid_types.h"
|
||||||
#include "hid_core/irsensor/irs_types.h"
|
#include "hid_core/irsensor/irs_types.h"
|
||||||
|
|
||||||
@@ -585,7 +584,6 @@ private:
|
|||||||
std::array<VibrationValue, 2> last_vibration_value{DEFAULT_VIBRATION_VALUE,
|
std::array<VibrationValue, 2> last_vibration_value{DEFAULT_VIBRATION_VALUE,
|
||||||
DEFAULT_VIBRATION_VALUE};
|
DEFAULT_VIBRATION_VALUE};
|
||||||
std::array<std::chrono::steady_clock::time_point, 2> last_vibration_timepoint{};
|
std::array<std::chrono::steady_clock::time_point, 2> last_vibration_timepoint{};
|
||||||
std::array<bool, HIDCore::available_controllers> controller_connected{};
|
|
||||||
|
|
||||||
// Atomically synched values
|
// Atomically synched values
|
||||||
std::atomic<HID::NpadStyleIndex> npad_type{HID::NpadStyleIndex::None};
|
std::atomic<HID::NpadStyleIndex> npad_type{HID::NpadStyleIndex::None};
|
||||||
|
|||||||
@@ -45,6 +45,19 @@ NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service
|
|||||||
AbstractPad{hid_core_.kernel},
|
AbstractPad{hid_core_.kernel},
|
||||||
}}
|
}}
|
||||||
{
|
{
|
||||||
|
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) {
|
||||||
|
for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) {
|
||||||
|
auto& controller = controller_data[aruid_index][i];
|
||||||
|
controller.device = hid_core.GetEmulatedControllerByIndex(i);
|
||||||
|
Core::HID::ControllerUpdateCallback engine_callback{
|
||||||
|
.on_change = [this, i, kernel = &hid_core.kernel](Core::HID::ControllerTriggerType type) {
|
||||||
|
ControllerUpdate(*kernel, type, i);
|
||||||
|
},
|
||||||
|
.is_npad_service = true,
|
||||||
|
};
|
||||||
|
controller.callback_key = controller.device->SetCallback(engine_callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (std::size_t i = 0; i < abstracted_pads.size(); ++i) {
|
for (std::size_t i = 0; i < abstracted_pads.size(); ++i) {
|
||||||
abstracted_pads[i].SetNpadId(IndexToNpadIdType(i));
|
abstracted_pads[i].SetNpadId(IndexToNpadIdType(i));
|
||||||
}
|
}
|
||||||
@@ -93,16 +106,6 @@ Result NPad::Activate(u64 aruid) {
|
|||||||
for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) {
|
for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) {
|
||||||
auto& controller = controller_data[aruid_index][i];
|
auto& controller = controller_data[aruid_index][i];
|
||||||
controller.shared_memory = &data->shared_memory_format->npad.npad_entry[i].internal_state;
|
controller.shared_memory = &data->shared_memory_format->npad.npad_entry[i].internal_state;
|
||||||
controller.device = hid_core.GetEmulatedControllerByIndex(i);
|
|
||||||
if (!controller.callback_key) {
|
|
||||||
Core::HID::ControllerUpdateCallback engine_callback{
|
|
||||||
.on_change = [this, i](Core::HID::ControllerTriggerType type) {
|
|
||||||
ControllerUpdate(hid_core.kernel, type, i);
|
|
||||||
},
|
|
||||||
.is_npad_service = true,
|
|
||||||
};
|
|
||||||
controller.callback_key = controller.device->SetCallback(engine_callback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefill controller buffers
|
// Prefill controller buffers
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ void BufferCache<P>::UnmapGPUMemory(size_t as_id, GPUVAddr gpu_addr, size_t size
|
|||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
void BufferCache<P>::WriteMemory(DAddr device_addr, u64 size) {
|
void BufferCache<P>::WriteMemory(DAddr device_addr, u64 size) {
|
||||||
if (memory_tracker.IsRegionGpuModified(device_addr, size)) {
|
if (IsRegionGpuModified(device_addr, size)) {
|
||||||
ClearDownload(device_addr, size);
|
ClearDownload(device_addr, size);
|
||||||
gpu_modified_ranges.Subtract(device_addr, size);
|
gpu_modified_ranges.Subtract(device_addr, size);
|
||||||
}
|
}
|
||||||
@@ -311,11 +311,8 @@ std::pair<typename P::Buffer*, u32> BufferCache<P>::ObtainCPUBuffer(
|
|||||||
MarkWrittenBuffer(buffer_id, device_addr, size);
|
MarkWrittenBuffer(buffer_id, device_addr, size);
|
||||||
break;
|
break;
|
||||||
case ObtainBufferOperation::DiscardWrite: {
|
case ObtainBufferOperation::DiscardWrite: {
|
||||||
const DAddr device_addr_start = Common::AlignDown(device_addr, 64);
|
ClearDownload(device_addr, size);
|
||||||
const DAddr device_addr_end = Common::AlignUp(device_addr + size, 64);
|
gpu_modified_ranges.Subtract(device_addr, size);
|
||||||
const size_t new_size = device_addr_end - device_addr_start;
|
|
||||||
ClearDownload(device_addr_start, new_size);
|
|
||||||
gpu_modified_ranges.Subtract(device_addr_start, new_size);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -1742,14 +1739,24 @@ bool BufferCache<P>::SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 si
|
|||||||
u64 total_size_bytes = 0;
|
u64 total_size_bytes = 0;
|
||||||
u64 largest_copy = 0;
|
u64 largest_copy = 0;
|
||||||
const DAddr buffer_start = buffer.cpu_addr_cached;
|
const DAddr buffer_start = buffer.cpu_addr_cached;
|
||||||
memory_tracker.ForEachUploadRange(device_addr, size, [&](u64 device_addr_out, u64 range_size) {
|
const auto add_upload = [&](DAddr start, DAddr end) {
|
||||||
|
if (start == end) return;
|
||||||
|
const u64 range_size = end - start;
|
||||||
upload_copies.push_back(BufferCopy{
|
upload_copies.push_back(BufferCopy{
|
||||||
.src_offset = total_size_bytes,
|
.src_offset = total_size_bytes,
|
||||||
.dst_offset = device_addr_out - buffer_start,
|
.dst_offset = start - buffer_start,
|
||||||
.size = range_size,
|
.size = range_size,
|
||||||
});
|
});
|
||||||
total_size_bytes += range_size;
|
total_size_bytes += range_size;
|
||||||
largest_copy = (std::max)(largest_copy, range_size);
|
largest_copy = (std::max)(largest_copy, range_size);
|
||||||
|
};
|
||||||
|
memory_tracker.ForEachUploadRange(device_addr, size, [&](u64 device_addr_out, u64 range_size) {
|
||||||
|
DAddr upload_start = device_addr_out;
|
||||||
|
gpu_modified_ranges.ForEachInRange(device_addr_out, range_size, [&](DAddr gpu_start, DAddr gpu_end) {
|
||||||
|
add_upload(upload_start, gpu_start);
|
||||||
|
upload_start = gpu_end;
|
||||||
|
});
|
||||||
|
add_upload(upload_start, device_addr_out + range_size);
|
||||||
});
|
});
|
||||||
if (total_size_bytes == 0) {
|
if (total_size_bytes == 0) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
namespace Tegra {
|
namespace Tegra {
|
||||||
|
|
||||||
constexpr u32 MacroRegistersStart = 0xE00;
|
constexpr u32 MacroRegistersStart = 0xE00;
|
||||||
[[maybe_unused]] constexpr u32 ComputeInline = 0x6D;
|
constexpr u32 ComputeInline = 0x6D;
|
||||||
|
|
||||||
DmaPusher::DmaPusher(Core::System& system_, MemoryManager& memory_manager_, Control::ChannelState& channel_state_)
|
DmaPusher::DmaPusher(Core::System& system_, MemoryManager& memory_manager_, Control::ChannelState& channel_state_)
|
||||||
: system{system_}
|
: system{system_}
|
||||||
@@ -73,11 +73,16 @@ bool DmaPusher::Step() {
|
|||||||
synced = false;
|
synced = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header.size > 0 && dma_state.method >= MacroRegistersStart && subchannels[dma_state.subchannel]) {
|
|
||||||
subchannels[dma_state.subchannel]->current_dirty = memory_manager.IsMemoryDirty(dma_state.dma_get, header.size * sizeof(u32));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (header.size > 0) {
|
if (header.size > 0) {
|
||||||
|
if (subchannels[dma_state.subchannel] && dma_state.method_count) {
|
||||||
|
const auto engine = subchannel_type[dma_state.subchannel];
|
||||||
|
const bool kepler_payload = engine == Engines::EngineTypes::KeplerCompute && dma_state.method == ComputeInline && dma_state.non_incrementing;
|
||||||
|
const bool macro_payload = engine == Engines::EngineTypes::Maxwell3D && dma_state.method >= MacroRegistersStart;
|
||||||
|
if (kepler_payload || macro_payload) {
|
||||||
|
const size_t words = std::min<size_t>(dma_state.method_count, header.size);
|
||||||
|
subchannels[dma_state.subchannel]->current_dirty = memory_manager.IsMemoryDirty(dma_state.dma_get, words * sizeof(u32));
|
||||||
|
}
|
||||||
|
}
|
||||||
const bool use_safe = Settings::IsDMALevelDefault() ? Settings::IsGPULevelHigh() : Settings::IsDMALevelSafe();
|
const bool use_safe = Settings::IsDMALevelDefault() ? Settings::IsGPULevelHigh() : Settings::IsDMALevelSafe();
|
||||||
if (use_safe) {
|
if (use_safe) {
|
||||||
Tegra::Memory::GpuGuestMemory<Tegra::CommandHeader, Tegra::Memory::GuestMemoryFlags::SafeRead>headers(memory_manager, dma_state.dma_get, header.size, &command_headers);
|
Tegra::Memory::GpuGuestMemory<Tegra::CommandHeader, Tegra::Memory::GuestMemoryFlags::SafeRead>headers(memory_manager, dma_state.dma_get, header.size, &command_headers);
|
||||||
|
|||||||
@@ -49,13 +49,16 @@ void KeplerCompute::CallMethod(Core::System& system, u32 method, u32 method_argu
|
|||||||
case KEPLER_COMPUTE_REG_INDEX(exec_upload): {
|
case KEPLER_COMPUTE_REG_INDEX(exec_upload): {
|
||||||
UploadInfo info{.upload_address = upload_address,
|
UploadInfo info{.upload_address = upload_address,
|
||||||
.exec_address = upload_state.ExecTargetAddress(),
|
.exec_address = upload_state.ExecTargetAddress(),
|
||||||
.copy_size = upload_state.GetUploadSize()};
|
.copy_size = upload_state.GetUploadSize(),
|
||||||
|
.was_dirty = upload_dirty};
|
||||||
uploads.push_back(info);
|
uploads.push_back(info);
|
||||||
upload_state.ProcessExec(regs.exec_upload.linear != 0);
|
upload_state.ProcessExec(regs.exec_upload.linear != 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case KEPLER_COMPUTE_REG_INDEX(data_upload): {
|
case KEPLER_COMPUTE_REG_INDEX(data_upload): {
|
||||||
upload_address = current_dma_segment;
|
upload_address = current_dma_segment;
|
||||||
|
upload_dirty = current_dirty;
|
||||||
|
current_dirty = false;
|
||||||
upload_state.ProcessData(method_argument, is_last_call);
|
upload_state.ProcessData(method_argument, is_last_call);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -64,9 +67,11 @@ void KeplerCompute::CallMethod(Core::System& system, u32 method, u32 method_argu
|
|||||||
|
|
||||||
for (auto& data : uploads) {
|
for (auto& data : uploads) {
|
||||||
const GPUVAddr offset = data.exec_address - launch_desc_loc;
|
const GPUVAddr offset = data.exec_address - launch_desc_loc;
|
||||||
if (offset / sizeof(u32) == LAUNCH_REG_INDEX(grid_dim_x) &&
|
if (offset / sizeof(u32) == LAUNCH_REG_INDEX(grid_dim_x)) {
|
||||||
memory_manager.IsMemoryDirty(data.upload_address, data.copy_size)) {
|
const bool source_dirty = memory_manager.IsMemoryDirty(data.upload_address, data.copy_size);
|
||||||
indirect_compute = {data.upload_address};
|
if (data.was_dirty || source_dirty) {
|
||||||
|
indirect_compute = {data.upload_address};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uploads.clear();
|
uploads.clear();
|
||||||
@@ -83,6 +88,8 @@ void KeplerCompute::CallMultiMethod(Core::System& system, u32 method, const u32*
|
|||||||
switch (method) {
|
switch (method) {
|
||||||
case KEPLER_COMPUTE_REG_INDEX(data_upload):
|
case KEPLER_COMPUTE_REG_INDEX(data_upload):
|
||||||
upload_address = current_dma_segment;
|
upload_address = current_dma_segment;
|
||||||
|
upload_dirty = current_dirty;
|
||||||
|
current_dirty = false;
|
||||||
upload_state.ProcessData(base_start, amount);
|
upload_state.ProcessData(base_start, amount);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -226,11 +226,13 @@ private:
|
|||||||
VideoCore::RasterizerInterface* rasterizer = nullptr;
|
VideoCore::RasterizerInterface* rasterizer = nullptr;
|
||||||
Upload::State upload_state;
|
Upload::State upload_state;
|
||||||
GPUVAddr upload_address;
|
GPUVAddr upload_address;
|
||||||
|
bool upload_dirty{};
|
||||||
|
|
||||||
struct UploadInfo {
|
struct UploadInfo {
|
||||||
GPUVAddr upload_address;
|
GPUVAddr upload_address;
|
||||||
GPUVAddr exec_address;
|
GPUVAddr exec_address;
|
||||||
u32 copy_size;
|
u32 copy_size;
|
||||||
|
bool was_dirty;
|
||||||
};
|
};
|
||||||
std::vector<UploadInfo> uploads;
|
std::vector<UploadInfo> uploads;
|
||||||
std::optional<GPUVAddr> indirect_compute{};
|
std::optional<GPUVAddr> indirect_compute{};
|
||||||
|
|||||||
@@ -94,13 +94,13 @@ void Layer::ConfigureDraw(const Device& device, PresentPushConstants* out_push_c
|
|||||||
const u32 scaled_width = texture_info ? texture_info->scaled_width : texture_width;
|
const u32 scaled_width = texture_info ? texture_info->scaled_width : texture_width;
|
||||||
const u32 scaled_height = texture_info ? texture_info->scaled_height : texture_height;
|
const u32 scaled_height = texture_info ? texture_info->scaled_height : texture_height;
|
||||||
const bool use_accelerated = texture_info.has_value();
|
const bool use_accelerated = texture_info.has_value();
|
||||||
|
const bool is_applet =
|
||||||
|
(framebuffer.layer_stack_mask & Service::Nvnflinger::LayerStackBit(
|
||||||
|
Service::Nvnflinger::LayerStackId::Recording)) == 0;
|
||||||
|
|
||||||
RefreshResources(device, framebuffer);
|
RefreshResources(device, framebuffer);
|
||||||
SetAntiAliasPass(device);
|
SetAntiAliasPass(device);
|
||||||
#ifdef HAS_RESHADE
|
#ifdef HAS_RESHADE
|
||||||
const bool is_applet =
|
|
||||||
(framebuffer.layer_stack_mask & Service::Nvnflinger::LayerStackBit(
|
|
||||||
Service::Nvnflinger::LayerStackId::Recording)) == 0;
|
|
||||||
SetPostProcessPass(device, is_applet);
|
SetPostProcessPass(device, is_applet);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -141,8 +141,11 @@ void Layer::ConfigureDraw(const Device& device, PresentPushConstants* out_push_c
|
|||||||
source_image_view = fsr->Draw(device, scheduler, image_index, source_image, source_image_view, render_extent, crop_rect);
|
source_image_view = fsr->Draw(device, scheduler, image_index, source_image, source_image_view, render_extent, crop_rect);
|
||||||
crop_rect = {0, 0, 1, 1};
|
crop_rect = {0, 0, 1, 1};
|
||||||
} else if (auto* sgsr = std::get_if<SGSR>(&sr_filter)) {
|
} else if (auto* sgsr = std::get_if<SGSR>(&sr_filter)) {
|
||||||
source_image_view = sgsr->Draw(device, scheduler, image_index, source_image, source_image_view, render_extent, crop_rect);
|
if (!is_applet) {
|
||||||
crop_rect = {0, 0, 1, 1};
|
source_image_view = sgsr->Draw(device, scheduler, image_index, source_image,
|
||||||
|
source_image_view, render_extent, crop_rect);
|
||||||
|
crop_rect = {0, 0, 1, 1};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetMatrixData(device, *out_push_constants, layout);
|
SetMatrixData(device, *out_push_constants, layout);
|
||||||
|
|||||||
Reference in New Issue
Block a user