diff --git a/CMakeLists.txt b/CMakeLists.txt index 7654bccb268..bb2bdc4b66a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,8 @@ else() set(IS_RELEASE_BUILD ON) endif() +option(ENABLE_VULKAN "Enable Vulkan Video Core" ON) + # LTO takes too much memory and time using MSVC. if (NOT MSVC AND NOT MINGW AND IS_RELEASE_BUILD) set(DEFAULT_ENABLE_LTO ON) @@ -92,6 +94,32 @@ option(ENABLE_LTO "Enable link time optimization" ${DEFAULT_ENABLE_LTO}) option(CITRA_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON) option(CITRA_WARNINGS_AS_ERRORS "Enable warnings as errors" ON) +# Disable features not used by a libretro core +# ======================================================================= +if(ENABLE_LIBRETRO) + set(ENABLE_QT OFF) + set(ENABLE_QT_UPDATER OFF) + set(ENABLE_DEDICATED_ROOM OFF) + set(ENABLE_WEB_SERVICE OFF) + set(ENABLE_SCRIPTING OFF) + set(ENABLE_CUBEB OFF) + set(ENABLE_OPENAL OFF) + set(ENABLE_TESTS OFF) + set(CITRA_ENABLE_BUNDLE_TARGET OFF) +endif() + +if(CMAKE_CXX_COMPILER MATCHES "webos" OR + CMAKE_CXX_COMPILER MATCHES "starfish") + set(WEBOS ON) + add_definitions(-DWEBOS=1) +endif() + +if(WEBOS) + set(ENABLE_VULKAN OFF) + # temp fix for fmt/ranges.h:211:59: error: self-comparison always evaluates to true [-Werror=tautological-compare] + add_definitions(-Wno-tautological-compare) +endif() + include(CitraHandleSystemLibs) if (CITRA_USE_PRECOMPILED_HEADERS) @@ -324,8 +352,17 @@ if (ENABLE_QT) endif() # Use system tsl::robin_map if available (otherwise we fallback to version bundled with dynarmic) +set(TSL_ROBIN_MAP_ENABLE_INSTALL ON CACHE BOOL "" FORCE) find_package(tsl-robin-map QUIET) +if (NOT TARGET tsl::robin_map) + if (EXISTS "${CMAKE_SOURCE_DIR}/externals/dynarmic/externals/robin-map/CMakeLists.txt") + add_subdirectory(externals/dynarmic/externals/robin-map) + else() + message(FATAL_ERROR "tsl-robin-map not found: please install it or initialize submodules") + endif() +endif() + # Platform-specific library requirements # ====================================== diff --git a/src/citra_libretro/CMakeLists.txt b/src/citra_libretro/CMakeLists.txt index 8fe7cc267b6..7569b30f745 100644 --- a/src/citra_libretro/CMakeLists.txt +++ b/src/citra_libretro/CMakeLists.txt @@ -8,8 +8,6 @@ add_library(citra_libretro SHARED input/input_factory.h input/mouse_tracker.cpp input/mouse_tracker.h - vulkan/vk_swapchain.cpp - vulkan/vk_swapchain.h citra_libretro.cpp citra_libretro.h environment.cpp @@ -17,6 +15,13 @@ add_library(citra_libretro SHARED core_settings.cpp core_settings.h) +if(ENABLE_VULKAN) + add_library(citra_libretro SHARED + vulkan/vk_swapchain.cpp + vulkan/vk_swapchain.h + ) +endif() + create_target_directory_groups(citra_libretro) target_link_libraries(citra_common PRIVATE libretro) diff --git a/src/common/atomic_ops.h b/src/common/atomic_ops.h index c18bb33c4a2..3f93d4a4095 100644 --- a/src/common/atomic_ops.h +++ b/src/common/atomic_ops.h @@ -11,6 +11,11 @@ #include #endif +#if !defined(__SIZEOF_INT128__) +#include +inline std::mutex g_atomic128_mutex; +#endif + namespace Common { #if _MSC_VER @@ -107,14 +112,6 @@ namespace Common { return __sync_bool_compare_and_swap(pointer, expected, value); } -[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected) { - unsigned __int128 value_a; - unsigned __int128 expected_a; - std::memcpy(&value_a, value.data(), sizeof(u128)); - std::memcpy(&expected_a, expected.data(), sizeof(u128)); - return __sync_bool_compare_and_swap((unsigned __int128*)pointer, expected_a, value_a); -} - [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected, u8& actual) { actual = __sync_val_compare_and_swap(pointer, expected, value); @@ -139,8 +136,52 @@ namespace Common { return actual == expected; } +#if !defined(__SIZEOF_INT128__) + +[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected) { + std::lock_guard lock(g_atomic128_mutex); + u128 current; + std::memcpy(current.data(), (const void*)pointer, sizeof(u128)); + bool match = (current == expected); + if (match) { + std::memcpy((void*)pointer, value.data(), sizeof(u128)); + } + return match; +} + +[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected, u128& actual) { + std::lock_guard lock(g_atomic128_mutex); + u128 current; + std::memcpy(current.data(), (const void*)pointer, sizeof(u128)); + bool match = (current == expected); + if (match) { + std::memcpy((void*)pointer, value.data(), sizeof(u128)); + } + actual = current; + return match; +} + +[[nodiscard]] inline u128 AtomicLoad128(volatile u64* pointer) { + std::lock_guard lock(g_atomic128_mutex); + u128 result; + std::memcpy(result.data(), (const void*)pointer, sizeof(u128)); + return result; +} + +#else + +[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected) +{ + unsigned __int128 value_a; + unsigned __int128 expected_a; + std::memcpy(&value_a, value.data(), sizeof(u128)); + std::memcpy(&expected_a, expected.data(), sizeof(u128)); + return __sync_bool_compare_and_swap((unsigned __int128*)pointer, expected_a, value_a); +} + [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected, - u128& actual) { + u128& actual) +{ unsigned __int128 value_a; unsigned __int128 expected_a; unsigned __int128 actual_a; @@ -151,7 +192,8 @@ namespace Common { return actual_a == expected_a; } -[[nodiscard]] inline u128 AtomicLoad128(volatile u64* pointer) { +[[nodiscard]] inline u128 AtomicLoad128(volatile u64* pointer) +{ unsigned __int128 zeros_a = 0; unsigned __int128 result_a = __sync_val_compare_and_swap((unsigned __int128*)pointer, zeros_a, zeros_a); @@ -161,6 +203,7 @@ namespace Common { return result; } -#endif +#endif // __SIZEOF_INT128__ +#endif // _MSC_VER } // namespace Common diff --git a/src/core/core.cpp b/src/core/core.cpp index 22d0a1de6bd..d5df8087d58 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -395,7 +395,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, #else for (u32 i = 0; i < num_cores; ++i) { cpu_cores.push_back( - std::make_shared(this, *memory, USER32MODE, i, timing->GetTimer(i))); + std::make_shared(*this, *memory, USER32MODE, i, timing->GetTimer(i))); } LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); #endif diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index 06c0334670d..8f9566280ea 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -42,7 +42,7 @@ class FixSizeDiskFile : public DiskFile { if (offset > size) { return ERR_WRITE_BEYOND_END; } else if (offset == size) { - return 0ULL; + return static_cast(0); } if (offset + length > size) { diff --git a/src/core/file_sys/archive_ncch.cpp b/src/core/file_sys/archive_ncch.cpp index 49744efd263..4c705cb94dd 100644 --- a/src/core/file_sys/archive_ncch.cpp +++ b/src/core/file_sys/archive_ncch.cpp @@ -258,7 +258,7 @@ ResultVal NCCHFile::Write(const u64 offset, const std::size_t lengt const u8* buffer) { LOG_ERROR(Service_FS, "Attempted to write to NCCH file"); // TODO(shinyquagsire23): Find error code - return 0ULL; + return static_cast(0); } u64 NCCHFile::GetSize() const { diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index d5d46e0ef58..f393b828a36 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp @@ -105,7 +105,7 @@ ResultVal IVFCFile::Write(const u64 offset, const std::size_t lengt const u8* buffer) { LOG_ERROR(Service_FS, "Attempted to write to IVFC file"); // TODO(Subv): Find error code - return 0ULL; + return static_cast(0); } u64 IVFCFile::GetSize() const { @@ -136,7 +136,7 @@ ResultVal IVFCFileInMemory::Write(const u64 offset, const std::size const bool flush, const u8* buffer) { LOG_ERROR(Service_FS, "Attempted to write to IVFC file"); // TODO(Subv): Find error code - return 0ULL; + return static_cast(0); } u64 IVFCFileInMemory::GetSize() const { diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 50c262becdd..80f3f271aaf 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -96,46 +96,6 @@ add_library(video_core STATIC renderer_software/sw_rasterizer.h renderer_software/sw_texturing.cpp renderer_software/sw_texturing.h - renderer_vulkan/pica_to_vk.h - renderer_vulkan/renderer_vulkan.cpp - renderer_vulkan/renderer_vulkan.h - renderer_vulkan/vk_blit_helper.cpp - renderer_vulkan/vk_blit_helper.h - renderer_vulkan/vk_common.cpp - renderer_vulkan/vk_common.h - renderer_vulkan/vk_descriptor_pool.cpp - renderer_vulkan/vk_descriptor_pool.h - renderer_vulkan/vk_graphics_pipeline.cpp - renderer_vulkan/vk_graphics_pipeline.h - renderer_vulkan/vk_master_semaphore.cpp - renderer_vulkan/vk_master_semaphore.h - renderer_vulkan/vk_memory_util.cpp - renderer_vulkan/vk_memory_util.h - renderer_vulkan/vk_rasterizer.cpp - renderer_vulkan/vk_rasterizer.h - renderer_vulkan/vk_rasterizer_cache.cpp - renderer_vulkan/vk_scheduler.cpp - renderer_vulkan/vk_scheduler.h - renderer_vulkan/vk_resource_pool.cpp - renderer_vulkan/vk_resource_pool.h - renderer_vulkan/vk_instance.cpp - renderer_vulkan/vk_instance.h - renderer_vulkan/vk_pipeline_cache.cpp - renderer_vulkan/vk_pipeline_cache.h - renderer_vulkan/vk_platform.cpp - renderer_vulkan/vk_platform.h - renderer_vulkan/vk_present_window.cpp - renderer_vulkan/vk_present_window.h - renderer_vulkan/vk_renderpass_cache.cpp - renderer_vulkan/vk_renderpass_cache.h - renderer_vulkan/vk_shader_util.cpp - renderer_vulkan/vk_shader_util.h - renderer_vulkan/vk_stream_buffer.cpp - renderer_vulkan/vk_stream_buffer.h - renderer_vulkan/vk_swapchain.cpp - renderer_vulkan/vk_swapchain.h - renderer_vulkan/vk_texture_runtime.cpp - renderer_vulkan/vk_texture_runtime.h shader/debug_data.h shader/generator/glsl_fs_shader_gen.cpp shader/generator/glsl_fs_shader_gen.h @@ -173,6 +133,51 @@ add_library(video_core STATIC video_core.h ) +if(ENABLE_VULKAN) + add_library(video_core STATIC + renderer_vulkan/pica_to_vk.h + renderer_vulkan/renderer_vulkan.cpp + renderer_vulkan/renderer_vulkan.h + renderer_vulkan/vk_blit_helper.cpp + renderer_vulkan/vk_blit_helper.h + renderer_vulkan/vk_common.cpp + renderer_vulkan/vk_common.h + renderer_vulkan/vk_descriptor_pool.cpp + renderer_vulkan/vk_descriptor_pool.h + renderer_vulkan/vk_graphics_pipeline.cpp + renderer_vulkan/vk_graphics_pipeline.h + renderer_vulkan/vk_master_semaphore.cpp + renderer_vulkan/vk_master_semaphore.h + renderer_vulkan/vk_memory_util.cpp + renderer_vulkan/vk_memory_util.h + renderer_vulkan/vk_rasterizer.cpp + renderer_vulkan/vk_rasterizer.h + renderer_vulkan/vk_rasterizer_cache.cpp + renderer_vulkan/vk_scheduler.cpp + renderer_vulkan/vk_scheduler.h + renderer_vulkan/vk_resource_pool.cpp + renderer_vulkan/vk_resource_pool.h + renderer_vulkan/vk_instance.cpp + renderer_vulkan/vk_instance.h + renderer_vulkan/vk_pipeline_cache.cpp + renderer_vulkan/vk_pipeline_cache.h + renderer_vulkan/vk_platform.cpp + renderer_vulkan/vk_platform.h + renderer_vulkan/vk_present_window.cpp + renderer_vulkan/vk_present_window.h + renderer_vulkan/vk_renderpass_cache.cpp + renderer_vulkan/vk_renderpass_cache.h + renderer_vulkan/vk_shader_util.cpp + renderer_vulkan/vk_shader_util.h + renderer_vulkan/vk_stream_buffer.cpp + renderer_vulkan/vk_stream_buffer.h + renderer_vulkan/vk_swapchain.cpp + renderer_vulkan/vk_swapchain.h + renderer_vulkan/vk_texture_runtime.cpp + renderer_vulkan/vk_texture_runtime.h + ) +endif() + add_dependencies(video_core host_shaders) target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE})