diff --git a/CMakeModules/DuckStationDependencies.cmake b/CMakeModules/DuckStationDependencies.cmake index 800ae82ef..a7c54e972 100644 --- a/CMakeModules/DuckStationDependencies.cmake +++ b/CMakeModules/DuckStationDependencies.cmake @@ -16,6 +16,7 @@ find_package(ZLIB REQUIRED) # 1.3, but Mac currently doesn't use it. find_package(PNG 1.6.40 REQUIRED) find_package(JPEG REQUIRED) # No version because flatpak uses libjpeg-turbo. find_package(Freetype 2.11.1 REQUIRED) +find_package(cpuinfo REQUIRED) if(NOT WIN32) find_package(CURL REQUIRED) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 650d38e34..0e51e7d46 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -137,7 +137,7 @@ target_precompile_headers(core PRIVATE "pch.h") target_include_directories(core PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..") target_include_directories(core PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..") target_link_libraries(core PUBLIC Threads::Threads common util ZLIB::ZLIB) -target_link_libraries(core PRIVATE xxhash imgui rapidyaml rcheevos) +target_link_libraries(core PRIVATE xxhash imgui rapidyaml rcheevos cpuinfo::cpuinfo) if(CPU_ARCH_X64) target_compile_definitions(core PUBLIC "ENABLE_RECOMPILER=1" "ENABLE_NEWREC=1" "ENABLE_MMAP_FASTMEM=1") diff --git a/src/core/system.cpp b/src/core/system.cpp index e2df61660..cb8318f34 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -54,6 +54,7 @@ #include "common/string_util.h" #include "common/threading.h" +#include "cpuinfo.h" #include "fmt/chrono.h" #include "fmt/format.h" #include "imgui.h" @@ -303,18 +304,43 @@ bool System::Internal::PerformEarlyHardwareChecks(Error* error) void System::CheckCacheLineSize() { - const size_t runtime_cache_line_size = PlatformMisc::GetRuntimeCacheLineSize(); - if (runtime_cache_line_size == 0) + u32 max_line_size = 0; + if (cpuinfo_initialize()) + { + const u32 num_l1is = cpuinfo_get_l1i_caches_count(); + const u32 num_l1ds = cpuinfo_get_l1d_caches_count(); + const u32 num_l2s = cpuinfo_get_l2_caches_count(); + for (u32 i = 0; i < num_l1is; i++) + { + const cpuinfo_cache* cache = cpuinfo_get_l1i_cache(i); + if (cache) + max_line_size = std::max(max_line_size, cache->line_size); + } + for (u32 i = 0; i < num_l1ds; i++) + { + const cpuinfo_cache* cache = cpuinfo_get_l1d_cache(i); + if (cache) + max_line_size = std::max(max_line_size, cache->line_size); + } + for (u32 i = 0; i < num_l2s; i++) + { + const cpuinfo_cache* cache = cpuinfo_get_l2_cache(i); + if (cache) + max_line_size = std::max(max_line_size, cache->line_size); + } + } + + if (max_line_size == 0) { ERROR_LOG("Cannot determine size of cache line. Continuing with expectation of {} byte lines.", - runtime_cache_line_size); + HOST_CACHE_LINE_SIZE); } - else if (HOST_CACHE_LINE_SIZE != runtime_cache_line_size) + else if (HOST_CACHE_LINE_SIZE != max_line_size) { // Not fatal, but does have performance implications. WARNING_LOG( "Cache line size mismatch. This build was compiled with {} byte lines, but the system has {} byte lines.", - HOST_CACHE_LINE_SIZE, runtime_cache_line_size); + HOST_CACHE_LINE_SIZE, max_line_size); } } diff --git a/src/duckstation-qt/CMakeLists.txt b/src/duckstation-qt/CMakeLists.txt index 74500cb2c..3b34fcb85 100644 --- a/src/duckstation-qt/CMakeLists.txt +++ b/src/duckstation-qt/CMakeLists.txt @@ -207,7 +207,7 @@ if(WIN32) ) #set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/translations") - set(DEPS_TO_COPY freetype.dll harfbuzz.dll libjpeg.dll libpng16.dll libsharpyuv.dll libwebp.dll SDL2.dll shaderc_shared.dll spirv-cross-c-shared.dll zlib1.dll zstd.dll) + set(DEPS_TO_COPY cpuinfo.dll freetype.dll harfbuzz.dll libjpeg.dll libpng16.dll libsharpyuv.dll libwebp.dll SDL2.dll shaderc_shared.dll spirv-cross-c-shared.dll zlib1.dll zstd.dll) foreach(DEP ${DEPS_TO_COPY}) list(APPEND DEP_BINS "${CMAKE_PREFIX_PATH}/bin/${DEP}") endforeach() diff --git a/src/util/platform_misc.h b/src/util/platform_misc.h index 0366df5f5..13b81d841 100644 --- a/src/util/platform_misc.h +++ b/src/util/platform_misc.h @@ -15,9 +15,6 @@ void ResumeScreensaver(); /// Returns the size of pages for the current host. size_t GetRuntimePageSize(); -/// Returns the size of a cache line for the current host. -size_t GetRuntimeCacheLineSize(); - /// Abstracts platform-specific code for asynchronously playing a sound. /// On Windows, this will use PlaySound(). On Linux, it will shell out to aplay. On MacOS, it uses NSSound. bool PlaySoundAsync(const char* path); diff --git a/src/util/platform_misc_mac.mm b/src/util/platform_misc_mac.mm index ee4c91dc7..9a76fcba2 100644 --- a/src/util/platform_misc_mac.mm +++ b/src/util/platform_misc_mac.mm @@ -93,11 +93,6 @@ size_t PlatformMisc::GetRuntimePageSize() return sysctlbyname("hw.pagesize").value_or(0); } -size_t PlatformMisc::GetRuntimeCacheLineSize() -{ - return static_cast(std::max(sysctlbyname("hw.cachelinesize").value_or(0), 0)); -} - bool PlatformMisc::PlaySoundAsync(const char* path) { NSString* nspath = [[NSString alloc] initWithUTF8String:path]; diff --git a/src/util/platform_misc_unix.cpp b/src/util/platform_misc_unix.cpp index 26be5afc2..cafc04d4d 100644 --- a/src/util/platform_misc_unix.cpp +++ b/src/util/platform_misc_unix.cpp @@ -132,28 +132,6 @@ size_t PlatformMisc::GetRuntimePageSize() return (res > 0) ? static_cast(res) : 0; } -size_t PlatformMisc::GetRuntimeCacheLineSize() -{ - int l1i = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); - int l1d = sysconf(_SC_LEVEL1_ICACHE_LINESIZE); - int res = (l1i > l1d) ? l1i : l1d; - for (int index = 0; index < 16; index++) - { - char buf[128]; - snprintf(buf, sizeof(buf), "/sys/devices/system/cpu/cpu0/cache/index%d/coherency_line_size", index); - std::FILE* fp = std::fopen(buf, "rb"); - if (!fp) - break; - - std::fread(buf, sizeof(buf), 1, fp); - std::fclose(fp); - int val = std::atoi(buf); - res = (val > res) ? val : res; - } - - return (res > 0) ? static_cast(res) : 0; -} - bool PlatformMisc::PlaySoundAsync(const char* path) { #ifdef __linux__ diff --git a/src/util/platform_misc_win32.cpp b/src/util/platform_misc_win32.cpp index a27040629..8528e4f17 100644 --- a/src/util/platform_misc_win32.cpp +++ b/src/util/platform_misc_win32.cpp @@ -85,28 +85,6 @@ size_t PlatformMisc::GetRuntimePageSize() return si.dwPageSize; } -size_t PlatformMisc::GetRuntimeCacheLineSize() -{ - DWORD size = 0; - if (!GetLogicalProcessorInformation(nullptr, &size) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) - return 0; - - std::unique_ptr lpi = - std::make_unique( - (size + (sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) - 1)) / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)); - if (!GetLogicalProcessorInformation(lpi.get(), &size)) - return 0; - - u32 max_line_size = 0; - for (u32 i = 0; i < size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); i++) - { - if (lpi[i].Relationship == RelationCache) - max_line_size = std::max(max_line_size, lpi[i].Cache.LineSize); - } - - return max_line_size; -} - bool PlatformMisc::PlaySoundAsync(const char* path) { const std::wstring wpath(FileSystem::GetWin32Path(path)); diff --git a/src/util/util.props b/src/util/util.props index ab485f5e7..0549e519c 100644 --- a/src/util/util.props +++ b/src/util/util.props @@ -4,7 +4,7 @@ - %(PreprocessorDefinitions);SOUNDTOUCH_FLOAT_SAMPLES;SOUNDTOUCH_ALLOW_SSE;ST_NO_EXCEPTION_HANDLING=1;ENABLE_VULKAN=1 + %(PreprocessorDefinitions);SOUNDTOUCH_FLOAT_SAMPLES;SOUNDTOUCH_ALLOW_SSE;ST_NO_EXCEPTION_HANDLING=1;CPUINFO_SHARED=1;ENABLE_VULKAN=1 %(PreprocessorDefinitions);ENABLE_OPENGL=1 %(PreprocessorDefinitions);SOUNDTOUCH_USE_NEON %(AdditionalIncludeDirectories);$(SolutionDir)dep\xxhash\include;$(SolutionDir)dep\freesurround\include;$(SolutionDir)dep\kissfft\include;$(SolutionDir)dep\soundtouch\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\libchdr\include;$(SolutionDir)dep\cubeb\include;$(SolutionDir)dep\d3d12ma\include;$(SolutionDir)dep\vulkan\include @@ -27,10 +27,11 @@ %(AdditionalIncludeDirectories);$(DepsIncludeDir)SDL2 - %(AdditionalDependencies);freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;SDL2.lib;zlib.lib;zstd.lib + %(AdditionalDependencies);cpuinfo.lib;freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;SDL2.lib;zlib.lib;zstd.lib +