diff --git a/README.md b/README.md index cb038d27f..4aac845c9 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 3704. +This is the source code for early-access 3705. ## Legal Notice diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt index f0a6753a9..b1771b424 100755 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt @@ -27,13 +27,13 @@ import android.view.MotionEvent import android.view.Surface import android.view.View import android.view.inputmethod.InputMethodManager +import android.widget.Toast import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsControllerCompat import androidx.navigation.fragment.NavHostFragment -import kotlin.math.roundToInt import org.yuzu.yuzu_emu.NativeLibrary import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.databinding.ActivityEmulationBinding @@ -44,8 +44,10 @@ import org.yuzu.yuzu_emu.model.Game import org.yuzu.yuzu_emu.utils.ControllerMappingHelper import org.yuzu.yuzu_emu.utils.ForegroundService import org.yuzu.yuzu_emu.utils.InputHandler +import org.yuzu.yuzu_emu.utils.MemoryUtil import org.yuzu.yuzu_emu.utils.NfcReader import org.yuzu.yuzu_emu.utils.ThemeHelper +import kotlin.math.roundToInt class EmulationActivity : AppCompatActivity(), SensorEventListener { private lateinit var binding: ActivityEmulationBinding @@ -102,6 +104,19 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { inputHandler = InputHandler() inputHandler.initialize() + val memoryUtil = MemoryUtil(this) + if (memoryUtil.isLessThan(8, MemoryUtil.Gb)) { + Toast.makeText( + this, + getString( + R.string.device_memory_inadequate, + memoryUtil.getDeviceRAM(), + "8 ${getString(R.string.memory_gigabyte)}" + ), + Toast.LENGTH_LONG + ).show() + } + // Start a foreground service to prevent the app from getting killed in the background val startIntent = Intent(this, ForegroundService::class.java) startForegroundService(startIntent) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt new file mode 100755 index 000000000..18e5fa0b0 --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.yuzu.yuzu_emu.utils + +import android.app.ActivityManager +import android.content.Context +import org.yuzu.yuzu_emu.R +import java.util.Locale + +class MemoryUtil(val context: Context) { + + private val Long.floatForm: String + get() = String.format(Locale.ROOT, "%.2f", this.toDouble()) + + private fun bytesToSizeUnit(size: Long): String { + return when { + size < Kb -> "${size.floatForm} ${context.getString(R.string.memory_byte)}" + size < Mb -> "${(size / Kb).floatForm} ${context.getString(R.string.memory_kilobyte)}" + size < Gb -> "${(size / Mb).floatForm} ${context.getString(R.string.memory_megabyte)}" + size < Tb -> "${(size / Gb).floatForm} ${context.getString(R.string.memory_gigabyte)}" + size < Pb -> "${(size / Tb).floatForm} ${context.getString(R.string.memory_terabyte)}" + size < Eb -> "${(size / Pb).floatForm} ${context.getString(R.string.memory_petabyte)}" + else -> "${(size / Eb).floatForm} ${context.getString(R.string.memory_exabyte)}" + } + } + + private val totalMemory = + with(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager) { + val memInfo = ActivityManager.MemoryInfo() + getMemoryInfo(memInfo) + memInfo.totalMem + } + + fun isLessThan(minimum: Int, size: Long): Boolean { + return when (size) { + Kb -> totalMemory < Mb && totalMemory < minimum + Mb -> totalMemory < Gb && (totalMemory / Mb) < minimum + Gb -> totalMemory < Tb && (totalMemory / Gb) < minimum + Tb -> totalMemory < Pb && (totalMemory / Tb) < minimum + Pb -> totalMemory < Eb && (totalMemory / Pb) < minimum + Eb -> totalMemory / Eb < minimum + else -> totalMemory < Kb && totalMemory < minimum + } + } + + fun getDeviceRAM(): String { + return bytesToSizeUnit(totalMemory) + } + + companion object { + const val Kb: Long = 1024 + const val Mb = Kb * 1024 + const val Gb = Mb * 1024 + const val Tb = Gb * 1024 + const val Pb = Tb * 1024 + const val Eb = Pb * 1024 + } +} diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 632aa50b3..f4fed0886 100755 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -237,6 +237,7 @@ public: m_software_keyboard = android_keyboard.get(); m_system.SetShuttingDown(false); m_system.ApplySettings(); + Settings::LogSettings(); m_system.HIDCore().ReloadInputDevices(); m_system.SetAppletFrontendSet({ nullptr, // Amiibo Settings diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index cc1d8c39d..85fc682f2 100755 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -270,6 +270,7 @@ Fatal Error A fatal error occurred. Check the log for details.\nContinuing emulation may result in crashes and bugs. Turning off this setting will significantly reduce emulation performance! For the best experience, it is recommended that you leave this setting enabled. + Device RAM: %1$s\nRecommended: %2$s Japan @@ -300,6 +301,15 @@ Traditional Chinese (正體中文) Brazilian Portuguese (Português do Brasil) + + Byte + KB + MB + GB + TB + PB + EB + Vulkan None diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index 378740f73..d9f0db4a5 100755 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -59,20 +59,6 @@ struct Range { return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; } -[[nodiscard]] VkMemoryPropertyFlags MemoryUsageRequiredVmaFlags(MemoryUsage usage) { - switch (usage) { - case MemoryUsage::DeviceLocal: - return VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - case MemoryUsage::Upload: - case MemoryUsage::Stream: - return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - case MemoryUsage::Download: - return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; - } - ASSERT_MSG(false, "Invalid memory usage={}", usage); - return {}; -} - [[nodiscard]] VkMemoryPropertyFlags MemoryUsagePreferedVmaFlags(MemoryUsage usage) { return usage != MemoryUsage::DeviceLocal ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VkMemoryPropertyFlagBits{}; @@ -259,7 +245,7 @@ vk::Buffer MemoryAllocator::CreateBuffer(const VkBufferCreateInfo& ci, MemoryUsa .flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT | MemoryUsageVmaFlags(usage), .usage = MemoryUsageVma(usage), - .requiredFlags = MemoryUsageRequiredVmaFlags(usage), + .requiredFlags = 0, .preferredFlags = MemoryUsagePreferedVmaFlags(usage), .memoryTypeBits = 0, .pool = VK_NULL_HANDLE,