Compare commits
10 commits
e81a358d83
...
1722ef66c5
Author | SHA1 | Date | |
---|---|---|---|
1722ef66c5 | |||
8f1a574fe0 | |||
d623e04606 | |||
4b558e5303 | |||
28b8159da1 | |||
87d42cf542 | |||
725407b989 | |||
6510818fca | |||
a487cea683 | |||
a3c0d59dc9 |
32 changed files with 148 additions and 330 deletions
|
@ -10,17 +10,18 @@
|
|||
/.ci @crueter
|
||||
|
||||
# cmake
|
||||
*.cmake @crueter
|
||||
*/CMakeLists.txt @crueter
|
||||
*.in @crueter
|
||||
*.cmake @crueter
|
||||
*CMakeLists.txt @crueter
|
||||
*.in @crueter
|
||||
|
||||
# individual stuff
|
||||
/src/web_service @AleksandrPopovich
|
||||
/src/dynarmic @Lizzie
|
||||
/src/core @Lizzie @Maufeat @PavelBARABANOV @MrPurple666
|
||||
/src/core/hle @Maufeat @PavelBARABANOV @SDK-Chan
|
||||
/src/*_room @AleksandrPopovich
|
||||
/src/video_core @CamilleLaVey @MaranBr @Wildcard @weakboson
|
||||
src/web_service @AleksandrPopovich
|
||||
src/dynarmic @Lizzie
|
||||
src/core @Lizzie @Maufeat @PavelBARABANOV @MrPurple666 @JPikachu
|
||||
src/core/hle @Maufeat @PavelBARABANOV @SDK-Chan
|
||||
src/core/arm @Lizzie @MrPurple666
|
||||
src/*_room @AleksandrPopovich
|
||||
src/video_core @CamilleLaVey @MaranBr @Wildcard @weakboson
|
||||
|
||||
# Global owners/triage
|
||||
* @CamilleLaVey @Maufeat @crueter @MrPurple666 @MaranBr @Lizzie
|
|
@ -836,13 +836,13 @@
|
|||
<string name="ratio_stretch">تمتد إلى النافذة</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (بطيء)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">تنفيذ التعليمات البرمجية الأصلية (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">دقه</string>
|
||||
<string name="cpu_accuracy_unsafe">غير آمن</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoid (بطيء)</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoid</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">الأسهم</string>
|
||||
|
|
|
@ -919,13 +919,13 @@
|
|||
<string name="ratio_stretch">Ajustar a la ventana</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">DynARMic (lento)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">Ejecución nativa de código (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">Preciso</string>
|
||||
<string name="cpu_accuracy_unsafe">Impreciso</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoico (Lento)</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoico</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">Cruceta</string>
|
||||
|
|
|
@ -918,13 +918,13 @@
|
|||
<string name="ratio_stretch">کشش تا پر کردن پنجره</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">دینارمیک (کند)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">اجرای کد اصلی (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">دقیق</string>
|
||||
<string name="cpu_accuracy_unsafe">ناامن</string>
|
||||
<string name="cpu_accuracy_paranoid">بدگمان (کند)</string>
|
||||
<string name="cpu_accuracy_paranoid">بدگمان</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">کلیدهای جهتی</string>
|
||||
|
|
|
@ -967,13 +967,13 @@
|
|||
<string name="ratio_stretch">Étirer à la fenêtre</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (Lent)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">Exécution de code natif (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">Précis</string>
|
||||
<string name="cpu_accuracy_unsafe">Risqué</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoïaque (Lent)</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoïaque</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">Pavé directionnel</string>
|
||||
|
|
|
@ -844,13 +844,13 @@
|
|||
<string name="ratio_stretch">הרחב לגודל המסך</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">דינמי (איטי)</string>
|
||||
<string name="cpu_backend_dynarmic">דינמי</string>
|
||||
<string name="cpu_backend_nce">ביצוע קוד מקורי (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">מדויק</string>
|
||||
<string name="cpu_accuracy_unsafe">לא בטוח</string>
|
||||
<string name="cpu_accuracy_paranoid">פראנואידי (איטי)</string>
|
||||
<string name="cpu_accuracy_paranoid">פראנואידי</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">D-pad</string>
|
||||
|
|
|
@ -954,13 +954,13 @@
|
|||
<string name="ratio_stretch">Ablakhoz nyújtás</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">Dinamikus (lassú)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">Natív kód végrehajtás (Native code execution (NCE))</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">Pontos</string>
|
||||
<string name="cpu_accuracy_unsafe">Nem biztonságos</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoid (Lassú)</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoid</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">D-pad</string>
|
||||
|
|
|
@ -911,13 +911,13 @@
|
|||
<string name="ratio_stretch">Merentangkan</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">Dynamic (Lambat)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">Native code execution (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">Akurat</string>
|
||||
<string name="cpu_accuracy_unsafe">Berbahaya</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoid (Slow)</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoid</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">D Pad</string>
|
||||
|
|
|
@ -834,13 +834,13 @@
|
|||
<string name="ratio_stretch">画面に合わせる</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (低速)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">ネイティブコード実行 (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">正確</string>
|
||||
<string name="cpu_accuracy_unsafe">不安定</string>
|
||||
<string name="cpu_accuracy_paranoid">パラノイド (低速)</string>
|
||||
<string name="cpu_accuracy_paranoid">パラノイド</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">方向ボタン</string>
|
||||
|
|
|
@ -910,13 +910,13 @@
|
|||
<string name="ratio_stretch">화면에 맞춤</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (느림)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">네이티브 코드 실행 (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">정확함</string>
|
||||
<string name="cpu_accuracy_unsafe">최적화 (안전하지 않음)</string>
|
||||
<string name="cpu_accuracy_paranoid">최적화하지 않음 (느림)</string>
|
||||
<string name="cpu_accuracy_paranoid">최적화하지 않음</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">십자키</string>
|
||||
|
|
|
@ -968,13 +968,13 @@ uma tentativa de mapeamento automático</string>
|
|||
<string name="ratio_stretch">Esticar à janela</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (Lenta)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">Execução de código nativo (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">Precisa</string>
|
||||
<string name="cpu_accuracy_unsafe">Não segura</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoica (Lenta)</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoica</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">Botões Direcionais</string>
|
||||
|
|
|
@ -968,13 +968,13 @@ uma tentativa de mapeamento automático</string>
|
|||
<string name="ratio_stretch">Esticar à janela</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (Lento)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">Native code execution (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">Preciso</string>
|
||||
<string name="cpu_accuracy_unsafe">Inseguro</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoid (Lento)</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoid</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">Botões Direcionais</string>
|
||||
|
|
|
@ -969,13 +969,13 @@
|
|||
<string name="ratio_stretch">Растянуть до окна</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (Медленно)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">Нативное выполнение (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">Точно</string>
|
||||
<string name="cpu_accuracy_unsafe">Небезопасно</string>
|
||||
<string name="cpu_accuracy_paranoid">Параноик (медленно)</string>
|
||||
<string name="cpu_accuracy_paranoid">Параноик</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">Крестовина</string>
|
||||
|
|
|
@ -988,13 +988,13 @@
|
|||
<string name="ratio_stretch">Протезање до прозора</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">Динамина (споро)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">Извођење изворног кода (НЦЕ)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">Тачан</string>
|
||||
<string name="cpu_accuracy_unsafe">Несигуран</string>
|
||||
<string name="cpu_accuracy_paranoid">Параноичан (споро)</string>
|
||||
<string name="cpu_accuracy_paranoid">Параноичан</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">Д-пад</string>
|
||||
|
|
|
@ -961,13 +961,13 @@
|
|||
<string name="ratio_stretch">拉伸窗口</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">动态编译 (慢速)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">本机代码执行 (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">高精度</string>
|
||||
<string name="cpu_accuracy_unsafe">低精度</string>
|
||||
<string name="cpu_accuracy_paranoid">偏执模式 (慢速)</string>
|
||||
<string name="cpu_accuracy_paranoid">偏执模式</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">十字方向键</string>
|
||||
|
|
|
@ -966,13 +966,13 @@
|
|||
<string name="ratio_stretch">延展視窗</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">動態 (慢)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">機器碼執行 (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">高精度</string>
|
||||
<string name="cpu_accuracy_unsafe">低精度</string>
|
||||
<string name="cpu_accuracy_paranoid">不合理 (慢)</string>
|
||||
<string name="cpu_accuracy_paranoid">不合理</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">方向鍵</string>
|
||||
|
|
|
@ -1014,13 +1014,13 @@
|
|||
<string name="ratio_stretch">Stretch to window</string>
|
||||
|
||||
<!-- CPU Backend -->
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (Slow)</string>
|
||||
<string name="cpu_backend_dynarmic">Dynarmic (JIT)</string>
|
||||
<string name="cpu_backend_nce">Native code execution (NCE)</string>
|
||||
|
||||
<!-- CPU Accuracy -->
|
||||
<string name="cpu_accuracy_accurate">Accurate</string>
|
||||
<string name="cpu_accuracy_unsafe">Unsafe</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoid (Slow)</string>
|
||||
<string name="cpu_accuracy_paranoid">Paranoid</string>
|
||||
|
||||
<!-- Gamepad Buttons -->
|
||||
<string name="gamepad_d_pad">D-pad</string>
|
||||
|
|
|
@ -107,8 +107,6 @@ add_library(core STATIC
|
|||
file_sys/fssystem/fssystem_nca_header.cpp
|
||||
file_sys/fssystem/fssystem_nca_header.h
|
||||
file_sys/fssystem/fssystem_nca_reader.cpp
|
||||
file_sys/fssystem/fssystem_pooled_buffer.cpp
|
||||
file_sys/fssystem/fssystem_pooled_buffer.h
|
||||
file_sys/fssystem/fssystem_sparse_storage.cpp
|
||||
file_sys/fssystem/fssystem_sparse_storage.h
|
||||
file_sys/fssystem/fssystem_switch_storage.h
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/file_sys/fssystem/fssystem_aes_ctr_storage.h"
|
||||
#include "core/file_sys/fssystem/fssystem_pooled_buffer.h"
|
||||
#include "core/file_sys/fssystem/fssystem_utility.h"
|
||||
|
||||
namespace FileSys {
|
||||
|
@ -76,13 +78,6 @@ size_t AesCtrStorage::Write(const u8* buffer, size_t size, size_t offset) {
|
|||
ASSERT(Common::IsAligned(offset, BlockSize));
|
||||
ASSERT(Common::IsAligned(size, BlockSize));
|
||||
|
||||
// Get a pooled buffer.
|
||||
PooledBuffer pooled_buffer;
|
||||
const bool use_work_buffer = true;
|
||||
if (use_work_buffer) {
|
||||
pooled_buffer.Allocate(size, BlockSize);
|
||||
}
|
||||
|
||||
// Setup the counter.
|
||||
std::array<u8, IvSize> ctr;
|
||||
std::memcpy(ctr.data(), m_iv.data(), IvSize);
|
||||
|
@ -91,25 +86,20 @@ size_t AesCtrStorage::Write(const u8* buffer, size_t size, size_t offset) {
|
|||
// Loop until all data is written.
|
||||
size_t remaining = size;
|
||||
s64 cur_offset = 0;
|
||||
|
||||
// Get a pooled buffer.
|
||||
std::vector<char> pooled_buffer(BlockSize);
|
||||
while (remaining > 0) {
|
||||
// Determine data we're writing and where.
|
||||
const size_t write_size =
|
||||
use_work_buffer ? (std::min)(pooled_buffer.GetSize(), remaining) : remaining;
|
||||
|
||||
void* write_buf;
|
||||
if (use_work_buffer) {
|
||||
write_buf = pooled_buffer.GetBuffer();
|
||||
} else {
|
||||
write_buf = const_cast<u8*>(buffer);
|
||||
}
|
||||
const size_t write_size = std::min(pooled_buffer.size(), remaining);
|
||||
u8* write_buf = reinterpret_cast<u8*>(pooled_buffer.data());
|
||||
|
||||
// Encrypt the data.
|
||||
m_cipher->SetIV(ctr);
|
||||
m_cipher->Transcode(buffer, write_size, reinterpret_cast<u8*>(write_buf),
|
||||
Core::Crypto::Op::Encrypt);
|
||||
m_cipher->Transcode(buffer, write_size, write_buf, Core::Crypto::Op::Encrypt);
|
||||
|
||||
// Write the encrypted data.
|
||||
m_base_storage->Write(reinterpret_cast<u8*>(write_buf), write_size, offset + cur_offset);
|
||||
m_base_storage->Write(write_buf, write_size, offset + cur_offset);
|
||||
|
||||
// Advance.
|
||||
cur_offset += write_size;
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/file_sys/errors.h"
|
||||
#include "core/file_sys/fssystem/fssystem_aes_xts_storage.h"
|
||||
#include "core/file_sys/fssystem/fssystem_pooled_buffer.h"
|
||||
#include "core/file_sys/fssystem/fssystem_utility.h"
|
||||
|
||||
namespace FileSys {
|
||||
|
@ -69,17 +70,14 @@ size_t AesXtsStorage::Read(u8* buffer, size_t size, size_t offset) const {
|
|||
|
||||
// Decrypt into a pooled buffer.
|
||||
{
|
||||
PooledBuffer tmp_buf(m_block_size, m_block_size);
|
||||
ASSERT(tmp_buf.GetSize() >= m_block_size);
|
||||
|
||||
std::memset(tmp_buf.GetBuffer(), 0, skip_size);
|
||||
std::memcpy(tmp_buf.GetBuffer() + skip_size, buffer, data_size);
|
||||
std::vector<char> tmp_buf(m_block_size, 0);
|
||||
std::memcpy(tmp_buf.data() + skip_size, buffer, data_size);
|
||||
|
||||
m_cipher->SetIV(ctr);
|
||||
m_cipher->Transcode(tmp_buf.GetBuffer(), m_block_size, tmp_buf.GetBuffer(),
|
||||
m_cipher->Transcode(tmp_buf.data(), m_block_size, tmp_buf.data(),
|
||||
Core::Crypto::Op::Decrypt);
|
||||
|
||||
std::memcpy(buffer, tmp_buf.GetBuffer() + skip_size, data_size);
|
||||
std::memcpy(buffer, tmp_buf.data() + skip_size, data_size);
|
||||
}
|
||||
|
||||
AddCounter(ctr.data(), IvSize, 1);
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "core/file_sys/errors.h"
|
||||
#include "core/file_sys/fssystem/fs_i_storage.h"
|
||||
#include "core/file_sys/fssystem/fssystem_alignment_matching_storage_impl.h"
|
||||
#include "core/file_sys/fssystem/fssystem_pooled_buffer.h"
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
|
@ -89,10 +90,11 @@ private:
|
|||
VirtualFile m_base_storage;
|
||||
s64 m_base_storage_size;
|
||||
size_t m_data_align;
|
||||
mutable std::vector<char> work_buffer;
|
||||
|
||||
public:
|
||||
explicit AlignmentMatchingStoragePooledBuffer(VirtualFile bs, size_t da)
|
||||
: m_base_storage(std::move(bs)), m_data_align(da) {
|
||||
: m_base_storage(std::move(bs)), m_data_align(da), work_buffer(da) {
|
||||
ASSERT(Common::IsPowerOfTwo(da));
|
||||
}
|
||||
|
||||
|
@ -104,16 +106,10 @@ public:
|
|||
|
||||
// Validate arguments.
|
||||
ASSERT(buffer != nullptr);
|
||||
|
||||
s64 bs_size = this->GetSize();
|
||||
ASSERT(R_SUCCEEDED(IStorage::CheckAccessRange(offset, size, bs_size)));
|
||||
|
||||
// Allocate a pooled buffer.
|
||||
PooledBuffer pooled_buffer;
|
||||
pooled_buffer.AllocateParticularlyLarge(m_data_align, m_data_align);
|
||||
|
||||
return AlignmentMatchingStorageImpl::Read(m_base_storage, pooled_buffer.GetBuffer(),
|
||||
pooled_buffer.GetSize(), m_data_align,
|
||||
return AlignmentMatchingStorageImpl::Read(m_base_storage, work_buffer.data(),
|
||||
work_buffer.size(), m_data_align,
|
||||
BufferAlign, offset, buffer, size);
|
||||
}
|
||||
|
||||
|
@ -125,16 +121,10 @@ public:
|
|||
|
||||
// Validate arguments.
|
||||
ASSERT(buffer != nullptr);
|
||||
|
||||
s64 bs_size = this->GetSize();
|
||||
ASSERT(R_SUCCEEDED(IStorage::CheckAccessRange(offset, size, bs_size)));
|
||||
|
||||
// Allocate a pooled buffer.
|
||||
PooledBuffer pooled_buffer;
|
||||
pooled_buffer.AllocateParticularlyLarge(m_data_align, m_data_align);
|
||||
|
||||
return AlignmentMatchingStorageImpl::Write(m_base_storage, pooled_buffer.GetBuffer(),
|
||||
pooled_buffer.GetSize(), m_data_align,
|
||||
return AlignmentMatchingStorageImpl::Write(m_base_storage, work_buffer.data(),
|
||||
work_buffer.size(), m_data_align,
|
||||
BufferAlign, offset, buffer, size);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "core/file_sys/errors.h"
|
||||
#include "core/file_sys/fssystem/fssystem_bucket_tree.h"
|
||||
#include "core/file_sys/fssystem/fssystem_bucket_tree_utils.h"
|
||||
#include "core/file_sys/fssystem/fssystem_pooled_buffer.h"
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
|
@ -465,16 +464,8 @@ Result BucketTree::Visitor::Find(s64 virtual_address) {
|
|||
}
|
||||
|
||||
Result BucketTree::Visitor::FindEntrySet(s32* out_index, s64 virtual_address, s32 node_index) {
|
||||
const auto node_size = m_tree->m_node_size;
|
||||
|
||||
PooledBuffer pool(node_size, 1);
|
||||
if (node_size <= pool.GetSize()) {
|
||||
R_RETURN(
|
||||
this->FindEntrySetWithBuffer(out_index, virtual_address, node_index, pool.GetBuffer()));
|
||||
} else {
|
||||
pool.Deallocate();
|
||||
R_RETURN(this->FindEntrySetWithoutBuffer(out_index, virtual_address, node_index));
|
||||
}
|
||||
std::vector<char> pool(m_tree->m_node_size);
|
||||
R_RETURN(FindEntrySetWithBuffer(out_index, virtual_address, node_index, pool.data()));
|
||||
}
|
||||
|
||||
Result BucketTree::Visitor::FindEntrySetWithBuffer(s32* out_index, s64 virtual_address,
|
||||
|
@ -525,15 +516,8 @@ Result BucketTree::Visitor::FindEntrySetWithoutBuffer(s32* out_index, s64 virtua
|
|||
}
|
||||
|
||||
Result BucketTree::Visitor::FindEntry(s64 virtual_address, s32 entry_set_index) {
|
||||
const auto entry_set_size = m_tree->m_node_size;
|
||||
|
||||
PooledBuffer pool(entry_set_size, 1);
|
||||
if (entry_set_size <= pool.GetSize()) {
|
||||
R_RETURN(this->FindEntryWithBuffer(virtual_address, entry_set_index, pool.GetBuffer()));
|
||||
} else {
|
||||
pool.Deallocate();
|
||||
R_RETURN(this->FindEntryWithoutBuffer(virtual_address, entry_set_index));
|
||||
}
|
||||
std::vector<char> pool(m_tree->m_node_size);
|
||||
R_RETURN(FindEntryWithBuffer(virtual_address, entry_set_index, pool.data()));
|
||||
}
|
||||
|
||||
Result BucketTree::Visitor::FindEntryWithBuffer(s64 virtual_address, s32 entry_set_index,
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -6,7 +9,6 @@
|
|||
#include "core/file_sys/errors.h"
|
||||
#include "core/file_sys/fssystem/fssystem_bucket_tree.h"
|
||||
#include "core/file_sys/fssystem/fssystem_bucket_tree_utils.h"
|
||||
#include "core/file_sys/fssystem/fssystem_pooled_buffer.h"
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
|
@ -35,23 +37,19 @@ Result BucketTree::ScanContinuousReading(ContinuousReadingInfo* out_info,
|
|||
R_UNLESS(entry.GetVirtualOffset() <= cur_offset, ResultOutOfRange);
|
||||
|
||||
// Create a pooled buffer for our scan.
|
||||
PooledBuffer pool(m_node_size, 1);
|
||||
char* buffer = nullptr;
|
||||
|
||||
std::vector<char> pool(m_node_size);
|
||||
s64 entry_storage_size = m_entry_storage->GetSize();
|
||||
|
||||
// Read the node.
|
||||
if (m_node_size <= pool.GetSize()) {
|
||||
buffer = pool.GetBuffer();
|
||||
const auto ofs = param.entry_set.index * static_cast<s64>(m_node_size);
|
||||
R_UNLESS(m_node_size + ofs <= static_cast<size_t>(entry_storage_size),
|
||||
ResultInvalidBucketTreeNodeEntryCount);
|
||||
u8* buffer = reinterpret_cast<u8*>(pool.data());
|
||||
const auto ofs = param.entry_set.index * s64(m_node_size);
|
||||
R_UNLESS(m_node_size + ofs <= size_t(entry_storage_size),
|
||||
ResultInvalidBucketTreeNodeEntryCount);
|
||||
|
||||
m_entry_storage->Read(reinterpret_cast<u8*>(buffer), m_node_size, ofs);
|
||||
}
|
||||
m_entry_storage->Read(buffer, m_node_size, ofs);
|
||||
|
||||
// Calculate extents.
|
||||
const auto end_offset = cur_offset + static_cast<s64>(param.size);
|
||||
const auto end_offset = cur_offset + s64(param.size);
|
||||
s64 phys_offset = entry.GetPhysicalOffset();
|
||||
|
||||
// Start merge tracking.
|
||||
|
@ -76,14 +74,8 @@ Result BucketTree::ScanContinuousReading(ContinuousReadingInfo* out_info,
|
|||
s64 next_entry_offset;
|
||||
|
||||
if (entry_index + 1 < entry_count) {
|
||||
if (buffer != nullptr) {
|
||||
const auto ofs = impl::GetBucketTreeEntryOffset(0, m_entry_size, entry_index + 1);
|
||||
std::memcpy(std::addressof(next_entry), buffer + ofs, m_entry_size);
|
||||
} else {
|
||||
const auto ofs = impl::GetBucketTreeEntryOffset(param.entry_set.index, m_node_size,
|
||||
m_entry_size, entry_index + 1);
|
||||
m_entry_storage->ReadObject(std::addressof(next_entry), ofs);
|
||||
}
|
||||
const auto offset = impl::GetBucketTreeEntryOffset(0, m_entry_size, entry_index + 1);
|
||||
std::memcpy(std::addressof(next_entry), buffer + offset, m_entry_size);
|
||||
|
||||
next_entry_offset = next_entry.GetVirtualOffset();
|
||||
R_UNLESS(param.offsets.IsInclude(next_entry_offset), ResultInvalidIndirectEntryOffset);
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -9,8 +12,6 @@
|
|||
#include "core/file_sys/fssystem/fs_i_storage.h"
|
||||
#include "core/file_sys/fssystem/fssystem_bucket_tree.h"
|
||||
#include "core/file_sys/fssystem/fssystem_compression_common.h"
|
||||
#include "core/file_sys/fssystem/fssystem_pooled_buffer.h"
|
||||
#include "core/file_sys/vfs/vfs.h"
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
|
@ -317,23 +318,11 @@ private:
|
|||
R_SUCCEED_IF(entry_count == 0);
|
||||
|
||||
// Get the remaining size in a convenient form.
|
||||
const size_t total_required_size =
|
||||
static_cast<size_t>(required_access_physical_size);
|
||||
const size_t total_required_size = size_t(required_access_physical_size);
|
||||
|
||||
// Perform the read based on whether we need to allocate a buffer.
|
||||
if (will_allocate_pooled_buffer) {
|
||||
// Allocate a pooled buffer.
|
||||
PooledBuffer pooled_buffer;
|
||||
if (pooled_buffer.GetAllocatableSizeMax() >= total_required_size) {
|
||||
pooled_buffer.Allocate(total_required_size, m_block_size_max);
|
||||
} else {
|
||||
pooled_buffer.AllocateParticularlyLarge(
|
||||
std::min<size_t>(
|
||||
total_required_size,
|
||||
PooledBuffer::GetAllocatableParticularlyLargeSizeMax()),
|
||||
m_block_size_max);
|
||||
}
|
||||
|
||||
std::vector<char> pooled_buffer(std::max(m_block_size_max, total_required_size));
|
||||
// Read each of the entries.
|
||||
for (s32 entry_idx = 0; entry_idx < entry_count; ++entry_idx) {
|
||||
// Determine the current read size.
|
||||
|
@ -342,13 +331,13 @@ private:
|
|||
if (const size_t target_entry_size =
|
||||
static_cast<size_t>(entries[entry_idx].physical_size) +
|
||||
static_cast<size_t>(entries[entry_idx].gap_from_prev);
|
||||
target_entry_size <= pooled_buffer.GetSize()) {
|
||||
target_entry_size <= pooled_buffer.size()) {
|
||||
// We'll be using the pooled buffer.
|
||||
will_use_pooled_buffer = true;
|
||||
|
||||
// Determine how much we can read.
|
||||
const size_t max_size = std::min<size_t>(
|
||||
required_access_physical_size, pooled_buffer.GetSize());
|
||||
required_access_physical_size, pooled_buffer.size());
|
||||
|
||||
size_t read_size = 0;
|
||||
for (auto n = entry_idx; n < entry_count; ++n) {
|
||||
|
@ -376,7 +365,7 @@ private:
|
|||
// Perform the read based on whether or not we'll use the pooled buffer.
|
||||
if (will_use_pooled_buffer) {
|
||||
// Read the compressed data into the pooled buffer.
|
||||
auto* const buffer = pooled_buffer.GetBuffer();
|
||||
auto* const buffer = pooled_buffer.data();
|
||||
m_data_storage->Read(reinterpret_cast<u8*>(buffer), cur_read_size,
|
||||
required_access_physical_offset);
|
||||
|
||||
|
@ -863,11 +852,9 @@ private:
|
|||
static_cast<size_t>(unaligned_range->virtual_size));
|
||||
|
||||
// Get a pooled buffer for our read.
|
||||
PooledBuffer pooled_buffer;
|
||||
pooled_buffer.Allocate(size_buffer_required, size_buffer_required);
|
||||
|
||||
std::vector<char> pooled_buffer(size_buffer_required);
|
||||
// Perform read.
|
||||
Result rc = read_impl(pooled_buffer.GetBuffer(), size_buffer_required);
|
||||
Result rc = read_impl(pooled_buffer.data(), size_buffer_required);
|
||||
if (R_FAILED(rc)) {
|
||||
R_THROW(rc);
|
||||
}
|
||||
|
@ -876,8 +863,7 @@ private:
|
|||
const size_t skip_size = cur_offset - unaligned_range->virtual_offset;
|
||||
const size_t copy_size = std::min<size_t>(
|
||||
cur_size, unaligned_range->GetEndVirtualOffset() - cur_offset);
|
||||
|
||||
std::memcpy(cur_dst, pooled_buffer.GetBuffer() + skip_size, copy_size);
|
||||
std::memcpy(cur_dst, pooled_buffer.data() + skip_size, copy_size);
|
||||
|
||||
// Advance.
|
||||
cur_dst += copy_size;
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "core/file_sys/fssystem/fssystem_pooled_buffer.h"
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr size_t HeapBlockSize = BufferPoolAlignment;
|
||||
static_assert(HeapBlockSize == 4_KiB);
|
||||
|
||||
// A heap block is 4KiB. An order is a power of two.
|
||||
// This gives blocks of the order 32KiB, 512KiB, 4MiB.
|
||||
constexpr s32 HeapOrderMax = 7;
|
||||
constexpr s32 HeapOrderMaxForLarge = HeapOrderMax + 3;
|
||||
|
||||
constexpr size_t HeapAllocatableSizeMax = HeapBlockSize * (static_cast<size_t>(1) << HeapOrderMax);
|
||||
constexpr size_t HeapAllocatableSizeMaxForLarge =
|
||||
HeapBlockSize * (static_cast<size_t>(1) << HeapOrderMaxForLarge);
|
||||
|
||||
} // namespace
|
||||
|
||||
size_t PooledBuffer::GetAllocatableSizeMaxCore(bool large) {
|
||||
return large ? HeapAllocatableSizeMaxForLarge : HeapAllocatableSizeMax;
|
||||
}
|
||||
|
||||
void PooledBuffer::AllocateCore(size_t ideal_size, size_t required_size, bool large) {
|
||||
// Ensure preconditions.
|
||||
ASSERT(m_buffer == nullptr);
|
||||
|
||||
// Check that we can allocate this size.
|
||||
ASSERT(required_size <= GetAllocatableSizeMaxCore(large));
|
||||
|
||||
const size_t target_size =
|
||||
(std::min)((std::max)(ideal_size, required_size), GetAllocatableSizeMaxCore(large));
|
||||
|
||||
// Dummy implementation for allocate.
|
||||
if (target_size > 0) {
|
||||
m_buffer =
|
||||
reinterpret_cast<char*>(::operator new(target_size, std::align_val_t{HeapBlockSize}));
|
||||
m_size = target_size;
|
||||
|
||||
// Ensure postconditions.
|
||||
ASSERT(m_buffer != nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void PooledBuffer::Shrink(size_t ideal_size) {
|
||||
ASSERT(ideal_size <= GetAllocatableSizeMaxCore(true));
|
||||
|
||||
// Shrinking to zero means that we have no buffer.
|
||||
if (ideal_size == 0) {
|
||||
::operator delete(m_buffer, std::align_val_t{HeapBlockSize});
|
||||
m_buffer = nullptr;
|
||||
m_size = ideal_size;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace FileSys
|
|
@ -1,95 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/literals.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
using namespace Common::Literals;
|
||||
|
||||
constexpr inline size_t BufferPoolAlignment = 4_KiB;
|
||||
constexpr inline size_t BufferPoolWorkSize = 320;
|
||||
|
||||
class PooledBuffer {
|
||||
YUZU_NON_COPYABLE(PooledBuffer);
|
||||
|
||||
public:
|
||||
// Constructor/Destructor.
|
||||
constexpr PooledBuffer() : m_buffer(), m_size() {}
|
||||
|
||||
PooledBuffer(size_t ideal_size, size_t required_size) : m_buffer(), m_size() {
|
||||
this->Allocate(ideal_size, required_size);
|
||||
}
|
||||
|
||||
~PooledBuffer() {
|
||||
this->Deallocate();
|
||||
}
|
||||
|
||||
// Move and assignment.
|
||||
explicit PooledBuffer(PooledBuffer&& rhs) : m_buffer(rhs.m_buffer), m_size(rhs.m_size) {
|
||||
rhs.m_buffer = nullptr;
|
||||
rhs.m_size = 0;
|
||||
}
|
||||
|
||||
PooledBuffer& operator=(PooledBuffer&& rhs) {
|
||||
PooledBuffer(std::move(rhs)).Swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Allocation API.
|
||||
void Allocate(size_t ideal_size, size_t required_size) {
|
||||
return this->AllocateCore(ideal_size, required_size, false);
|
||||
}
|
||||
|
||||
void AllocateParticularlyLarge(size_t ideal_size, size_t required_size) {
|
||||
return this->AllocateCore(ideal_size, required_size, true);
|
||||
}
|
||||
|
||||
void Shrink(size_t ideal_size);
|
||||
|
||||
void Deallocate() {
|
||||
// Shrink the buffer to empty.
|
||||
this->Shrink(0);
|
||||
ASSERT(m_buffer == nullptr);
|
||||
}
|
||||
|
||||
char* GetBuffer() const {
|
||||
ASSERT(m_buffer != nullptr);
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
size_t GetSize() const {
|
||||
ASSERT(m_buffer != nullptr);
|
||||
return m_size;
|
||||
}
|
||||
|
||||
public:
|
||||
static size_t GetAllocatableSizeMax() {
|
||||
return GetAllocatableSizeMaxCore(false);
|
||||
}
|
||||
static size_t GetAllocatableParticularlyLargeSizeMax() {
|
||||
return GetAllocatableSizeMaxCore(true);
|
||||
}
|
||||
|
||||
private:
|
||||
static size_t GetAllocatableSizeMaxCore(bool large);
|
||||
|
||||
private:
|
||||
void Swap(PooledBuffer& rhs) {
|
||||
std::swap(m_buffer, rhs.m_buffer);
|
||||
std::swap(m_size, rhs.m_size);
|
||||
}
|
||||
|
||||
void AllocateCore(size_t ideal_size, size_t required_size, bool large);
|
||||
|
||||
private:
|
||||
char* m_buffer;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
} // namespace FileSys
|
|
@ -53,6 +53,19 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
|
|||
// Set default speed limit to 100%.
|
||||
*out_speed_scale = 1.0f;
|
||||
|
||||
// If no layers are available, skip the logic.
|
||||
bool any_visible = false;
|
||||
for (auto& layer : display.stack.layers) {
|
||||
if (layer->visible) {
|
||||
any_visible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!any_visible) {
|
||||
*out_speed_scale = 1.0f;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Determine the number of vsync periods to wait before composing again.
|
||||
std::optional<s32> swap_interval{};
|
||||
bool has_acquired_buffer{};
|
||||
|
@ -110,7 +123,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
|
|||
}
|
||||
|
||||
// If any new buffers were acquired, we can present.
|
||||
if (has_acquired_buffer) {
|
||||
if (has_acquired_buffer && !composition_stack.empty()) {
|
||||
// Sort by Z-index.
|
||||
std::stable_sort(composition_stack.begin(), composition_stack.end(),
|
||||
[&](auto& l, auto& r) { return l.z_index < r.z_index; });
|
||||
|
@ -119,6 +132,19 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
|
|||
nvdisp.Composite(composition_stack);
|
||||
}
|
||||
|
||||
// Batch framebuffer releases, instead of one-into-one.
|
||||
std::vector<std::pair<Layer*, Framebuffer*>> to_release;
|
||||
for (auto& [layer_id, framebuffer] : m_framebuffers) {
|
||||
if (framebuffer.release_frame_number > m_frame_number || !framebuffer.is_acquired)
|
||||
continue;
|
||||
if (auto layer = display.stack.FindLayer(layer_id); layer)
|
||||
to_release.emplace_back(layer.get(), &framebuffer);
|
||||
}
|
||||
for (auto& [layer, framebuffer] : to_release) {
|
||||
layer->buffer_item_consumer->ReleaseBuffer(framebuffer->item, android::Fence::NoFence());
|
||||
framebuffer->is_acquired = false;
|
||||
}
|
||||
|
||||
// Advance by at least one frame.
|
||||
const u32 frame_advance = swap_interval.value_or(1);
|
||||
m_frame_number += frame_advance;
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2017 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -41,7 +44,14 @@ PerfStats::~PerfStats() {
|
|||
|
||||
const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::LogDir);
|
||||
// %F Date format expanded is "%Y-%m-%d"
|
||||
const auto filename = fmt::format("{:%F-%H-%M}_{:016X}.csv", *std::localtime(&t), title_id);
|
||||
const auto filename = fmt::format("{}_{:016X}.csv",
|
||||
[&] {
|
||||
std::ostringstream oss;
|
||||
oss << std::put_time(std::localtime(&t), "%F-%H-%M");
|
||||
return oss.str();
|
||||
}(),
|
||||
title_id);
|
||||
|
||||
const auto filepath = path / filename;
|
||||
|
||||
if (Common::FS::CreateParentDir(filepath)) {
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -33,7 +36,9 @@ std::filesystem::path GetPath(std::string_view type, u64 title_id, std::string_v
|
|||
|
||||
std::string GetTimestamp() {
|
||||
const auto time = std::time(nullptr);
|
||||
return fmt::format("{:%FT%H-%M-%S}", *std::localtime(&time));
|
||||
std::ostringstream oss;
|
||||
oss << std::put_time(std::localtime(&time), "%FT%H-%M-%S");
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
using namespace nlohmann;
|
||||
|
|
|
@ -246,10 +246,7 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
|
|||
INSERT(Settings,
|
||||
vram_usage_mode,
|
||||
tr("VRAM Usage Mode:"),
|
||||
tr("Selects whether the emulator should prefer to conserve memory or make maximum usage "
|
||||
"of available video memory for performance.\nHas no effect on integrated graphics. "
|
||||
"Aggressive mode may severely impact the performance of other applications such as "
|
||||
"recording software."));
|
||||
tr("Selects whether the emulator should prefer to conserve memory or make maximum usage of available video memory for performance.\nAggressive mode may severely impact the performance of other applications such as recording software."));
|
||||
INSERT(Settings,
|
||||
skip_cpu_inner_invalidation,
|
||||
tr("Skip CPU Inner Invalidation"),
|
||||
|
|
|
@ -470,8 +470,8 @@ void PresentManager::CopyToSwapchainImpl(Frame* frame) {
|
|||
const std::array wait_semaphores = {present_semaphore, *frame->render_ready};
|
||||
|
||||
static constexpr std::array<VkPipelineStageFlags, 2> wait_stage_masks{
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
};
|
||||
|
||||
const VkSubmitInfo submit_info{
|
||||
|
|
|
@ -1395,23 +1395,20 @@ void Device::CollectPhysicalMemoryInfo() {
|
|||
}
|
||||
device_access_memory += mem_properties.memoryHeaps[element].size;
|
||||
}
|
||||
if (!is_integrated) {
|
||||
if (is_integrated) {
|
||||
const s64 available_memory = static_cast<s64>(device_access_memory - device_initial_usage);
|
||||
const u64 memory_size = Settings::values.vram_usage_mode.GetValue() == Settings::VramUsageMode::Aggressive ? 6_GiB : 4_GiB;
|
||||
device_access_memory = static_cast<u64>(std::max<s64>(std::min<s64>(available_memory - 8_GiB, memory_size), std::min<s64>(local_memory, memory_size)));
|
||||
} else {
|
||||
const u64 reserve_memory = std::min<u64>(device_access_memory / 8, 1_GiB);
|
||||
device_access_memory -= reserve_memory;
|
||||
|
||||
if (Settings::values.vram_usage_mode.GetValue() != Settings::VramUsageMode::Aggressive) {
|
||||
// Account for resolution scaling in memory limits
|
||||
const size_t normal_memory = 6_GiB;
|
||||
const size_t scaler_memory = 1_GiB * Settings::values.resolution_info.ScaleUp(1);
|
||||
device_access_memory =
|
||||
std::min<u64>(device_access_memory, normal_memory + scaler_memory);
|
||||
device_access_memory = std::min<u64>(device_access_memory, normal_memory + scaler_memory);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
const s64 available_memory = static_cast<s64>(device_access_memory - device_initial_usage);
|
||||
device_access_memory = static_cast<u64>(std::max<s64>(
|
||||
std::min<s64>(available_memory - 8_GiB, 6_GiB), std::min<s64>(local_memory, 6_GiB)));
|
||||
}
|
||||
|
||||
void Device::CollectToolingInfo() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue