mirror of https://git.suyu.dev/suyu/suyu
Merge remote-tracking branch 'origin/master' into ssl
commit
98685d48e3
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1 +1 @@
|
|||||||
Subproject commit f17058b562c8a1090c0c996b42982721ace90903
|
Subproject commit 491fba1d06a4810645092b2559b9cc94abeb23bb
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,43 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace bcn {
|
||||||
|
/**
|
||||||
|
* @brief Decodes a BC1 encoded image to R8G8B8A8
|
||||||
|
*/
|
||||||
|
void DecodeBc1(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decodes a BC2 encoded image to R8G8B8A8
|
||||||
|
*/
|
||||||
|
void DecodeBc2(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decodes a BC3 encoded image to R8G8B8A8
|
||||||
|
*/
|
||||||
|
void DecodeBc3(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decodes a BC4 encoded image to R8
|
||||||
|
*/
|
||||||
|
void DecodeBc4(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height, bool isSigned);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decodes a BC5 encoded image to R8G8
|
||||||
|
*/
|
||||||
|
void DecodeBc5(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height, bool isSigned);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decodes a BC6 encoded image to R16G16B16A16
|
||||||
|
*/
|
||||||
|
void DecodeBc6(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height, bool isSigned);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decodes a BC7 encoded image to R8G8B8A8
|
||||||
|
*/
|
||||||
|
void DecodeBc7(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height);
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
Subproject commit 34df65eff295c2bd9ee9e6a077d662486d5cabb3
|
Subproject commit 212afa2394a74226dcf1b7996a570aae17debb69
|
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 0aa3989b8f382f185fdf646cc83a1d16fa31d6ab
|
@ -0,0 +1,8 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#define VMA_IMPLEMENTATION
|
||||||
|
#define VMA_STATIC_VULKAN_FUNCTIONS 0
|
||||||
|
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
|
||||||
|
|
||||||
|
#include <vk_mem_alloc.h>
|
@ -0,0 +1,62 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.fragments
|
||||||
|
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import org.yuzu.yuzu_emu.R
|
||||||
|
|
||||||
|
class LongMessageDialogFragment : DialogFragment() {
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
val titleId = requireArguments().getInt(TITLE)
|
||||||
|
val description = requireArguments().getString(DESCRIPTION)
|
||||||
|
val helpLinkId = requireArguments().getInt(HELP_LINK)
|
||||||
|
|
||||||
|
val dialog = MaterialAlertDialogBuilder(requireContext())
|
||||||
|
.setPositiveButton(R.string.close, null)
|
||||||
|
.setTitle(titleId)
|
||||||
|
.setMessage(description)
|
||||||
|
|
||||||
|
if (helpLinkId != 0) {
|
||||||
|
dialog.setNeutralButton(R.string.learn_more) { _, _ ->
|
||||||
|
openLink(getString(helpLinkId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openLink(link: String) {
|
||||||
|
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(link))
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TAG = "LongMessageDialogFragment"
|
||||||
|
|
||||||
|
private const val TITLE = "Title"
|
||||||
|
private const val DESCRIPTION = "Description"
|
||||||
|
private const val HELP_LINK = "Link"
|
||||||
|
|
||||||
|
fun newInstance(
|
||||||
|
titleId: Int,
|
||||||
|
description: String,
|
||||||
|
helpLinkId: Int = 0
|
||||||
|
): LongMessageDialogFragment {
|
||||||
|
val dialog = LongMessageDialogFragment()
|
||||||
|
val bundle = Bundle()
|
||||||
|
bundle.apply {
|
||||||
|
putInt(TITLE, titleId)
|
||||||
|
putString(DESCRIPTION, description)
|
||||||
|
putInt(HELP_LINK, helpLinkId)
|
||||||
|
}
|
||||||
|
dialog.arguments = bundle
|
||||||
|
return dialog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -1,165 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
|
|
||||||
// Function calls from the Java side
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_UnPauseEmulation(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_PauseEmulation(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_StopEmulation(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_ResetRomMetadata(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_IsRunning(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_isHandheldOnly(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_setDeviceType(JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
jstring j_device,
|
|
||||||
jstring j_type);
|
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadConnectEvent(
|
|
||||||
JNIEnv* env, jclass clazz, jstring j_device);
|
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadDisconnectEvent(
|
|
||||||
JNIEnv* env, jclass clazz, jstring j_device);
|
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadEvent(
|
|
||||||
JNIEnv* env, jclass clazz, jstring j_device, jint j_button, jint action);
|
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadMoveEvent(
|
|
||||||
JNIEnv* env, jclass clazz, jstring j_device, jint axis, jfloat x, jfloat y);
|
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadAxisEvent(
|
|
||||||
JNIEnv* env, jclass clazz, jstring j_device, jint axis_id, jfloat axis_val);
|
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_onReadNfcTag(JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
jbyteArray j_data);
|
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_onRemoveNfcTag(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchEvent(JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
jfloat x, jfloat y,
|
|
||||||
jboolean pressed);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchMoved(JNIEnv* env, jclass clazz,
|
|
||||||
jfloat x, jfloat y);
|
|
||||||
|
|
||||||
JNIEXPORT jbyteArray JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_GetIcon(JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
jstring j_file);
|
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_GetTitle(JNIEnv* env, jclass clazz,
|
|
||||||
jstring j_filename);
|
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_GetDescription(JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
jstring j_filename);
|
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_GetGameId(JNIEnv* env, jclass clazz,
|
|
||||||
jstring j_filename);
|
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_GetRegions(JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
jstring j_filename);
|
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_GetCompany(JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
jstring j_filename);
|
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_GetGitRevision(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_SetAppDirectory(JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
jstring j_directory);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_org_yuzu_yuzu_1emu_NativeLibrary_Java_org_yuzu_yuzu_1emu_NativeLibrary_InitializeGpuDriver(
|
|
||||||
JNIEnv* env, jclass clazz, jstring hook_lib_dir, jstring custom_driver_dir,
|
|
||||||
jstring custom_driver_name, jstring file_redirect_dir);
|
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadKeys(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_utils_DirectoryInitialization_SetSysDirectory(
|
|
||||||
JNIEnv* env, jclass clazz, jstring path_);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_SetSysDirectory(JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
jstring path);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_InitializeEmulation(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_DefaultCPUCore(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_SetProfiling(JNIEnv* env, jclass clazz,
|
|
||||||
jboolean enable);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_WriteProfileResults(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_NotifyOrientationChange(
|
|
||||||
JNIEnv* env, jclass clazz, jint layout_option, jint rotation);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_Run__Ljava_lang_String_2(
|
|
||||||
JNIEnv* env, jclass clazz, jstring j_path);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_org_yuzu_yuzu_1emu_NativeLibrary_Run__Ljava_lang_String_2Ljava_lang_String_2Z(
|
|
||||||
JNIEnv* env, jclass clazz, jstring j_file, jstring j_savestate, jboolean j_delete_savestate);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_SurfaceChanged(JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
jobject surf);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_SurfaceDestroyed(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_InitGameIni(JNIEnv* env, jclass clazz,
|
|
||||||
jstring j_game_id);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadSettings(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_SetUserSetting(
|
|
||||||
JNIEnv* env, jclass clazz, jstring j_game_id, jstring j_section, jstring j_key,
|
|
||||||
jstring j_value);
|
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_GetUserSetting(
|
|
||||||
JNIEnv* env, jclass clazz, jstring game_id, jstring section, jstring key);
|
|
||||||
|
|
||||||
JNIEXPORT jdoubleArray JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_GetPerfStats(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_LogDeviceInfo(JNIEnv* env,
|
|
||||||
jclass clazz);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_SubmitInlineKeyboardText(
|
|
||||||
JNIEnv* env, jclass clazz, jstring j_text);
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_SubmitInlineKeyboardInput(
|
|
||||||
JNIEnv* env, jclass clazz, jint j_key_code);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:viewportWidth="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M7,9v6h4l5,5V4l-5,5H7z" />
|
||||||
|
</vector>
|
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:viewportWidth="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z" />
|
||||||
|
</vector>
|
@ -1,164 +1,50 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <chrono>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#include "common/atomic_ops.h"
|
|
||||||
#include "common/steady_clock.h"
|
|
||||||
#include "common/uint128.h"
|
#include "common/uint128.h"
|
||||||
#include "common/x64/native_clock.h"
|
#include "common/x64/native_clock.h"
|
||||||
|
#include "common/x64/rdtsc.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
namespace Common::X64 {
|
||||||
#include <intrin.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Common {
|
NativeClock::NativeClock(u64 rdtsc_frequency_)
|
||||||
|
: start_ticks{FencedRDTSC()}, rdtsc_frequency{rdtsc_frequency_},
|
||||||
|
ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den, rdtsc_frequency)},
|
||||||
|
us_rdtsc_factor{GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency)},
|
||||||
|
ms_rdtsc_factor{GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency)},
|
||||||
|
cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency)},
|
||||||
|
gputick_rdtsc_factor{GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency)} {}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
std::chrono::nanoseconds NativeClock::GetTimeNS() const {
|
||||||
__forceinline static u64 FencedRDTSC() {
|
return std::chrono::nanoseconds{MultiplyHigh(GetHostTicksElapsed(), ns_rdtsc_factor)};
|
||||||
_mm_lfence();
|
|
||||||
_ReadWriteBarrier();
|
|
||||||
const u64 result = __rdtsc();
|
|
||||||
_mm_lfence();
|
|
||||||
_ReadWriteBarrier();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static u64 FencedRDTSC() {
|
|
||||||
u64 eax;
|
|
||||||
u64 edx;
|
|
||||||
asm volatile("lfence\n\t"
|
|
||||||
"rdtsc\n\t"
|
|
||||||
"lfence\n\t"
|
|
||||||
: "=a"(eax), "=d"(edx));
|
|
||||||
return (edx << 32) | eax;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <u64 Nearest>
|
|
||||||
static u64 RoundToNearest(u64 value) {
|
|
||||||
const auto mod = value % Nearest;
|
|
||||||
return mod >= (Nearest / 2) ? (value - mod + Nearest) : (value - mod);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 EstimateRDTSCFrequency() {
|
std::chrono::microseconds NativeClock::GetTimeUS() const {
|
||||||
// Discard the first result measuring the rdtsc.
|
return std::chrono::microseconds{MultiplyHigh(GetHostTicksElapsed(), us_rdtsc_factor)};
|
||||||
FencedRDTSC();
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds{1});
|
|
||||||
FencedRDTSC();
|
|
||||||
|
|
||||||
// Get the current time.
|
|
||||||
const auto start_time = Common::RealTimeClock::Now();
|
|
||||||
const u64 tsc_start = FencedRDTSC();
|
|
||||||
// Wait for 250 milliseconds.
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds{250});
|
|
||||||
const auto end_time = Common::RealTimeClock::Now();
|
|
||||||
const u64 tsc_end = FencedRDTSC();
|
|
||||||
// Calculate differences.
|
|
||||||
const u64 timer_diff = static_cast<u64>(
|
|
||||||
std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count());
|
|
||||||
const u64 tsc_diff = tsc_end - tsc_start;
|
|
||||||
const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff);
|
|
||||||
return RoundToNearest<1000>(tsc_freq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace X64 {
|
std::chrono::milliseconds NativeClock::GetTimeMS() const {
|
||||||
NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_,
|
return std::chrono::milliseconds{MultiplyHigh(GetHostTicksElapsed(), ms_rdtsc_factor)};
|
||||||
u64 rtsc_frequency_)
|
|
||||||
: WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{
|
|
||||||
rtsc_frequency_} {
|
|
||||||
// Thread to re-adjust the RDTSC frequency after 10 seconds has elapsed.
|
|
||||||
time_sync_thread = std::jthread{[this](std::stop_token token) {
|
|
||||||
// Get the current time.
|
|
||||||
const auto start_time = Common::RealTimeClock::Now();
|
|
||||||
const u64 tsc_start = FencedRDTSC();
|
|
||||||
// Wait for 10 seconds.
|
|
||||||
if (!Common::StoppableTimedWait(token, std::chrono::seconds{10})) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto end_time = Common::RealTimeClock::Now();
|
|
||||||
const u64 tsc_end = FencedRDTSC();
|
|
||||||
// Calculate differences.
|
|
||||||
const u64 timer_diff = static_cast<u64>(
|
|
||||||
std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count());
|
|
||||||
const u64 tsc_diff = tsc_end - tsc_start;
|
|
||||||
const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff);
|
|
||||||
rtsc_frequency = tsc_freq;
|
|
||||||
CalculateAndSetFactors();
|
|
||||||
}};
|
|
||||||
|
|
||||||
time_point.inner.last_measure = FencedRDTSC();
|
|
||||||
time_point.inner.accumulated_ticks = 0U;
|
|
||||||
CalculateAndSetFactors();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NativeClock::GetRTSC() {
|
u64 NativeClock::GetCNTPCT() const {
|
||||||
TimePoint new_time_point{};
|
return MultiplyHigh(GetHostTicksElapsed(), cntpct_rdtsc_factor);
|
||||||
TimePoint current_time_point{};
|
|
||||||
|
|
||||||
current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
|
|
||||||
do {
|
|
||||||
const u64 current_measure = FencedRDTSC();
|
|
||||||
u64 diff = current_measure - current_time_point.inner.last_measure;
|
|
||||||
diff = diff & ~static_cast<u64>(static_cast<s64>(diff) >> 63); // max(diff, 0)
|
|
||||||
new_time_point.inner.last_measure = current_measure > current_time_point.inner.last_measure
|
|
||||||
? current_measure
|
|
||||||
: current_time_point.inner.last_measure;
|
|
||||||
new_time_point.inner.accumulated_ticks = current_time_point.inner.accumulated_ticks + diff;
|
|
||||||
} while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack,
|
|
||||||
current_time_point.pack, current_time_point.pack));
|
|
||||||
return new_time_point.inner.accumulated_ticks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeClock::Pause(bool is_paused) {
|
u64 NativeClock::GetGPUTick() const {
|
||||||
if (!is_paused) {
|
return MultiplyHigh(GetHostTicksElapsed(), gputick_rdtsc_factor);
|
||||||
TimePoint current_time_point{};
|
|
||||||
TimePoint new_time_point{};
|
|
||||||
|
|
||||||
current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
|
|
||||||
do {
|
|
||||||
new_time_point.pack = current_time_point.pack;
|
|
||||||
new_time_point.inner.last_measure = FencedRDTSC();
|
|
||||||
} while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack,
|
|
||||||
current_time_point.pack, current_time_point.pack));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::nanoseconds NativeClock::GetTimeNS() {
|
u64 NativeClock::GetHostTicksNow() const {
|
||||||
const u64 rtsc_value = GetRTSC();
|
return FencedRDTSC();
|
||||||
return std::chrono::nanoseconds{MultiplyHigh(rtsc_value, ns_rtsc_factor)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::microseconds NativeClock::GetTimeUS() {
|
u64 NativeClock::GetHostTicksElapsed() const {
|
||||||
const u64 rtsc_value = GetRTSC();
|
return FencedRDTSC() - start_ticks;
|
||||||
return std::chrono::microseconds{MultiplyHigh(rtsc_value, us_rtsc_factor)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::milliseconds NativeClock::GetTimeMS() {
|
bool NativeClock::IsNative() const {
|
||||||
const u64 rtsc_value = GetRTSC();
|
return true;
|
||||||
return std::chrono::milliseconds{MultiplyHigh(rtsc_value, ms_rtsc_factor)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NativeClock::GetClockCycles() {
|
} // namespace Common::X64
|
||||||
const u64 rtsc_value = GetRTSC();
|
|
||||||
return MultiplyHigh(rtsc_value, clock_rtsc_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 NativeClock::GetCPUCycles() {
|
|
||||||
const u64 rtsc_value = GetRTSC();
|
|
||||||
return MultiplyHigh(rtsc_value, cpu_rtsc_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NativeClock::CalculateAndSetFactors() {
|
|
||||||
ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency);
|
|
||||||
us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency);
|
|
||||||
ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency);
|
|
||||||
clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency);
|
|
||||||
cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace X64
|
|
||||||
|
|
||||||
} // namespace Common
|
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "common/steady_clock.h"
|
||||||
|
#include "common/uint128.h"
|
||||||
|
#include "common/x64/rdtsc.h"
|
||||||
|
|
||||||
|
namespace Common::X64 {
|
||||||
|
|
||||||
|
template <u64 Nearest>
|
||||||
|
static u64 RoundToNearest(u64 value) {
|
||||||
|
const auto mod = value % Nearest;
|
||||||
|
return mod >= (Nearest / 2) ? (value - mod + Nearest) : (value - mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 EstimateRDTSCFrequency() {
|
||||||
|
// Discard the first result measuring the rdtsc.
|
||||||
|
FencedRDTSC();
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds{1});
|
||||||
|
FencedRDTSC();
|
||||||
|
|
||||||
|
// Get the current time.
|
||||||
|
const auto start_time = RealTimeClock::Now();
|
||||||
|
const u64 tsc_start = FencedRDTSC();
|
||||||
|
// Wait for 100 milliseconds.
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds{100});
|
||||||
|
const auto end_time = RealTimeClock::Now();
|
||||||
|
const u64 tsc_end = FencedRDTSC();
|
||||||
|
// Calculate differences.
|
||||||
|
const u64 timer_diff = static_cast<u64>(
|
||||||
|
std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count());
|
||||||
|
const u64 tsc_diff = tsc_end - tsc_start;
|
||||||
|
const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff);
|
||||||
|
return RoundToNearest<100'000>(tsc_freq);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Common::X64
|
@ -0,0 +1,37 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <intrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
namespace Common::X64 {
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
__forceinline static u64 FencedRDTSC() {
|
||||||
|
_mm_lfence();
|
||||||
|
_ReadWriteBarrier();
|
||||||
|
const u64 result = __rdtsc();
|
||||||
|
_mm_lfence();
|
||||||
|
_ReadWriteBarrier();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline u64 FencedRDTSC() {
|
||||||
|
u64 eax;
|
||||||
|
u64 edx;
|
||||||
|
asm volatile("lfence\n\t"
|
||||||
|
"rdtsc\n\t"
|
||||||
|
"lfence\n\t"
|
||||||
|
: "=a"(eax), "=d"(edx));
|
||||||
|
return (edx << 32) | eax;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
u64 EstimateRDTSCFrequency();
|
||||||
|
|
||||||
|
} // namespace Common::X64
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue