diff --git a/README.md b/README.md index bd923fa38..4b9b13897 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 3667. +This is the source code for early-access 3669. ## Legal Notice diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt index c5722a5a1..fa84f94f5 100755 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt @@ -26,13 +26,18 @@ enum class IntSetting( RENDERER_FORCE_MAX_CLOCK( "force_max_clock", Settings.SECTION_RENDERER, - 1 + 0 ), RENDERER_ASYNCHRONOUS_SHADERS( "use_asynchronous_shaders", Settings.SECTION_RENDERER, 0 ), + RENDERER_REACTIVE_FLUSHING( + "use_reactive_flushing", + Settings.SECTION_RENDERER, + 0 + ), RENDERER_DEBUG( "debug", Settings.SECTION_RENDERER, diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index 061046b2e..1ceaa6fb4 100755 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -321,6 +321,15 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) IntSetting.RENDERER_ASYNCHRONOUS_SHADERS.defaultValue ) ) + add( + SwitchSetting( + IntSetting.RENDERER_REACTIVE_FLUSHING, + R.string.renderer_reactive_flushing, + R.string.renderer_reactive_flushing_description, + IntSetting.RENDERER_REACTIVE_FLUSHING.key, + IntSetting.RENDERER_REACTIVE_FLUSHING.defaultValue + ) + ) } } diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp index 2d622a048..43e8aa72a 100755 --- a/src/android/app/src/main/jni/config.cpp +++ b/src/android/app/src/main/jni/config.cpp @@ -235,9 +235,13 @@ void Config::ReadValues() { Settings::values.async_presentation = config->GetBoolean("Renderer", "async_presentation", true); - // Enable force_max_clock by default on Android + // Disable force_max_clock by default on Android Settings::values.renderer_force_max_clock = - config->GetBoolean("Renderer", "force_max_clock", true); + config->GetBoolean("Renderer", "force_max_clock", false); + + // Disable use_reactive_flushing by default on Android + Settings::values.use_reactive_flushing = + config->GetBoolean("Renderer", "use_reactive_flushing", false); // Audio ReadSetting("Audio", Settings::values.sink_id); diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h index c5dfaff54..d81422a74 100755 --- a/src/android/app/src/main/jni/default_ini.h +++ b/src/android/app/src/main/jni/default_ini.h @@ -251,7 +251,7 @@ backend = # 0: Off, 1 (default): On async_presentation = -# Enable graphics API debugging mode. +# Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied). # 0 (default): Disabled, 1: Enabled force_max_clock = @@ -328,6 +328,10 @@ shader_backend = # 0 (default): Off, 1: On use_asynchronous_shaders = +# Uses reactive flushing instead of predictive flushing. Allowing a more accurate syncing of memory. +# 0 (default): Off, 1: On +use_reactive_flushing = + # NVDEC emulation. # 0: Disabled, 1: CPU Decoding, 2 (default): GPU Decoding nvdec_emulation = diff --git a/src/android/app/src/main/res/values-de/strings.xml b/src/android/app/src/main/res/values-de/strings.xml index 795320e3e..969223ef8 100755 --- a/src/android/app/src/main/res/values-de/strings.xml +++ b/src/android/app/src/main/res/values-de/strings.xml @@ -176,7 +176,6 @@ Treiber wird installiert... - Erweiterte Einstellungen Einstellungen Allgemein System @@ -228,7 +227,6 @@ Das Deaktivieren dieser Einstellung führt zu erheblichen Leistungsverlusten! Für ein optimales Erlebnis wird empfohlen, sie aktiviert zu lassen. - Automatisch auswählen Japan USA Europa @@ -301,7 +299,6 @@ Auf Fenster anpassen - Auto Akkurat Unsicher Paranoid (Langsam) diff --git a/src/android/app/src/main/res/values-es/strings.xml b/src/android/app/src/main/res/values-es/strings.xml index a7b4ebef4..986e80e50 100755 --- a/src/android/app/src/main/res/values-es/strings.xml +++ b/src/android/app/src/main/res/values-es/strings.xml @@ -61,11 +61,6 @@ Archivo de claves inválido seleccionado Claves instaladas correctamente Error al leer las claves de cifrado - - 1. Verifique que sus claves acaben con la extensión .keys.\n\n - 2. Las claves no deben de estar almacenadas en la carpeta Descargas.\n\n - Resuelva el/los problema(s) y vuelva a intentarlo. - Claves de cifrado no válidas https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys El archivo seleccionado es incorrecto o está corrupto. Vuelva a redumpear sus claves. @@ -184,7 +179,6 @@ Instalando driver... - Configuración avanzada Ajustes General Sistema @@ -238,7 +232,6 @@ ¡Desactivar esta configuración reducirá significativamente el rendimiento de la emulación! Para obtener la mejor experiencia, se recomienda dejar esta configuración habilitada. - Auto seleccionar Japón EEUU Europa @@ -311,7 +304,6 @@ Ajustar a la ventana - Auto Preciso Impreciso Paranoico (Lento) diff --git a/src/android/app/src/main/res/values-fr/strings.xml b/src/android/app/src/main/res/values-fr/strings.xml index 905ab5c03..14a9b2d5c 100755 --- a/src/android/app/src/main/res/values-fr/strings.xml +++ b/src/android/app/src/main/res/values-fr/strings.xml @@ -61,11 +61,6 @@ Fichier de clés sélectionné invalide Clés installées avec succès Erreur lors de la lecture des clés de chiffrement - - 1. Vérifiez que vos clés ont l\'extension .keys.\n\n - 2. Les clés ne doivent pas être stockées dans le dossier Téléchargements.\n\n - Résolvez le(s) problème(s) et réessayez. - Clés de chiffrement invalides https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys Le fichier sélectionné est incorrect ou corrompu. Veuillez dumper à nouveau vos clés. @@ -184,7 +179,6 @@ Installation du pilote... - Paramètres avancés Paramètres Général Système @@ -238,7 +232,6 @@ La désactivation de ce paramètre réduira considérablement les performances d\'émulation ! Pour une expérience optimale, il est recommandé de laisser ce paramètre activé. - Sélection automatique Japon É.-U.A. Europe @@ -311,7 +304,6 @@ Étirer à la fenêtre - Auto Précis Risqué Paranoïaque (Lent) diff --git a/src/android/app/src/main/res/values-it/strings.xml b/src/android/app/src/main/res/values-it/strings.xml index fede49650..47a4cfa31 100755 --- a/src/android/app/src/main/res/values-it/strings.xml +++ b/src/android/app/src/main/res/values-it/strings.xml @@ -61,10 +61,6 @@ Selezionate chiavi non valide Chiavi installate correttamente Errore durante la lettura delle chiavi di crittografia - -1. Verifica che le tue chiavi abbiano l\'estensione .keys.\n\n -2. Le chiavi non devono essere archiviate nella cartella Download.\n\n -Risolvi i problemi e riprova. Chiavi di crittografia non valide https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys Il file selezionato è incorretto o corrotto. Per favore riesegui il dump delle tue chiavi. @@ -183,7 +179,6 @@ Risolvi i problemi e riprova. Installando i driver... - Impostazioni Avanzate Impostazioni Generali Sistema @@ -237,7 +232,6 @@ Risolvi i problemi e riprova. Disattivare questa impostazione può ridurre significativamente le performance di emulazione! Per una migliore esperienza, è consigliato lasciare questa impostazione attivata. - Selezione automatica Giappone USA Europa @@ -310,7 +304,6 @@ Risolvi i problemi e riprova. Allunga a finestra - Automatico Accurata Non sicura Paranoico (Lento) diff --git a/src/android/app/src/main/res/values-ja/strings.xml b/src/android/app/src/main/res/values-ja/strings.xml index 4a649778e..46eda9ef7 100755 --- a/src/android/app/src/main/res/values-ja/strings.xml +++ b/src/android/app/src/main/res/values-ja/strings.xml @@ -60,11 +60,6 @@ 無効なキーファイルが選択されました 正常にインストールされました 暗号化キーの読み取りエラー - - 1. キーの拡張子が .keys であることを確認します。\n\n - 2. キーはダウンロードフォルダに保存しないでください。\n\n - 問題を解決して、再度お試しください。 - 暗号化キーが無効です https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys 選択されたファイルが不正または破損しています。キーを再ダンプしてください。 @@ -183,7 +178,6 @@ インストール中… - 詳細設定 設定 全般 システム @@ -236,7 +230,6 @@ この設定をオフにすると、エミュレーションのパフォーマンスが著しく低下します!最高の体験を得るためには、この設定を有効にしておくことをお勧めします。 - 自動選択 日本 アメリカ ヨーロッパ @@ -309,7 +302,6 @@ ウィンドウに合わせる - 自動 正確 不安定 パラノイド (低速) diff --git a/src/android/app/src/main/res/values-ko/strings.xml b/src/android/app/src/main/res/values-ko/strings.xml index 43b00ebc4..5da80ab4b 100755 --- a/src/android/app/src/main/res/values-ko/strings.xml +++ b/src/android/app/src/main/res/values-ko/strings.xml @@ -61,11 +61,6 @@ 잘못된 keys 파일 선택 keys가 성공적으로 설치됨 암호화 keys 읽기 오류 - -1. keys의 확장자가 .keys인지 확인하세요.\n\n -2. keys는 다운로드 폴더에 저장하면 안 됩니다.\n\n -문제를 해결하고 다시 시도하세요. - 잘못된 암호화 keys https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys 선택한 파일이 잘못되었거나 손상되었습니다. keys를 다시 덤프하세요. @@ -184,7 +179,6 @@ 드라이버 설치 중... - 고급 설정 설정 일반 시스템 @@ -238,7 +232,6 @@ 이 설정을 끄면 에뮬레이션 성능이 크게 저하됩니다! 최상의 환경을 위해 이 설정을 활성화된 상태로 두는 것이 좋습니다. - 자동 선택 일본 미국 유럽 @@ -311,7 +304,6 @@ 창에 맞게 늘림 - 자동 정확함 안전하지 않음 편집증 (느림) diff --git a/src/android/app/src/main/res/values-nb/strings.xml b/src/android/app/src/main/res/values-nb/strings.xml index 80213aed4..3e1f9bce5 100755 --- a/src/android/app/src/main/res/values-nb/strings.xml +++ b/src/android/app/src/main/res/values-nb/strings.xml @@ -61,11 +61,6 @@ Ugyldig nøkkelfil valgt Nøkler vellykket installert Feil ved lesing av krypteringsnøkler - - 1. Kontroller at nøklene har filtypen .keys.\n\n - 2. Nøkler må ikke lagres i nedlastingsmappen.\n\n - Løs problemet/problemene og prøv igjen. - Ugyldige krypteringsnøkler https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys Den valgte filen er feil eller ødelagt. Vennligst dump nøklene på nytt. @@ -184,7 +179,6 @@ Installerer driver... - Avanserte innstillinger Innstillinger Generelt System @@ -238,7 +232,6 @@ Hvis du slår av denne innstillingen, reduseres emuleringsytelsen betydelig! Vi anbefaler at du lar denne innstillingen være aktivert for å få den beste opplevelsen. - Automatisk valg Japan USA Europa @@ -311,7 +304,6 @@ Strekk til Vindu - Auto Nøyaktig Utrygt Paranoid (Langsom) diff --git a/src/android/app/src/main/res/values-pl/strings.xml b/src/android/app/src/main/res/values-pl/strings.xml index fc9f49e0e..1cd1a8f87 100755 --- a/src/android/app/src/main/res/values-pl/strings.xml +++ b/src/android/app/src/main/res/values-pl/strings.xml @@ -61,10 +61,6 @@ Wybrano niepoprawne klucze Klucze zainstalowane pomyślnie Błąd podczas odczytu kluczy - -1. Upewnij się że klucze mają rozszerzenie .keys. \n\n -2. Klucze nie mogą znajdować się w folderze Pobrane. \n\n -Rozwiąż te problemy (oba) i spróbuj ponownie. Niepoprawne klucze https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys Wybrany plik jest niepoprawny lub uszkodzony. Zrzuć ponownie swoje klucze. @@ -183,7 +179,6 @@ Rozwiąż te problemy (oba) i spróbuj ponownie. Instalowanie sterownika... - Zaawansowane Ustawienia Ogólne System @@ -237,7 +232,6 @@ Rozwiąż te problemy (oba) i spróbuj ponownie. Wyłączenie tej opcji znacząco ograniczy wydajność! Dla najlepszego doświadczenia, zaleca się zostawienie tej opcji włączonej. - Auto-wybór Japonia USA Europa @@ -310,7 +304,6 @@ Rozwiąż te problemy (oba) i spróbuj ponownie. Rozciągnij do Okna - Automatyczny Dokładny Niebezpieczny Paranoid (Wolny) diff --git a/src/android/app/src/main/res/values-pt-rBR/strings.xml b/src/android/app/src/main/res/values-pt-rBR/strings.xml index 83185c385..35197c280 100755 --- a/src/android/app/src/main/res/values-pt-rBR/strings.xml +++ b/src/android/app/src/main/res/values-pt-rBR/strings.xml @@ -61,11 +61,6 @@ Ficheiro de chaves inválido Chaves instaladas com sucesso Erro ao ler chaves de encriptação - - 1. Verifica se as tuas chaves têm a extensão .keys.\n\n - 2. As Chaves não podem estar gravadas na pasta Transferências.\n\n - Resolve esta(s) questões e tenta novamente. - Chaves de encriptação inválidas https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys O ficheiro selecionado está corrompido. Por favor recarrega as tuas chaves. @@ -184,7 +179,6 @@ A instalar o Driver... - Configurações avançadas Configurações Geral Sistema @@ -238,7 +232,6 @@ Desligar esta configuração irá reduzir a performance da emulação significantemente! Para a melhor experiência é recomendado que deixes esta configuração ativada. - Auto seleção Japão EUA Europa @@ -311,7 +304,6 @@ Esticar para a janela - Automático Preciso Não seguro Paranoid (Lento) diff --git a/src/android/app/src/main/res/values-pt-rPT/strings.xml b/src/android/app/src/main/res/values-pt-rPT/strings.xml index 3d0851e6f..8761e2374 100755 --- a/src/android/app/src/main/res/values-pt-rPT/strings.xml +++ b/src/android/app/src/main/res/values-pt-rPT/strings.xml @@ -61,11 +61,6 @@ Ficheiro de chaves inválido Chaves instaladas com sucesso Erro ao ler chaves de encriptação - - 1. Verifica se as tuas chaves têm a extensão .keys.\n\n - 2. As Chaves não podem estar gravadas na pasta Transferências.\n\n - Resolve esta(s) questões e tenta novamente. - Chaves de encriptação inválidas https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys O ficheiro selecionado está corrompido. Por favor recarrega as tuas chaves. @@ -184,7 +179,6 @@ A instalar o Driver... - Configurações avançadas Configurações Geral Sistema @@ -238,7 +232,6 @@ Desligar esta configuração irá reduzir a performance da emulação significantemente! Para a melhor experiência é recomendado que deixes esta configuração ativada. - Autosseleção Japão EUA Europa @@ -311,7 +304,6 @@ Esticar à Janela - Automático Preciso Inseguro Paranoid (Lento) diff --git a/src/android/app/src/main/res/values-ru/strings.xml b/src/android/app/src/main/res/values-ru/strings.xml index 1401cf6a0..0fb4908f7 100755 --- a/src/android/app/src/main/res/values-ru/strings.xml +++ b/src/android/app/src/main/res/values-ru/strings.xml @@ -61,11 +61,6 @@ Выбран неверный файл ключей Ключи успешно установлены Ошибка при чтении ключей шифрования - - 1. Убедитесь, что ваши ключи имеют расширение .keys\n\n - 2. Ключи не должны находиться в папке Downloads.\n\n - Исправьте проблему(-ы) и повторите попытку. - Неверные ключи шифрования https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys Выбранный файл неверен или поврежден. Пожалуйста, пере-дампите ваши ключи. @@ -184,7 +179,6 @@ Установка драйвера... - Расширенные настройки Настройки Общие Система @@ -238,7 +232,6 @@ Отключение этой настройки значительно снизит производительность эмуляции! Для достижения наилучших результатов рекомендуется оставить эту настройку включенной. - Авто-выбор Япония США Европа @@ -311,7 +304,6 @@ Растянуть до окна - Авто Точно Небезопасно Параноик (медленно) diff --git a/src/android/app/src/main/res/values-uk/strings.xml b/src/android/app/src/main/res/values-uk/strings.xml index 86d9c84f0..0d11eb2d2 100755 --- a/src/android/app/src/main/res/values-uk/strings.xml +++ b/src/android/app/src/main/res/values-uk/strings.xml @@ -61,11 +61,6 @@ Вибрано неправильний файл ключів Ключі успішно встановлено Помилка під час зчитування ключів шифрування - - 1. Переконайтеся, що ваші ключі мають розширення .keys\n\n - 2. Ключі не повинні знаходитися в папці Downloads.\n\n - Виправте проблему(-и) та спробуйте ще раз. - Невірні ключі шифрування https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys Обраний файл невірний або пошкоджений. Будь ласка, пере-дампіть ваші ключі. @@ -184,7 +179,6 @@ Встановлення драйвера... - Розширені налаштування Налаштування Загальні Система @@ -238,7 +232,6 @@ Вимкнення цього налаштування значно знизить продуктивність емуляції! Для досягнення найкращих результатів рекомендується залишити це налаштування увімкненим. - Авто-вибір Японія США Європа @@ -311,7 +304,6 @@ Розтягнути до вікна - Авто Точно Небезпечно Параноїк (повільно) diff --git a/src/android/app/src/main/res/values-zh-rCN/strings.xml b/src/android/app/src/main/res/values-zh-rCN/strings.xml index 034421c92..e00bbaa2e 100755 --- a/src/android/app/src/main/res/values-zh-rCN/strings.xml +++ b/src/android/app/src/main/res/values-zh-rCN/strings.xml @@ -61,11 +61,6 @@ 选择的密钥文件无效 密钥文件已成功安装 读取加密密钥时出错 - - 1. 验证您的密钥文件是否具有 .keys 扩展名。\n\n - 2. 密钥文件不能放置于 Downloads 文件夹。\n\n - 解决问题并再试一次。 - 无效的加密密钥 https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys 选择的密钥文件不正确或已损坏。请重新转储密钥文件。 @@ -184,7 +179,6 @@ 正在安装驱动程序… - 高级选项 设置 通用 系统 @@ -238,7 +232,6 @@ 关闭此项会显著降低模拟性能!建议您将此项保持为启用状态。 - 自动选择 日本 美国 欧洲 @@ -311,7 +304,6 @@ 拉伸窗口 - 自动 高精度 低精度 偏执模式 (慢速) diff --git a/src/android/app/src/main/res/values-zh-rTW/strings.xml b/src/android/app/src/main/res/values-zh-rTW/strings.xml index 85798cc6a..a54d04248 100755 --- a/src/android/app/src/main/res/values-zh-rTW/strings.xml +++ b/src/android/app/src/main/res/values-zh-rTW/strings.xml @@ -61,11 +61,6 @@ 無效的金鑰檔案已選取 金鑰已成功安裝 讀取加密金鑰時出現錯誤 - - 1. 驗證您的金鑰是否具有 .keys 副檔名。\n\n - 2. 金鑰不能儲存於 Downloads 資料夾。\n\n - 解決問題並再試一次。 - 無效的加密金鑰 https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys 選取的檔案不正確或已損毀,請重新傾印您的金鑰。 @@ -184,7 +179,6 @@ 正在安裝驅動程式… - 進階設定 設定 一般 系統 @@ -238,7 +232,6 @@ 關閉此設定會顯著降低模擬效能!如需最佳體驗,建議您將此設定保持為啟用狀態。 - 自動選取 日本 美國 歐洲 @@ -311,8 +304,6 @@ 延伸視窗 - 自動 - 高精度 低精度 不合理 (慢) diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 7dae63dcb..c236811fa 100755 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -169,6 +169,8 @@ Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied). Use asynchronous shaders Compiles shaders asynchronously, reducing stutter but may introduce glitches. + Use reactive flushing + Improves rendering accuracy in some games at the cost of performance. Graphics debugging Sets the graphics API to a slow debugging mode. Disk shader cache diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index 2bc656ed0..140c1199a 100755 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp @@ -25,8 +25,6 @@ namespace FS = Common::FS; namespace { -constexpr size_t MaxOpenFiles = 512; - constexpr FS::FileAccessMode ModeFlagsToFileAccessMode(Mode mode) { switch (mode) { case Mode::Read: @@ -75,10 +73,24 @@ VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const { VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); - auto reference = std::make_unique(); - this->InsertReferenceIntoList(*reference); + if (const auto weak_iter = cache.find(path); weak_iter != cache.cend()) { + const auto& weak = weak_iter->second; - return std::shared_ptr(new RealVfsFile(*this, std::move(reference), path, perms)); + if (!weak.expired()) { + return std::shared_ptr(new RealVfsFile(*this, weak.lock(), path, perms)); + } + } + + auto backing = FS::FileOpen(path, ModeFlagsToFileAccessMode(perms), FS::FileType::BinaryFile); + + if (!backing) { + return nullptr; + } + + cache.insert_or_assign(path, std::move(backing)); + + // Cannot use make_shared as RealVfsFile constructor is private + return std::shared_ptr(new RealVfsFile(*this, backing, path, perms)); } VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) { @@ -111,19 +123,51 @@ VirtualFile RealVfsFilesystem::CopyFile(std::string_view old_path_, std::string_ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) { const auto old_path = FS::SanitizePath(old_path_, FS::DirectorySeparator::PlatformDefault); const auto new_path = FS::SanitizePath(new_path_, FS::DirectorySeparator::PlatformDefault); - if (!FS::RenameFile(old_path, new_path)) { + const auto cached_file_iter = cache.find(old_path); + + if (cached_file_iter != cache.cend()) { + auto file = cached_file_iter->second.lock(); + + if (!cached_file_iter->second.expired()) { + file->Close(); + } + + if (!FS::RenameFile(old_path, new_path)) { + return nullptr; + } + + cache.erase(old_path); + file->Open(new_path, FS::FileAccessMode::Read, FS::FileType::BinaryFile); + if (file->IsOpen()) { + cache.insert_or_assign(new_path, std::move(file)); + } else { + LOG_ERROR(Service_FS, "Failed to open path {} in order to re-cache it", new_path); + } + } else { + ASSERT(false); return nullptr; } + return OpenFile(new_path, Mode::ReadWrite); } bool RealVfsFilesystem::DeleteFile(std::string_view path_) { const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); + const auto cached_iter = cache.find(path); + + if (cached_iter != cache.cend()) { + if (!cached_iter->second.expired()) { + cached_iter->second.lock()->Close(); + } + cache.erase(path); + } + return FS::RemoveFile(path); } VirtualDir RealVfsFilesystem::OpenDirectory(std::string_view path_, Mode perms) { const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); + // Cannot use make_shared as RealVfsDirectory constructor is private return std::shared_ptr(new RealVfsDirectory(*this, path, perms)); } @@ -132,6 +176,7 @@ VirtualDir RealVfsFilesystem::CreateDirectory(std::string_view path_, Mode perms if (!FS::CreateDirs(path)) { return nullptr; } + // Cannot use make_shared as RealVfsDirectory constructor is private return std::shared_ptr(new RealVfsDirectory(*this, path, perms)); } @@ -149,102 +194,73 @@ VirtualDir RealVfsFilesystem::MoveDirectory(std::string_view old_path_, if (!FS::RenameDir(old_path, new_path)) { return nullptr; } + + for (auto& kv : cache) { + // If the path in the cache doesn't start with old_path, then bail on this file. + if (kv.first.rfind(old_path, 0) != 0) { + continue; + } + + const auto file_old_path = + FS::SanitizePath(kv.first, FS::DirectorySeparator::PlatformDefault); + auto file_new_path = FS::SanitizePath(new_path + '/' + kv.first.substr(old_path.size()), + FS::DirectorySeparator::PlatformDefault); + const auto& cached = cache[file_old_path]; + + if (cached.expired()) { + continue; + } + + auto file = cached.lock(); + cache.erase(file_old_path); + file->Open(file_new_path, FS::FileAccessMode::Read, FS::FileType::BinaryFile); + if (file->IsOpen()) { + cache.insert_or_assign(std::move(file_new_path), std::move(file)); + } else { + LOG_ERROR(Service_FS, "Failed to open path {} in order to re-cache it", file_new_path); + } + } + return OpenDirectory(new_path, Mode::ReadWrite); } bool RealVfsFilesystem::DeleteDirectory(std::string_view path_) { const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); + + for (auto& kv : cache) { + // If the path in the cache doesn't start with path, then bail on this file. + if (kv.first.rfind(path, 0) != 0) { + continue; + } + + const auto& entry = cache[kv.first]; + if (!entry.expired()) { + entry.lock()->Close(); + } + + cache.erase(kv.first); + } + return FS::RemoveDirRecursively(path); } -void RealVfsFilesystem::RefreshReference(const std::string& path, Mode perms, - FileReference& reference) { - // Temporarily remove from list. - this->RemoveReferenceFromList(reference); - - // Restore file if needed. - if (!reference.file) { - this->EvictSingleReference(); - - reference.file = - FS::FileOpen(path, ModeFlagsToFileAccessMode(perms), FS::FileType::BinaryFile); - if (reference.file) { - num_open_files++; - } - } - - // Reinsert into list. - this->InsertReferenceIntoList(reference); -} - -void RealVfsFilesystem::DropReference(std::unique_ptr&& reference) { - // Remove from list. - this->RemoveReferenceFromList(*reference); - - // Close the file. - if (reference->file) { - reference->file.reset(); - num_open_files--; - } -} - -void RealVfsFilesystem::EvictSingleReference() { - if (num_open_files < MaxOpenFiles || open_references.empty()) { - return; - } - - // Get and remove from list. - auto& reference = open_references.back(); - this->RemoveReferenceFromList(reference); - - // Close the file. - if (reference.file) { - reference.file.reset(); - num_open_files--; - } - - // Reinsert into closed list. - this->InsertReferenceIntoList(reference); -} - -void RealVfsFilesystem::InsertReferenceIntoList(FileReference& reference) { - if (reference.file) { - open_references.push_front(reference); - } else { - closed_references.push_front(reference); - } -} - -void RealVfsFilesystem::RemoveReferenceFromList(FileReference& reference) { - if (reference.file) { - open_references.erase(open_references.iterator_to(reference)); - } else { - closed_references.erase(closed_references.iterator_to(reference)); - } -} - -RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr reference_, +RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::shared_ptr backing_, const std::string& path_, Mode perms_) - : base(base_), reference(std::move(reference_)), path(path_), - parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponents(path_)), - perms(perms_) {} + : base(base_), backing(std::move(backing_)), path(path_), parent_path(FS::GetParentPath(path_)), + path_components(FS::SplitPathComponents(path_)), perms(perms_) {} -RealVfsFile::~RealVfsFile() { - base.DropReference(std::move(reference)); -} +RealVfsFile::~RealVfsFile() = default; std::string RealVfsFile::GetName() const { return path_components.back(); } std::size_t RealVfsFile::GetSize() const { - base.RefreshReference(path, perms, *reference); - return reference->file ? reference->file->GetSize() : 0; + return backing->GetSize(); } bool RealVfsFile::Resize(std::size_t new_size) { - base.RefreshReference(path, perms, *reference); - return reference->file ? reference->file->SetSize(new_size) : false; + return backing->SetSize(new_size); } VirtualDir RealVfsFile::GetContainingDirectory() const { @@ -260,25 +276,27 @@ bool RealVfsFile::IsReadable() const { } std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const { - base.RefreshReference(path, perms, *reference); - if (!reference->file || !reference->file->Seek(static_cast(offset))) { + if (!backing->Seek(static_cast(offset))) { return 0; } - return reference->file->ReadSpan(std::span{data, length}); + return backing->ReadSpan(std::span{data, length}); } std::size_t RealVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) { - base.RefreshReference(path, perms, *reference); - if (!reference->file || !reference->file->Seek(static_cast(offset))) { + if (!backing->Seek(static_cast(offset))) { return 0; } - return reference->file->WriteSpan(std::span{data, length}); + return backing->WriteSpan(std::span{data, length}); } bool RealVfsFile::Rename(std::string_view name) { return base.MoveFile(path, parent_path + '/' + std::string(name)) != nullptr; } +void RealVfsFile::Close() { + backing->Close(); +} + // TODO(DarkLordZach): MSVC would not let me combine the following two functions using 'if // constexpr' because there is a compile error in the branch not used. diff --git a/src/core/file_sys/vfs_real.h b/src/core/file_sys/vfs_real.h index 4c2879fec..ba29857df 100755 --- a/src/core/file_sys/vfs_real.h +++ b/src/core/file_sys/vfs_real.h @@ -4,7 +4,7 @@ #pragma once #include -#include "common/intrusive_list.h" +#include #include "core/file_sys/mode.h" #include "core/file_sys/vfs.h" @@ -14,11 +14,6 @@ class IOFile; namespace FileSys { -struct FileReference : public Common::IntrusiveListBaseNode { - std::shared_ptr file{}; -}; - -class RealVfsFile; class RealVfsFilesystem : public VfsFilesystem { public: RealVfsFilesystem(); @@ -40,20 +35,7 @@ public: bool DeleteDirectory(std::string_view path) override; private: - using ReferenceListType = Common::IntrusiveListBaseTraits::ListType; - ReferenceListType open_references; - ReferenceListType closed_references; - size_t num_open_files{}; - -private: - friend class RealVfsFile; - void RefreshReference(const std::string& path, Mode perms, FileReference& reference); - void DropReference(std::unique_ptr&& reference); - void EvictSingleReference(); - -private: - void InsertReferenceIntoList(FileReference& reference); - void RemoveReferenceFromList(FileReference& reference); + boost::container::flat_map> cache; }; // An implementation of VfsFile that represents a file on the user's computer. @@ -75,11 +57,13 @@ public: bool Rename(std::string_view name) override; private: - RealVfsFile(RealVfsFilesystem& base, std::unique_ptr reference, + RealVfsFile(RealVfsFilesystem& base, std::shared_ptr backing, const std::string& path, Mode perms = Mode::Read); + void Close(); + RealVfsFilesystem& base; - std::unique_ptr reference; + std::shared_ptr backing; std::string path; std::string parent_path; std::vector path_components; diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp index dbe6018d8..22eb7bd00 100755 --- a/src/video_core/texture_cache/image_info.cpp +++ b/src/video_core/texture_cache/image_info.cpp @@ -22,6 +22,9 @@ using Tegra::Texture::TICEntry; using VideoCore::Surface::PixelFormat; using VideoCore::Surface::SurfaceType; +constexpr u32 RescaleHeightThreshold = 288; +constexpr u32 DownscaleHeightThreshold = 512; + ImageInfo::ImageInfo(const TICEntry& config) noexcept { forced_flushed = config.IsPitchLinear() && !Settings::values.use_reactive_flushing.GetValue(); dma_downloaded = forced_flushed; @@ -113,8 +116,9 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept { layer_stride = CalculateLayerStride(*this); maybe_unaligned_layer_stride = CalculateLayerSize(*this); rescaleable &= (block.depth == 0) && resources.levels == 1; - rescaleable &= size.height > 256 || GetFormatType(format) != SurfaceType::ColorTexture; - downscaleable = size.height > 512; + rescaleable &= size.height > RescaleHeightThreshold || + GetFormatType(format) != SurfaceType::ColorTexture; + downscaleable = size.height > DownscaleHeightThreshold; } } @@ -152,8 +156,8 @@ ImageInfo::ImageInfo(const Maxwell3D::Regs::RenderTargetConfig& ct, size.depth = ct.depth; } else { rescaleable = block.depth == 0; - rescaleable &= size.height > 256; - downscaleable = size.height > 512; + rescaleable &= size.height > RescaleHeightThreshold; + downscaleable = size.height > DownscaleHeightThreshold; type = ImageType::e2D; resources.layers = ct.depth; } @@ -232,8 +236,8 @@ ImageInfo::ImageInfo(const Fermi2D::Surface& config) noexcept { .height = config.height, .depth = 1, }; - rescaleable = block.depth == 0 && size.height > 256; - downscaleable = size.height > 512; + rescaleable = block.depth == 0 && size.height > RescaleHeightThreshold; + downscaleable = size.height > DownscaleHeightThreshold; } } @@ -275,8 +279,8 @@ ImageInfo::ImageInfo(const Tegra::DMA::ImageOperand& config) noexcept { resources.layers = 1; layer_stride = CalculateLayerStride(*this); maybe_unaligned_layer_stride = CalculateLayerSize(*this); - rescaleable = block.depth == 0 && size.height > 256; - downscaleable = size.height > 512; + rescaleable = block.depth == 0 && size.height > RescaleHeightThreshold; + downscaleable = size.height > DownscaleHeightThreshold; } } // namespace VideoCommon