diff --git a/CMakeLists.txt b/CMakeLists.txt index 6afa37e9de..8ca2131927 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -806,7 +806,6 @@ add_library(Common STATIC Common/Input/KeyCodes.h Common/Input/InputState.cpp Common/Input/InputState.h - Common/Math/fast/fast_matrix.c Common/Math/SIMDHeaders.h Common/Math/SIMDHeaders.h Common/Math/curves.cpp diff --git a/Common/Common.h b/Common/Common.h index b924226e68..00646d57bd 100644 --- a/Common/Common.h +++ b/Common/Common.h @@ -90,3 +90,12 @@ // Easy way to printf string_views (note: The formatting specifier is "%.*s", not "%s") #define STR_VIEW(sv) (int)(sv).size(), (sv).data() + +// Restrict qualifier +#if defined(_MSC_VER) +#define RESTRICT __restrict +#elif defined(__GNUC__) || defined(__clang__) +#define RESTRICT __restrict__ +#else +#define RESTRICT +#endif diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 1e193e172a..a7e6188d4f 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -918,7 +918,6 @@ - diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 1dd44daa52..094913347f 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -861,9 +861,6 @@ Math\lin - - Math\fast - Data\Format diff --git a/Common/Math/CrossSIMD.h b/Common/Math/CrossSIMD.h index 3c62e449f6..9376936fe1 100644 --- a/Common/Math/CrossSIMD.h +++ b/Common/Math/CrossSIMD.h @@ -198,7 +198,7 @@ struct Vec4F32 { return Vec4F32 { _mm_mul_ps(_mm_cvtepi32_ps(value32), _mm_set1_ps(1.0f / 128.0f)) }; } static Vec4F32 LoadS16Norm(const int16_t *src) { // Divides by 32768.0f - __m128i bits = _mm_castpd_si128(_mm_load_sd((const double *)src)); + __m128i bits = _mm_loadl_epi64((const __m128i*)src); // Sign extension. A bit ugly without SSE4. bits = _mm_srai_epi32(_mm_unpacklo_epi16(bits, bits), 16); return Vec4F32 { _mm_mul_ps(_mm_cvtepi32_ps(bits), _mm_set1_ps(1.0f / 32768.0f)) }; diff --git a/Common/Math/fast/fast_matrix.c b/Common/Math/fast/fast_matrix.c deleted file mode 100644 index 6ce87e2a6a..0000000000 --- a/Common/Math/fast/fast_matrix.c +++ /dev/null @@ -1,159 +0,0 @@ -#include "ppsspp_config.h" - -#include "Common/Math/SIMDHeaders.h" - -#include "fast_matrix.h" - -#if PPSSPP_ARCH(SSE2) - -void fast_matrix_mul_4x4_sse(float *dest, const float *a, const float *b) { - int i; - __m128 a_col_1 = _mm_loadu_ps(a); - __m128 a_col_2 = _mm_loadu_ps(&a[4]); - __m128 a_col_3 = _mm_loadu_ps(&a[8]); - __m128 a_col_4 = _mm_loadu_ps(&a[12]); - - for (i = 0; i < 16; i += 4) { - __m128 r_col = _mm_mul_ps(a_col_1, _mm_set1_ps(b[i])); - r_col = _mm_add_ps(r_col, _mm_mul_ps(a_col_2, _mm_set1_ps(b[i + 1]))); - r_col = _mm_add_ps(r_col, _mm_mul_ps(a_col_3, _mm_set1_ps(b[i + 2]))); - r_col = _mm_add_ps(r_col, _mm_mul_ps(a_col_4, _mm_set1_ps(b[i + 3]))); - _mm_storeu_ps(&dest[i], r_col); - } -} - -#elif PPSSPP_ARCH(LOONGARCH64_LSX) - -typedef union -{ - int32_t i; - float f; -} FloatInt; - -static __m128 __lsx_vreplfr2vr_s(float val) -{ - FloatInt tmpval = {.f = val}; - return (__m128)__lsx_vreplgr2vr_w(tmpval.i); -} - -void fast_matrix_mul_4x4_lsx(float *dest, const float *a, const float *b) { - __m128 a_col_1 = (__m128)__lsx_vld(a, 0); - __m128 a_col_2 = (__m128)__lsx_vld(a + 4, 0); - __m128 a_col_3 = (__m128)__lsx_vld(a + 8, 0); - __m128 a_col_4 = (__m128)__lsx_vld(a + 12, 0); - - for (int i = 0; i < 16; i += 4) { - - __m128 b1 = __lsx_vreplfr2vr_s(b[i]); - __m128 b2 = __lsx_vreplfr2vr_s(b[i + 1]); - __m128 b3 = __lsx_vreplfr2vr_s(b[i + 2]); - __m128 b4 = __lsx_vreplfr2vr_s(b[i + 3]); - - __m128 result = __lsx_vfmul_s(a_col_1, b1); - result = __lsx_vfmadd_s(a_col_2, b2, result); - result = __lsx_vfmadd_s(a_col_3, b3, result); - result = __lsx_vfmadd_s(a_col_4, b4, result); - - __lsx_vst(result, &dest[i], 0); - } -} - -#elif PPSSPP_ARCH(ARM_NEON) - -// From https://developer.arm.com/documentation/102467/0100/Matrix-multiplication-example -void fast_matrix_mul_4x4_neon(float *C, const float *A, const float *B) { - // these are the columns A - float32x4_t A0; - float32x4_t A1; - float32x4_t A2; - float32x4_t A3; - - // these are the columns B - float32x4_t B0; - float32x4_t B1; - float32x4_t B2; - float32x4_t B3; - - // these are the columns C - float32x4_t C0; - float32x4_t C1; - float32x4_t C2; - float32x4_t C3; - - A0 = vld1q_f32(A); - A1 = vld1q_f32(A + 4); - A2 = vld1q_f32(A + 8); - A3 = vld1q_f32(A + 12); - - // Multiply accumulate in 4x1 blocks, i.e. each column in C - B0 = vld1q_f32(B); - C0 = vmulq_laneq_f32(A0, B0, 0); - C0 = vfmaq_laneq_f32(C0, A1, B0, 1); - C0 = vfmaq_laneq_f32(C0, A2, B0, 2); - C0 = vfmaq_laneq_f32(C0, A3, B0, 3); - vst1q_f32(C, C0); - - B1 = vld1q_f32(B + 4); - C1 = vmulq_laneq_f32(A0, B1, 0); - C1 = vfmaq_laneq_f32(C1, A1, B1, 1); - C1 = vfmaq_laneq_f32(C1, A2, B1, 2); - C1 = vfmaq_laneq_f32(C1, A3, B1, 3); - vst1q_f32(C + 4, C1); - - B2 = vld1q_f32(B + 8); - C2 = vmulq_laneq_f32(A0, B2, 0); - C2 = vfmaq_laneq_f32(C2, A1, B2, 1); - C2 = vfmaq_laneq_f32(C2, A2, B2, 2); - C2 = vfmaq_laneq_f32(C2, A3, B2, 3); - vst1q_f32(C + 8, C2); - - B3 = vld1q_f32(B + 12); - C3 = vmulq_laneq_f32(A0, B3, 0); - C3 = vfmaq_laneq_f32(C3, A1, B3, 1); - C3 = vfmaq_laneq_f32(C3, A2, B3, 2); - C3 = vfmaq_laneq_f32(C3, A3, B3, 3); - vst1q_f32(C + 12, C3); -} - -#else - -#define xx 0 -#define xy 1 -#define xz 2 -#define xw 3 -#define yx 4 -#define yy 5 -#define yz 6 -#define yw 7 -#define zx 8 -#define zy 9 -#define zz 10 -#define zw 11 -#define wx 12 -#define wy 13 -#define wz 14 -#define ww 15 - -void fast_matrix_mul_4x4_c(float *dest, const float *a, const float *b) { - dest[xx] = b[xx] * a[xx] + b[xy] * a[yx] + b[xz] * a[zx] + b[xw] * a[wx]; - dest[xy] = b[xx] * a[xy] + b[xy] * a[yy] + b[xz] * a[zy] + b[xw] * a[wy]; - dest[xz] = b[xx] * a[xz] + b[xy] * a[yz] + b[xz] * a[zz] + b[xw] * a[wz]; - dest[xw] = b[xx] * a[xw] + b[xy] * a[yw] + b[xz] * a[zw] + b[xw] * a[ww]; - - dest[yx] = b[yx] * a[xx] + b[yy] * a[yx] + b[yz] * a[zx] + b[yw] * a[wx]; - dest[yy] = b[yx] * a[xy] + b[yy] * a[yy] + b[yz] * a[zy] + b[yw] * a[wy]; - dest[yz] = b[yx] * a[xz] + b[yy] * a[yz] + b[yz] * a[zz] + b[yw] * a[wz]; - dest[yw] = b[yx] * a[xw] + b[yy] * a[yw] + b[yz] * a[zw] + b[yw] * a[ww]; - - dest[zx] = b[zx] * a[xx] + b[zy] * a[yx] + b[zz] * a[zx] + b[zw] * a[wx]; - dest[zy] = b[zx] * a[xy] + b[zy] * a[yy] + b[zz] * a[zy] + b[zw] * a[wy]; - dest[zz] = b[zx] * a[xz] + b[zy] * a[yz] + b[zz] * a[zz] + b[zw] * a[wz]; - dest[zw] = b[zx] * a[xw] + b[zy] * a[yw] + b[zz] * a[zw] + b[zw] * a[ww]; - - dest[wx] = b[wx] * a[xx] + b[wy] * a[yx] + b[wz] * a[zx] + b[ww] * a[wx]; - dest[wy] = b[wx] * a[xy] + b[wy] * a[yy] + b[wz] * a[zy] + b[ww] * a[wy]; - dest[wz] = b[wx] * a[xz] + b[wy] * a[yz] + b[wz] * a[zz] + b[ww] * a[wz]; - dest[ww] = b[wx] * a[xw] + b[wy] * a[yw] + b[wz] * a[zw] + b[ww] * a[ww]; -} - -#endif diff --git a/Common/Math/fast/fast_matrix.h b/Common/Math/fast/fast_matrix.h index fb4a1b7f26..f6bfa69a6d 100644 --- a/Common/Math/fast/fast_matrix.h +++ b/Common/Math/fast/fast_matrix.h @@ -2,28 +2,145 @@ #include "ppsspp_config.h" -#ifdef __cplusplus -extern "C" { -#endif -// A mini library of 4x4 matrix muls. +#include "Common/Math/SIMDHeaders.h" +#include "Common/Common.h" -extern void fast_matrix_mul_4x4_c(float *dest, const float *a, const float *b); -extern void fast_matrix_mul_4x4_neon(float *dest, const float *a, const float *b); -extern void fast_matrix_mul_4x4_sse(float *dest, const float *a, const float *b); -extern void fast_matrix_mul_4x4_lsx(float *dest, const float *a, const float *b); +#if PPSSPP_ARCH(SSE2) + +inline void fast_matrix_mul_4x4(float *dest, const float *a, const float *b) { + int i; + __m128 a_col_1 = _mm_loadu_ps(a); + __m128 a_col_2 = _mm_loadu_ps(&a[4]); + __m128 a_col_3 = _mm_loadu_ps(&a[8]); + __m128 a_col_4 = _mm_loadu_ps(&a[12]); + + for (i = 0; i < 16; i += 4) { + __m128 r_col = _mm_mul_ps(a_col_1, _mm_set1_ps(b[i])); + r_col = _mm_add_ps(r_col, _mm_mul_ps(a_col_2, _mm_set1_ps(b[i + 1]))); + r_col = _mm_add_ps(r_col, _mm_mul_ps(a_col_3, _mm_set1_ps(b[i + 2]))); + r_col = _mm_add_ps(r_col, _mm_mul_ps(a_col_4, _mm_set1_ps(b[i + 3]))); + _mm_storeu_ps(&dest[i], r_col); + } +} -#if PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) -// Hard link to SSE implementations on x86/amd64 -#define fast_matrix_mul_4x4 fast_matrix_mul_4x4_sse -#elif PPSSPP_ARCH(ARM_NEON) -#define fast_matrix_mul_4x4 fast_matrix_mul_4x4_neon #elif PPSSPP_ARCH(LOONGARCH64_LSX) -#define fast_matrix_mul_4x4 fast_matrix_mul_4x4_lsx -#else -#define fast_matrix_mul_4x4 fast_matrix_mul_4x4_c + +inline __m128 __lsx_vreplfr2vr_s(float val) { + typedef union { + int32_t i; + float f; + } FloatInt; + FloatInt tmpval = {.f = val}; + return (__m128)__lsx_vreplgr2vr_w(tmpval.i); +} + +inline void fast_matrix_mul_4x4(float *dest, const float *a, const float *b) { + __m128 a_col_1 = (__m128)__lsx_vld(a, 0); + __m128 a_col_2 = (__m128)__lsx_vld(a + 4, 0); + __m128 a_col_3 = (__m128)__lsx_vld(a + 8, 0); + __m128 a_col_4 = (__m128)__lsx_vld(a + 12, 0); + + for (int i = 0; i < 16; i += 4) { + + __m128 b1 = __lsx_vreplfr2vr_s(b[i]); + __m128 b2 = __lsx_vreplfr2vr_s(b[i + 1]); + __m128 b3 = __lsx_vreplfr2vr_s(b[i + 2]); + __m128 b4 = __lsx_vreplfr2vr_s(b[i + 3]); + + __m128 result = __lsx_vfmul_s(a_col_1, b1); + result = __lsx_vfmadd_s(a_col_2, b2, result); + result = __lsx_vfmadd_s(a_col_3, b3, result); + result = __lsx_vfmadd_s(a_col_4, b4, result); + + __lsx_vst(result, &dest[i], 0); + } +} + +#elif PPSSPP_ARCH(ARM_NEON) + +#ifdef B0 +#undef B0 #endif -#ifdef __cplusplus -} // extern "C" +// From https://developer.arm.com/documentation/102467/0100/Matrix-multiplication-example +inline void fast_matrix_mul_4x4(float *C, const float *A, const float *B) { + // these are the columns A + float32x4_t A0; + float32x4_t A1; + float32x4_t A2; + float32x4_t A3; + + // these are the columns B + float32x4_t B0; + float32x4_t B1; + float32x4_t B2; + float32x4_t B3; + + // these are the columns C + float32x4_t C0; + float32x4_t C1; + float32x4_t C2; + float32x4_t C3; + + A0 = vld1q_f32(A); + A1 = vld1q_f32(A + 4); + A2 = vld1q_f32(A + 8); + A3 = vld1q_f32(A + 12); + + // Multiply accumulate in 4x1 blocks, i.e. each column in C + B0 = vld1q_f32(B); + B1 = vld1q_f32(B + 4); + B2 = vld1q_f32(B + 8); + B3 = vld1q_f32(B + 12); + + C0 = vmulq_laneq_f32(A0, B0, 0); + C0 = vfmaq_laneq_f32(C0, A1, B0, 1); + C0 = vfmaq_laneq_f32(C0, A2, B0, 2); + C0 = vfmaq_laneq_f32(C0, A3, B0, 3); + vst1q_f32(C, C0); + + C1 = vmulq_laneq_f32(A0, B1, 0); + C1 = vfmaq_laneq_f32(C1, A1, B1, 1); + C1 = vfmaq_laneq_f32(C1, A2, B1, 2); + C1 = vfmaq_laneq_f32(C1, A3, B1, 3); + vst1q_f32(C + 4, C1); + + C2 = vmulq_laneq_f32(A0, B2, 0); + C2 = vfmaq_laneq_f32(C2, A1, B2, 1); + C2 = vfmaq_laneq_f32(C2, A2, B2, 2); + C2 = vfmaq_laneq_f32(C2, A3, B2, 3); + vst1q_f32(C + 8, C2); + + C3 = vmulq_laneq_f32(A0, B3, 0); + C3 = vfmaq_laneq_f32(C3, A1, B3, 1); + C3 = vfmaq_laneq_f32(C3, A2, B3, 2); + C3 = vfmaq_laneq_f32(C3, A3, B3, 3); + vst1q_f32(C + 12, C3); +} + +#else + +inline void fast_matrix_mul_4x4(float * RESTRICT dest, const float * RESTRICT a, const float * RESTRICT b) { + dest[0] = b[0] * a[0] + b[1] * a[4] + b[2] * a[8] + b[3] * a[12]; + dest[1] = b[0] * a[1] + b[1] * a[5] + b[2] * a[9] + b[3] * a[13]; + dest[2] = b[0] * a[2] + b[1] * a[6] + b[2] * a[10] + b[3] * a[14]; + dest[3] = b[0] * a[3] + b[1] * a[7] + b[2] * a[11] + b[3] * a[15]; + + dest[4] = b[4] * a[0] + b[5] * a[4] + b[6] * a[8] + b[7] * a[12]; + dest[5] = b[4] * a[1] + b[5] * a[5] + b[6] * a[9] + b[7] * a[13]; + dest[6] = b[4] * a[2] + b[5] * a[6] + b[6] * a[10] + b[7] * a[14]; + dest[7] = b[4] * a[3] + b[5] * a[7] + b[6] * a[11] + b[7] * a[15]; + + dest[8] = b[8] * a[0] + b[9] * a[4] + b[10] * a[8] + b[11] * a[12]; + dest[9] = b[8] * a[1] + b[9] * a[5] + b[10] * a[9] + b[11] * a[13]; + dest[10] = b[8] * a[2] + b[9] * a[6] + b[10] * a[10] + b[11] * a[14]; + dest[11] = b[8] * a[3] + b[9] * a[7] + b[10] * a[11] + b[11] * a[15]; + + dest[12] = b[12] * a[0] + b[13] * a[4] + b[14] * a[8] + b[15] * a[12]; + dest[13] = b[12] * a[1] + b[13] * a[5] + b[14] * a[9] + b[15] * a[13]; + dest[14] = b[12] * a[2] + b[13] * a[6] + b[14] * a[10] + b[15] * a[14]; + dest[15] = b[12] * a[3] + b[13] * a[7] + b[14] * a[11] + b[15] * a[15]; +} + #endif diff --git a/Core/KeyMap.cpp b/Core/KeyMap.cpp index ad7bfa3fae..76aed645fd 100644 --- a/Core/KeyMap.cpp +++ b/Core/KeyMap.cpp @@ -848,7 +848,8 @@ void NotifyPadConnected(InputDeviceID deviceId, std::string_view name) { g_padNames[deviceId] = name; // Don't notify within the first 5 seconds, to avoid notification spam on startup. - if (time_now_d() >= 5.0) { + // Also for some reason we get some strange things on Android... "Virtual"? + if (time_now_d() >= 5.0 && name != "Virtual") { auto co = GetI18NCategory(I18NCat::CONTROLS); g_OSD.Show(OSDType::MESSAGE_SUCCESS, ApplySafeSubstitutions("%1: %2", co->T("Game controller connected"), name), "", "I_CONTROLLER", 2.0f, "controller_connected"); } diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index a43940fd3c..ad56d67a9d 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -802,7 +802,7 @@ bool TextureCacheCommon::GetBestFramebufferCandidate(const TextureDefinition &en if (bestIndex != -1) { if (logging) { - WARN_LOG(Log::G3D, "Chose candidate %d:\n%s (%dx%d)\n", (int)bestIndex, candidates[bestIndex].ToString().c_str()); + WARN_LOG(Log::G3D, "Chose candidate %d:\n%s", (int)bestIndex, candidates[bestIndex].ToString().c_str()); } *bestCandidate = candidates[bestIndex]; return true; diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 3ac226ebae..d9f43f7e8f 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -330,7 +330,6 @@ - @@ -461,10 +460,6 @@ - - - - {c249f016-7f82-45cf-bb6e-0642a988c4d3} @@ -477,4 +472,4 @@ - \ No newline at end of file + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 865a3c9a95..87c60ea43f 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -250,9 +250,6 @@ Math - - Math\fast - Math\lin @@ -702,9 +699,6 @@ Math - - Math\fast - Math\lin @@ -1049,12 +1043,6 @@ - - Math\fast - - - Math\lin - ext\basis_universal @@ -1095,4 +1083,4 @@ ext\at3_standalone - \ No newline at end of file + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index d6eb76f2a2..83cf96d752 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -330,7 +330,6 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/Render/Text/draw_text_android.cpp \ $(SRC)/Common/Input/GestureDetector.cpp \ $(SRC)/Common/Input/InputState.cpp \ - $(SRC)/Common/Math/fast/fast_matrix.c \ $(SRC)/Common/Math/math_util.cpp \ $(SRC)/Common/Math/Statistics.cpp \ $(SRC)/Common/Math/curves.cpp \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index f04a911811..a35e72419a 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -561,9 +561,8 @@ SOURCES_CXX += \ $(COMMONDIR)/VR/VRInput.cpp \ $(COMMONDIR)/VR/VRRenderer.cpp -SOURCES_C +=\ - $(COMMONDIR)/GPU/OpenGL/gl3stub.c \ - $(COMMONDIR)/Math/fast/fast_matrix.c +SOURCES_C += \ + $(COMMONDIR)/GPU/OpenGL/gl3stub.c SOURCES_CXX += \ $(GPUCOMMONDIR)/Draw2D.cpp \