From 268918aeced185684d246a2eaaf8ffce3fb795b1 Mon Sep 17 00:00:00 2001 From: Ribbit Date: Sat, 4 Oct 2025 23:58:08 +0200 Subject: [PATCH 01/24] [vk] Implement Shader Read Barrier (#2671) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding the shader read barrier keeps every render/compute/transfer write visible before the image is sampled, so it prevents the “read-before-writes-finish” hazards. Without it you can get random stale frames, flickering post process passes, partially updated HUD textures, and corrupted depth-to-color conversions especially in scenes that render into an offscreen image and immediately feed that image to a shader (reflections, bloom, dynamic resolution, depth visualizers, etc.). This fix makes those R2T chains deterministic again across all Vulkan drivers. Co-authored-by: Ribbit Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2671 Reviewed-by: MaranBr Reviewed-by: crueter Co-authored-by: Ribbit Co-committed-by: Ribbit --- src/video_core/engines/maxwell_dma.cpp | 2 + src/video_core/renderer_vulkan/blit_image.cpp | 83 +++++++++++++++++-- src/video_core/renderer_vulkan/blit_image.h | 13 +-- .../renderer_vulkan/vk_texture_cache.cpp | 17 ++-- 4 files changed, 95 insertions(+), 20 deletions(-) diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 52ca9bbdb6..e2aa6c7e49 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp @@ -156,6 +156,8 @@ void MaxwellDMA::Launch() { } void MaxwellDMA::CopyBlockLinearToPitch() { + + u32 bytes_per_pixel = 1; DMA::ImageOperand src_operand; src_operand.bytes_per_pixel = bytes_per_pixel; diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index 7bfcd6503b..68543bdd48 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp @@ -46,6 +46,38 @@ namespace Vulkan { using VideoCommon::ImageViewType; namespace { + +[[nodiscard]] VkImageAspectFlags AspectMaskFromFormat(VideoCore::Surface::PixelFormat format) { + using VideoCore::Surface::SurfaceType; + switch (VideoCore::Surface::GetFormatType(format)) { + case SurfaceType::ColorTexture: + return VK_IMAGE_ASPECT_COLOR_BIT; + case SurfaceType::Depth: + return VK_IMAGE_ASPECT_DEPTH_BIT; + case SurfaceType::Stencil: + return VK_IMAGE_ASPECT_STENCIL_BIT; + case SurfaceType::DepthStencil: + return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + default: + return VK_IMAGE_ASPECT_COLOR_BIT; + } +} + +[[nodiscard]] VkImageSubresourceRange SubresourceRangeFromView(const ImageView& image_view) { + auto range = image_view.range; + if ((image_view.flags & VideoCommon::ImageViewFlagBits::Slice) != VideoCommon::ImageViewFlagBits{}) { + range.base.layer = 0; + range.extent.layers = 1; + } + return VkImageSubresourceRange{ + .aspectMask = AspectMaskFromFormat(image_view.format), + .baseMipLevel = static_cast(range.base.level), + .levelCount = static_cast(range.extent.levels), + .baseArrayLayer = static_cast(range.base.layer), + .layerCount = static_cast(range.extent.layers), + }; +} + struct PushConstants { std::array tex_scale; std::array tex_offset; @@ -417,6 +449,40 @@ void TransitionImageLayout(vk::CommandBuffer& cmdbuf, VkImage image, VkImageLayo 0, barrier); } +void RecordShaderReadBarrier(Scheduler& scheduler, const ImageView& image_view) { + const VkImage image = image_view.ImageHandle(); + const VkImageSubresourceRange subresource_range = SubresourceRangeFromView(image_view); + scheduler.RequestOutsideRenderPassOperationContext(); + scheduler.Record([image, subresource_range](vk::CommandBuffer cmdbuf) { + const VkImageMemoryBarrier barrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | + VK_ACCESS_SHADER_WRITE_BIT | + VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, + .oldLayout = VK_IMAGE_LAYOUT_GENERAL, + .newLayout = VK_IMAGE_LAYOUT_GENERAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = image, + .subresourceRange = subresource_range, + }; + cmdbuf.PipelineBarrier( + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | + VK_PIPELINE_STAGE_TRANSFER_BIT | + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + 0, + barrier); + }); +} + void BeginRenderPass(vk::CommandBuffer& cmdbuf, const Framebuffer* framebuffer) { const VkRenderPass render_pass = framebuffer->RenderPass(); const VkFramebuffer framebuffer_handle = framebuffer->Handle(); @@ -484,7 +550,7 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_, BlitImageHelper::~BlitImageHelper() = default; -void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView src_view, +void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, const Region2D& dst_region, const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter, Tegra::Engines::Fermi2D::Operation operation) { @@ -496,10 +562,12 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView const VkPipelineLayout layout = *one_texture_pipeline_layout; const VkSampler sampler = is_linear ? *linear_sampler : *nearest_sampler; const VkPipeline pipeline = FindOrEmplaceColorPipeline(key); + const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D); + + RecordShaderReadBarrier(scheduler, src_image_view); scheduler.RequestRenderpass(dst_framebuffer); scheduler.Record([this, dst_region, src_region, pipeline, layout, sampler, src_view](vk::CommandBuffer cmdbuf) { - // TODO: Barriers const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit(); UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); @@ -538,7 +606,7 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView } void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer, - VkImageView src_depth_view, VkImageView src_stencil_view, + ImageView& src_image_view, const Region2D& dst_region, const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter, Tegra::Engines::Fermi2D::Operation operation) { @@ -554,10 +622,13 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer, const VkPipelineLayout layout = *two_textures_pipeline_layout; const VkSampler sampler = *nearest_sampler; const VkPipeline pipeline = FindOrEmplaceDepthStencilPipeline(key); + const VkImageView src_depth_view = src_image_view.DepthView(); + const VkImageView src_stencil_view = src_image_view.StencilView(); + + RecordShaderReadBarrier(scheduler, src_image_view); scheduler.RequestRenderpass(dst_framebuffer); scheduler.Record([dst_region, src_region, pipeline, layout, sampler, src_depth_view, src_stencil_view, this](vk::CommandBuffer cmdbuf) { - // TODO: Barriers const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit(); UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view, src_stencil_view); @@ -692,6 +763,7 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb const VkSampler sampler = *nearest_sampler; const VkExtent2D extent = GetConversionExtent(src_image_view); + RecordShaderReadBarrier(scheduler, src_image_view); scheduler.RequestRenderpass(dst_framebuffer); scheduler.Record([pipeline, layout, sampler, src_view, extent, this](vk::CommandBuffer cmdbuf) { const VkOffset2D offset{ @@ -717,7 +789,6 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit(); UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view); - // TODO: Barriers cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, nullptr); @@ -737,6 +808,7 @@ void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer const VkSampler sampler = *nearest_sampler; const VkExtent2D extent = GetConversionExtent(src_image_view); + RecordShaderReadBarrier(scheduler, src_image_view); scheduler.RequestRenderpass(dst_framebuffer); scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent, this](vk::CommandBuffer cmdbuf) { @@ -763,7 +835,6 @@ void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit(); UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view, src_stencil_view); - // TODO: Barriers cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, nullptr); diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h index 3d400be6a9..bdb8cce883 100644 --- a/src/video_core/renderer_vulkan/blit_image.h +++ b/src/video_core/renderer_vulkan/blit_image.h @@ -1,4 +1,7 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -43,7 +46,7 @@ public: StateTracker& state_tracker, DescriptorPool& descriptor_pool); ~BlitImageHelper(); - void BlitColor(const Framebuffer* dst_framebuffer, VkImageView src_image_view, + void BlitColor(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, const Region2D& dst_region, const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter, Tegra::Engines::Fermi2D::Operation operation); @@ -52,9 +55,9 @@ public: VkImage src_image, VkSampler src_sampler, const Region2D& dst_region, const Region2D& src_region, const Extent3D& src_size); - void BlitDepthStencil(const Framebuffer* dst_framebuffer, VkImageView src_depth_view, - VkImageView src_stencil_view, const Region2D& dst_region, - const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter, + void BlitDepthStencil(const Framebuffer* dst_framebuffer, ImageView& src_image_view, + const Region2D& dst_region, const Region2D& src_region, + Tegra::Engines::Fermi2D::Filter filter, Tegra::Engines::Fermi2D::Operation operation); void ConvertD32ToR32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 8d1d609a35..575651905e 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1086,8 +1086,8 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst return; } if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT && !is_src_msaa && !is_dst_msaa) { - blit_image_helper.BlitColor(dst_framebuffer, src.Handle(Shader::TextureType::Color2D), - dst_region, src_region, filter, operation); + blit_image_helper.BlitColor(dst_framebuffer, src, dst_region, src_region, filter, + operation); return; } ASSERT(src.format == dst.format); @@ -1106,8 +1106,8 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst }(); if (!can_blit_depth_stencil) { UNIMPLEMENTED_IF(is_src_msaa || is_dst_msaa); - blit_image_helper.BlitDepthStencil(dst_framebuffer, src.DepthView(), src.StencilView(), - dst_region, src_region, filter, operation); + blit_image_helper.BlitDepthStencil(dst_framebuffer, src, dst_region, src_region, + filter, operation); return; } } @@ -1968,18 +1968,17 @@ bool Image::BlitScaleHelper(bool scale_up) { blit_framebuffer = std::make_unique(*runtime, view_ptr, nullptr, extent, scale_up); } - const auto color_view = blit_view->Handle(Shader::TextureType::Color2D); - runtime->blit_image_helper.BlitColor(blit_framebuffer.get(), color_view, dst_region, + runtime->blit_image_helper.BlitColor(blit_framebuffer.get(), *blit_view, dst_region, src_region, operation, BLIT_OPERATION); } else if (aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { if (!blit_framebuffer) { blit_framebuffer = std::make_unique(*runtime, nullptr, view_ptr, extent, scale_up); } - runtime->blit_image_helper.BlitDepthStencil(blit_framebuffer.get(), blit_view->DepthView(), - blit_view->StencilView(), dst_region, - src_region, operation, BLIT_OPERATION); + runtime->blit_image_helper.BlitDepthStencil(blit_framebuffer.get(), *blit_view, + dst_region, src_region, operation, + BLIT_OPERATION); } else { // TODO: Use helper blits where applicable flags &= ~ImageFlagBits::Rescaled; From 1a13e79c3d8619ff302d9c77eacf1a35c2210b66 Mon Sep 17 00:00:00 2001 From: crueter Date: Sun, 5 Oct 2025 00:00:52 +0200 Subject: [PATCH 02/24] [cmake] fix video_core and tests comp errors on Windows (#2631) did not link to video_core thus did not properly propagate the GPUOpen target thus failed to find vk_mem_alloc also msvc sucks Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2631 Reviewed-by: MaranBr --- src/tests/CMakeLists.txt | 5 ++++- src/video_core/vulkan_common/vma.h | 8 ++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 1e158f3759..c1fdd374ef 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + # SPDX-FileCopyrightText: 2018 yuzu Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later @@ -21,7 +24,7 @@ add_executable(tests create_target_directory_groups(tests) -target_link_libraries(tests PRIVATE common core input_common) +target_link_libraries(tests PRIVATE common core input_common video_core) target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} Catch2::Catch2WithMain Threads::Threads) add_test(NAME tests COMMAND tests) diff --git a/src/video_core/vulkan_common/vma.h b/src/video_core/vulkan_common/vma.h index 911c1114b2..e022b2bf7d 100644 --- a/src/video_core/vulkan_common/vma.h +++ b/src/video_core/vulkan_common/vma.h @@ -10,4 +10,12 @@ #define VMA_STATIC_VULKAN_FUNCTIONS 0 #define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4189 ) +#endif #include "vk_mem_alloc.h" + +#ifdef _MSC_VER +#pragma warning( pop ) +#endif From 9f385bf627e40e2b7d5b06cd83cab0a4e9f98f99 Mon Sep 17 00:00:00 2001 From: crueter Date: Sun, 5 Oct 2025 03:04:53 +0200 Subject: [PATCH 03/24] [tools, cmake] refactor: update/hash check scripts, use tags for some more deps, proper CPMUtil separation (#2666) Uses tags for a bunch of deps that can use them Also adds a bunmch of scripts to tools/cpm, notably for checking hashes and checking for updates. TODO for the future: - CI target to check hashes - Weekly CI to check for updates Need to get that other CI runner up additional stuff - Ports gentoo fixes - makes solaris work (TODO: sdl2) - way better docs - properly separates CPMUtil as a standalone project Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2666 Reviewed-by: Lizzie Reviewed-by: MaranBr --- .shellcheckrc | 1 + CMakeLists.txt | 18 +- CMakeModules/CPM.cmake | 8 +- CMakeModules/CPMUtil.cmake | 20 +- CMakeModules/Findzstd.cmake | 3 + README.md | 2 + cpmfile.json | 27 +- docs/CPM.md | 258 ------------------ docs/CPMUtil.md | 14 + docs/Deps.md | 3 +- docs/README.md | 2 +- externals/CMakeLists.txt | 42 +-- externals/cpmfile.json | 150 +++++----- externals/ffmpeg/cpmfile.json | 10 +- externals/libusb/CMakeLists.txt | 13 +- externals/libusb/cpmfile.json | 15 +- src/common/common_types.h | 4 +- src/core/frontend/applets/cabinet.h | 5 + src/core/memory/dmnt_cheat_vm.h | 5 + src/dynarmic/externals/cpmfile.json | 7 +- src/dynarmic/src/dynarmic/CMakeLists.txt | 2 +- .../src/dynarmic/common/common_types.h | 3 + src/hid_core/resources/applet_resource.h | 4 + src/hid_core/resources/npad/npad_vibration.h | 4 + src/hid_core/resources/touch_screen/gesture.h | 4 + .../resources/touch_screen/touch_screen.h | 4 + src/yuzu/main.cpp | 3 +- tools/README.md | 21 ++ tools/clang-format.sh | 5 +- tools/cpm-fetch-all.sh | 12 +- tools/cpm-fetch.sh | 236 ---------------- tools/cpm-hash.sh | 4 - tools/cpm/README.md | 71 +++++ tools/cpm/check-hash-all.sh | 10 + tools/cpm/check-hash.sh | 46 ++++ tools/cpm/check-updates-all.sh | 10 + tools/cpm/check-updates.sh | 90 ++++++ tools/cpm/common.sh | 32 +++ tools/cpm/download.sh | 100 +++++++ tools/cpm/fetch-all.sh | 10 + tools/cpm/fetch.sh | 36 +++ tools/cpm/format.sh | 15 + tools/cpm/hash.sh | 25 ++ tools/cpm/package.sh | 203 ++++++++++++++ tools/cpm/replace.sh | 20 ++ tools/cpm/url-hash.sh | 7 + tools/cpm/which.sh | 15 + tools/dtrace-tool.sh | 47 +++- tools/llvmpipe-run.sh | 192 ++++++++++++- tools/optimize-assets.sh | 7 +- tools/reset-submodules.sh | 8 - tools/shellcheck.sh | 11 + tools/update-cpm.sh | 7 +- tools/update-icons.sh | 5 +- tools/url-hash.sh | 4 - 55 files changed, 1197 insertions(+), 683 deletions(-) create mode 100644 .shellcheckrc delete mode 100644 docs/CPM.md create mode 100644 docs/CPMUtil.md create mode 100644 tools/README.md mode change 100755 => 100644 tools/cpm-fetch-all.sh delete mode 100755 tools/cpm-fetch.sh delete mode 100755 tools/cpm-hash.sh create mode 100755 tools/cpm/README.md create mode 100755 tools/cpm/check-hash-all.sh create mode 100755 tools/cpm/check-hash.sh create mode 100755 tools/cpm/check-updates-all.sh create mode 100755 tools/cpm/check-updates.sh create mode 100755 tools/cpm/common.sh create mode 100755 tools/cpm/download.sh create mode 100755 tools/cpm/fetch-all.sh create mode 100755 tools/cpm/fetch.sh create mode 100755 tools/cpm/format.sh create mode 100755 tools/cpm/hash.sh create mode 100755 tools/cpm/package.sh create mode 100755 tools/cpm/replace.sh create mode 100755 tools/cpm/url-hash.sh create mode 100755 tools/cpm/which.sh delete mode 100755 tools/reset-submodules.sh create mode 100755 tools/shellcheck.sh delete mode 100755 tools/url-hash.sh diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000000..96e22629de --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1 @@ +shell=sh diff --git a/CMakeLists.txt b/CMakeLists.txt index b397ba01aa..7f192887f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,10 +32,20 @@ endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules") + +# NB: this does not account for SPARC +# If you get Eden working on SPARC, please shoot crueter@crueter.xyz multiple emails +# and you will be hailed for eternity if (PLATFORM_SUN) # Terrific Solaris pkg shenanigans list(APPEND CMAKE_PREFIX_PATH "/usr/lib/qt/6.6/lib/amd64/cmake") list(APPEND CMAKE_MODULE_PATH "/usr/lib/qt/6.6/lib/amd64/cmake") + + # amazing + # absolutely incredible + list(APPEND CMAKE_PREFIX_PATH "/usr/lib/amd64/cmake") + list(APPEND CMAKE_MODULE_PATH "/usr/lib/amd64/cmake") + # For some mighty reason, doing a normal release build sometimes may not trigger # the proper -O3 switch to materialize if (CMAKE_BUILD_TYPE MATCHES "Release") @@ -454,6 +464,7 @@ if (YUZU_USE_CPM) if (zstd_ADDED) add_library(zstd::zstd ALIAS libzstd_static) + add_library(zstd::libzstd ALIAS libzstd_static) endif() # Opus @@ -489,9 +500,9 @@ else() # wow if (PLATFORM_LINUX) - find_package(Boost 1.57.0 REQUIRED headers context system fiber) + find_package(Boost 1.57.0 CONFIG REQUIRED headers context system fiber) else() - find_package(Boost 1.57.0 REQUIRED) + find_package(Boost 1.57.0 CONFIG REQUIRED) endif() if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR ANDROID) @@ -542,6 +553,7 @@ find_package(MbedTLS) find_package(VulkanUtilityLibraries) find_package(SimpleIni) find_package(SPIRV-Tools) +find_package(sirit) if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) find_package(xbyak) @@ -593,6 +605,8 @@ if (ENABLE_QT) endif() if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + # yes Qt, we get it + set(QT_NO_PRIVATE_MODULE_WARNING ON) find_package(Qt6 REQUIRED COMPONENTS DBus OPTIONAL_COMPONENTS GuiPrivate) elseif (UNIX AND NOT APPLE) find_package(Qt6 REQUIRED COMPONENTS DBus Gui) diff --git a/CMakeModules/CPM.cmake b/CMakeModules/CPM.cmake index 3636ee5da0..5544d8eefe 100644 --- a/CMakeModules/CPM.cmake +++ b/CMakeModules/CPM.cmake @@ -743,9 +743,11 @@ function(CPMAddPackage) if(NOT DEFINED CPM_ARGS_NAME) set(CPM_ARGS_NAME ${nameFromUrl}) endif() - if(NOT DEFINED CPM_ARGS_VERSION) - set(CPM_ARGS_VERSION ${verFromUrl}) - endif() + + # this is dumb and should not be done + # if(NOT DEFINED CPM_ARGS_VERSION) + # set(CPM_ARGS_VERSION ${verFromUrl}) + # endif() list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS URL "${CPM_ARGS_URL}") endif() diff --git a/CMakeModules/CPMUtil.cmake b/CMakeModules/CPMUtil.cmake index 3347c7e884..3d7b84c029 100644 --- a/CMakeModules/CPMUtil.cmake +++ b/CMakeModules/CPMUtil.cmake @@ -277,6 +277,7 @@ function(AddPackage) KEY BUNDLED_PACKAGE + FORCE_BUNDLED_PACKAGE FIND_PACKAGE_ARGUMENTS ) @@ -426,7 +427,9 @@ function(AddPackage) - BUNDLED_PACKAGE - default to allow local ]]# - if (${PKG_ARGS_NAME}_FORCE_SYSTEM) + if (PKG_ARGS_FORCE_BUNDLED_PACKAGE) + set_precedence(OFF OFF) + elseif (${PKG_ARGS_NAME}_FORCE_SYSTEM) set_precedence(ON ON) elseif (${PKG_ARGS_NAME}_FORCE_BUNDLED) set_precedence(OFF OFF) @@ -446,9 +449,14 @@ function(AddPackage) set_precedence(ON OFF) endif() + if (DEFINED PKG_ARGS_VERSION) + list(APPEND EXTRA_ARGS + VERSION ${PKG_ARGS_VERSION} + ) + endif() + CPMAddPackage( NAME ${PKG_ARGS_NAME} - VERSION ${PKG_ARGS_VERSION} URL ${pkg_url} URL_HASH ${pkg_hash} CUSTOM_CACHE_KEY ${pkg_key} @@ -459,6 +467,8 @@ function(AddPackage) PATCHES ${PKG_ARGS_PATCHES} EXCLUDE_FROM_ALL ON + ${EXTRA_ARGS} + ${PKG_ARGS_UNPARSED_ARGUMENTS} ) @@ -511,12 +521,12 @@ function(add_ci_package key) NAME ${ARTIFACT_PACKAGE} REPO ${ARTIFACT_REPO} TAG v${ARTIFACT_VERSION} - VERSION ${ARTIFACT_VERSION} + GIT_VERSION ${ARTIFACT_VERSION} ARTIFACT ${ARTIFACT} - KEY ${key} + KEY ${key}-${ARTIFACT_VERSION} HASH_SUFFIX sha512sum - BUNDLED_PACKAGE ON + FORCE_BUNDLED_PACKAGE ON ) set(ARTIFACT_DIR ${${ARTIFACT_PACKAGE}_SOURCE_DIR} PARENT_SCOPE) diff --git a/CMakeModules/Findzstd.cmake b/CMakeModules/Findzstd.cmake index bf38d20fbf..17efec2192 100644 --- a/CMakeModules/Findzstd.cmake +++ b/CMakeModules/Findzstd.cmake @@ -13,9 +13,12 @@ find_package_handle_standard_args(zstd if (zstd_FOUND AND NOT TARGET zstd::zstd) if (TARGET zstd::libzstd_shared) add_library(zstd::zstd ALIAS zstd::libzstd_shared) + add_library(zstd::libzstd ALIAS zstd::libzstd_shared) elseif (TARGET zstd::libzstd_static) add_library(zstd::zstd ALIAS zstd::libzstd_static) + add_library(zstd::libzstd ALIAS zstd::libzstd_static) else() add_library(zstd::zstd ALIAS PkgConfig::ZSTD) + add_library(zstd::libzstd ALIAS PkgConfig::ZSTD) endif() endif() diff --git a/README.md b/README.md index 1a4f017576..c78490e6d4 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ Alternatively, if you wish to add translations, go to the [Eden project on Trans See the [General Build Guide](docs/Build.md) +For information on provided development tooling, see the [Tools directory](./tools) + ## Download You can download the latest releases from [here](https://github.com/eden-emulator/Releases/releases). diff --git a/cpmfile.json b/cpmfile.json index 4cf61f0ffc..e9e53ed326 100644 --- a/cpmfile.json +++ b/cpmfile.json @@ -18,6 +18,7 @@ "hash": "4fb7f6fde92762305aad8754d7643cd918dd1f3f67e104e9ab385b18c73178d72a17321354eb203b790b6702f2cf6d725a5d6e2dfbc63b1e35f9eb59fb42ece9", "git_version": "1.89.0", "version": "1.57", + "find_args": "CONFIG", "patches": [ "0001-clang-cl.patch", "0002-use-marmasm.patch", @@ -26,12 +27,10 @@ }, "fmt": { "repo": "fmtlib/fmt", - "sha": "40626af88b", - "hash": "d59f06c24339f223de4ec2afeba1c67b5835a0f350a1ffa86242a72fc3e616a6b8b21798355428d4200c75287308b66634619ffa0b52ba5bd74cc01772ea1a8a", + "tag": "%VERSION%", + "hash": "c4ab814c20fbad7e3f0ae169125a4988a2795631194703251481dc36b18da65c886c4faa9acd046b0a295005217b3689eb0126108a9ba5aac2ca909aae263c2f", "version": "8", - "options": [ - "FMT_INSTALL OFF" - ] + "git_version": "12.0.0" }, "lz4": { "name": "lz4", @@ -43,16 +42,18 @@ "nlohmann": { "package": "nlohmann_json", "repo": "nlohmann/json", - "sha": "55f93686c0", - "hash": "b739749b066800e21154506ea150d2c5cbce8a45344177f46f884547a1399d26753166fd0df8135269ce28cf223552b1b65cd625b88c844d54753f2434900486", - "version": "3.8" + "tag": "v%VERSION%", + "hash": "6cc1e86261f8fac21cc17a33da3b6b3c3cd5c116755651642af3c9e99bb3538fd42c1bd50397a77c8fb6821bc62d90e6b91bcdde77a78f58f2416c62fc53b97d", + "version": "3.8", + "git_version": "3.12.0" }, "zlib": { "package": "ZLIB", "repo": "madler/zlib", - "sha": "51b7f2abda", - "hash": "16eaf1f3752489d12fd9ce30f7b5f7cbd5cb8ff53d617005a9847ae72d937f65e01e68be747f62d7ac19fd0c9aeba9956e60f16d6b465c5fdc2f3d08b4db2e6c", + "tag": "v%VERSION%", + "hash": "8c9642495bafd6fad4ab9fb67f09b268c69ff9af0f4f20cf15dfc18852ff1f312bd8ca41de761b3f8d8e90e77d79f2ccacd3d4c5b19e475ecf09d021fdfe9088", "version": "1.2", + "git_version": "1.3.1", "options": [ "ZLIB_BUILD_SHARED OFF", "ZLIB_INSTALL OFF" @@ -60,8 +61,8 @@ }, "zstd": { "repo": "facebook/zstd", - "sha": "f8745da6ff", - "hash": "3037007f990040fe32573b46f9bef8762fd5dbeeb07ffffcbfeba51ec98167edae39bb9c87f9299efcd61c4e467c5e84f7c19f0df7799bc1fc04864a278792ee", + "sha": "b8d6101fba", + "hash": "a6c8e5272214fd3e65e03ae4fc375f452bd2f646623886664ee23e239e35751cfc842db4d34a84a8039d89fc8f76556121f2a4ae350d017bdff5e22150f9c3de", "version": "1.5", "source_subdir": "build/cmake", "find_args": "MODULE", @@ -89,7 +90,7 @@ "llvm-mingw": { "repo": "misc/llvm-mingw", "git_host": "git.crueter.xyz", - "tag": "20250828", + "tag": "%VERSION%", "version": "20250828", "artifact": "clang-rt-builtins.tar.zst", "hash": "d902392caf94e84f223766e2cc51ca5fab6cae36ab8dc6ef9ef6a683ab1c483bfcfe291ef0bd38ab16a4ecc4078344fa8af72da2f225ab4c378dee23f6186181" diff --git a/docs/CPM.md b/docs/CPM.md deleted file mode 100644 index c01376469d..0000000000 --- a/docs/CPM.md +++ /dev/null @@ -1,258 +0,0 @@ -# CPM - -CPM (CMake Package Manager) is the preferred method of managing dependencies within Eden. - -Global Options: - -- `YUZU_USE_CPM` is set by default on MSVC and Android. Other platforms should use this if certain "required" system dependencies (e.g. OpenSSL) are broken or missing - * If this is `OFF`, required system dependencies will be searched via `find_package`, although certain externals use CPM regardless. -- `CPMUTIL_FORCE_SYSTEM` (default `OFF`): Require all CPM dependencies to use system packages. NOT RECOMMENDED! - * Many packages, e.g. mcl, sirit, xbyak, discord-rpc, are not generally available as a system package. - * You may optionally override these (see CPMUtil section) -- `CPMUTIL_FORCE_BUNDLED` (default `ON` on MSVC and Android, `OFF` elsewhere): Require all CPM dependencies to use bundled packages. - -## CPMUtil - -CPMUtil is a wrapper around CPM that aims to reduce boilerplate and add useful utility functions to make dependency management a piece of cake. - -### AddPackage - -`AddPackage` is the core of the CPMUtil wrapper, and is generally the lowest level you will need to go when dealing with dependencies. - -**Identification/Fetching** - -- `NAME` (required): The package name (must be the same as the `find_package` name if applicable) -- `VERSION`: The minimum version of this package that can be used on the system -- `GIT_VERSION`: The "version" found within git -- `URL`: The URL to fetch. -- `REPO`: The GitHub repo to use (`owner/repo`). - * Only GitHub is supported for now, though other platforms will see support at some point -- `TAG`: The tag to fetch, if applicable. -- `ARTIFACT`: The name of the artifact, if applicable. -- `SHA`: Commit sha to fetch, if applicable. -- `BRANCH`: Branch to fetch, if applicable. - -The following configurations are supported, in descending order of precedence: - -- `URL`: Bare URL download, useful for custom artifacts - * If this is set, `GIT_URL` or `REPO` should be set to allow the dependency viewer to link to the project's Git repository. - * If this is NOT set, `REPO` must be defined. -- `REPO + TAG + ARTIFACT`: GitHub release artifact - * The final download URL will be `https://github.com/${REPO}/releases/download/${TAG}/${ARTIFACT}` - * Useful for prebuilt libraries and prefetched archives -- `REPO + TAG`: GitHub tag archive - * The final download URL will be `https://github.com/${REPO}/archive/refs/tags/${TAG}.tar.gz` - * Useful for pinning to a specific tag, better for build identification -- `REPO + SHA`: GitHub commit archive - * The final download URL will be `https://github.com/${REPO}/archive/${SHA}.zip` - * Useful for pinning to a specific commit -- `REPO + BRANCH`: GitHub branch archive - * The final download URL will be `https://github.com/${REPO}/archive/refs/heads/${BRANCH}.zip` - * Generally not recommended unless the branch is frozen -- `REPO`: GitHub master archive - * The final download URL will be `https://github.com/${REPO}/archive/refs/heads/master.zip` - * Generally not recommended unless the project is dead - -**Hashing** - -Hashing is used for verifying downloads. It's highly recommended to use these. - -- `HASH_ALGO` (default `SHA512`): Hash algorithm to use - -Hashing strategies, descending order of precedence: - -- `HASH`: Bare hash verification, useful for static downloads e.g. commit archives -- `HASH_SUFFIX`: Download the hash as `${DOWNLOAD_URL}.${HASH_SUFFIX}` - * The downloaded hash *must* match the hash algorithm and contain nothing but the hash; no filenames or extra content. -- `HASH_URL`: Download the hash from a separate URL - -**Additional Options** - -- `KEY`: Custom cache key to use (stored as `.cache/cpm/${packagename_lower}/${key}`) - * Default is based on, in descending order of precedence: - - First 4 characters of the sha - - `GIT_VERSION` - - Tag - - `VERSION` - - Otherwise, CPM defaults will be used. This is not recommended as it doesn't produce reproducible caches -- `DOWNLOAD_ONLY`: Whether or not to configure the downloaded package via CMake - * Useful to turn `OFF` if the project doesn't use CMake -- `SOURCE_SUBDIR`: Subdirectory of the project containing a CMakeLists.txt file -- `FIND_PACKAGE_ARGUMENTS`: Arguments to pass to the `find_package` call -- `BUNDLED_PACKAGE`: Set to `ON` to force the usage of a bundled package -- `OPTIONS`: Options to pass to the configuration of the package -- `PATCHES`: Patches to apply to the package, stored in `.patch/${packagename_lower}/0001-patch-name.patch` and so on -- Other arguments can be passed to CPM as well - -**Extra Variables** - -For each added package, users may additionally force usage of the system/bundled package. - -- `${package}_FORCE_SYSTEM`: Require the package to be installed on the system -- `${package}_FORCE_BUNDLED`: Force the package to be fetched and use the bundled version - -**Bundled/System Switching** - -Descending order of precedence: -- If `${package}_FORCE_SYSTEM` is true, requires the package to be on the system -- If `${package}_FORCE_BUNDLED` is true, forcefully uses the bundled package -- If `CPMUTIL_FORCE_SYSTEM` is true, requires the package to be on the system -- If `CPMUTIL_FORCE_BUNDLED` is true, forcefully uses the bundled package -- If the `BUNDLED_PACKAGE` argument is true, forcefully uses the bundled package -- Otherwise, CPM will search for the package first, and if not found, will use the bundled package - -**Identification** - -All dependencies must be identifiable in some way for usage in the dependency viewer. Lists are provided in descending order of precedence. - -URLs: - -- `GIT_URL` -- `REPO` as a Git repository - * You may optionally specify `GIT_HOST` to use a custom host, e.g. `GIT_HOST git.crueter.xyz`. Note that the git host MUST be GitHub-like in its artifact/archive downloads, e.g. Forgejo - * If `GIT_HOST` is unspecified, defaults to `github.com` -- `URL` - -Versions (bundled): - -- `SHA` -- `GIT_VERSION` -- `VERSION` -- `TAG` -- "unknown" - -If the package is a system package, AddPackage will attempt to determine the package version and append ` (system)` to the identifier. Otherwise, it will be marked as `unknown (system)` - -### AddCIPackage - -Adds a package that follows crueter's CI repository spec. - -- `VERSION` (required): The version to get (the tag will be `v${VERSION}`) -- `NAME` (required): Name used within the artifacts -- `REPO` (required): CI repository, e.g. `crueter-ci/OpenSSL` -- `PACKAGE` (required): `find_package` package name -- `EXTENSION`: Artifact extension (default `tar.zst`) -- `MIN_VERSION`: Minimum version for `find_package`. Only used if platform does not support this package as a bundled artifact -- `DISABLED_PLATFORMS`: List of platforms that lack artifacts for this package. One of: - * `windows-amd64` - * `windows-arm64` - * `android` - * `solaris-amd64` - * `freebsd-amd64` - * `linux-amd64` - * `linux-aarch64` - * `macos-universal` - -### AddJsonPackage - -This is the recommended method of usage for CPMUtil. In each directory that utilizes `CPMUtil`, there must be a `cpmfile.json` that defines dependencies in a similar manner to the individual calls. - -The cpmfile is an object of objects, with each sub-object being named according to the package's identifier, e.g. `openssl`, which can then be fetched with `AddJsonPackage()`. Options are designed to map closely to the argument names, and are always strings unless otherwise specified. - -- `package` -> `NAME` (`PACKAGE` for CI), defaults to the object key -- `repo` -> `REPO` -- `version` -> `VERSION` -- `ci` (bool) - -If `ci` is `false`: - -- `hash` -> `HASH` -- `hash_suffix` -> `HASH_SUFFIX` -- `sha` -> `SHA` -- `key` -> `KEY` -- `tag` -> `TAG` - * If the tag contains `%VERSION%`, that part will be replaced by the `git_version`, OR `version` if `git_version` is not specified -- `url` -> `URL` -- `artifact` -> `ARTIFACT` - * If the artifact contains `%VERSION%`, that part will be replaced by the `git_version`, OR `version` if `git_version` is not specified - * If the artifact contains `%TAG%`, that part will be replaced by the `tag` (with its replacement already done) -- `git_version` -> `GIT_VERSION` -- `git_host` -> `GIT_HOST` -- `source_subdir` -> `SOURCE_SUBDIR` -- `bundled` -> `BUNDLED_PACKAGE` -- `find_args` -> `FIND_PACKAGE_ARGUMENTS` -- `patches` -> `PATCHES` (array) -- `options` -> `OPTIONS` (array) - -Other arguments aren't currently supported. If you wish to add them, see the `AddJsonPackage` function in `CMakeModules/CPMUtil.cmake`. - -If `ci` is `true`: - -- `name` -> `NAME`, defaults to the object key -- `extension` -> `EXTENSION`, defaults to `tar.zst` -- `min_version` -> `MIN_VERSION` -- `extension` -> `EXTENSION` - -### Examples - -In order: OpenSSL CI, Boost (tag + artifact), Opus (options + find_args), discord-rpc (sha + options + patches) - -```json -{ - "openssl": { - "ci": true, - "package": "OpenSSL", - "name": "openssl", - "repo": "crueter-ci/OpenSSL", - "version": "3.5.2", - "min_version": "1.1.1" - }, - "boost": { - "package": "Boost", - "repo": "boostorg/boost", - "tag": "boost-%VERSION%", - "artifact": "%TAG%-cmake.7z", - "hash": "e5b049e5b61964480ca816395f63f95621e66cb9bcf616a8b10e441e0e69f129e22443acb11e77bc1e8170f8e4171b9b7719891efc43699782bfcd4b3a365f01", - "git_version": "1.88.0", - "version": "1.57" - }, - "opus": { - "package": "Opus", - "repo": "xiph/opus", - "sha": "5ded705cf4", - "hash": "0dc89e58ddda1f3bc6a7037963994770c5806c10e66f5cc55c59286fc76d0544fe4eca7626772b888fd719f434bc8a92f792bdb350c807968b2ac14cfc04b203", - "version": "1.3", - "find_args": "MODULE", - "options": [ - "OPUS_BUILD_TESTING OFF", - "OPUS_BUILD_PROGRAMS OFF", - "OPUS_INSTALL_PKG_CONFIG_MODULE OFF", - "OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF" - ] - }, - "discord-rpc": { - "repo": "discord/discord-rpc", - "sha": "963aa9f3e5", - "hash": "386e1344e9a666d730f2d335ee3aef1fd05b1039febefd51aa751b705009cc764411397f3ca08dffd46205c72f75b235c870c737b2091a4ed0c3b061f5919bde", - "options": [ - "BUILD_EXAMPLES OFF" - ], - "patches": [ - "0001-cmake-version.patch", - "0002-no-clang-format.patch", - "0003-fix-cpp17.patch" - ] - }, -} -``` - -### Inclusion - -To include CPMUtil: - -```cmake -include(CPMUtil) -``` - -## Prefetching - -- To prefetch a CPM dependency (requires cpmfile): - * `tools/cpm-fetch.sh ` -- To prefetch all CPM dependencies: - * `tools/cpm-fetch-all.sh` - -Currently, `cpm-fetch.sh` defines the following directories for cpmfiles (max depth of 2, so subdirs are caught as well): - -`externals src/qt_common src/dynarmic .` - -Whenever you add a new cpmfile, update the script accordingly \ No newline at end of file diff --git a/docs/CPMUtil.md b/docs/CPMUtil.md new file mode 100644 index 0000000000..779515ae7e --- /dev/null +++ b/docs/CPMUtil.md @@ -0,0 +1,14 @@ +# CPMUtil + +CPMUtil is a wrapper around CPM that aims to reduce boilerplate and add useful utility functions to make dependency management a piece of cake. + +See more in [its repository](https://git.crueter.xyz/CMake/CPMUtil) + +Eden-specific options: + +- `YUZU_USE_CPM` is set by default on MSVC and Android. Other platforms should use this if certain "required" system dependencies (e.g. OpenSSL) are broken or missing + * If this is `OFF`, required system dependencies will be searched via `find_package`, although most externals use CPM regardless. + +## Tooling + +See the [tooling docs](../tools/cpm) \ No newline at end of file diff --git a/docs/Deps.md b/docs/Deps.md index 573d1fe14a..b8a1be66d2 100644 --- a/docs/Deps.md +++ b/docs/Deps.md @@ -63,6 +63,7 @@ Certain other dependencies will be fetched by CPM regardless. System packages *c * [VulkanMemoryAllocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator) * [sirit](https://github.com/eden-emulator/sirit) * [httplib](https://github.com/yhirose/cpp-httplib) - if `ENABLE_QT_UPDATE_CHECKER` or `ENABLE_WEB_SERVICE` are on + - This package is known to be broken on the AUR. * [cpp-jwt](https://github.com/arun11299/cpp-jwt) 1.4+ - if `ENABLE_WEB_SERVICE` is on * [unordered-dense](https://github.com/martinus/unordered_dense) * [mcl](https://github.com/azahar-emu/mcl) - subject to removal @@ -194,7 +195,7 @@ Run the usual update + install of essential toolings: `sudo pkg update && sudo p - **gcc**: `sudo pkg install developer/gcc-14`. - **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`. -Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`. +Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/lz4 libusb-1 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`.
diff --git a/docs/README.md b/docs/README.md index 71e79e15ea..49617fa43a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,6 +5,6 @@ This contains documentation created by developers. This contains build instructi - **[General Build Instructions](Build.md)** - **[Development Guidelines](Development.md)** - **[Dependencies](Deps.md)** -- **[CPM - CMake Package Manager](CPM.md)** +- **[CPM - CMake Package Manager](CPMUtil.md)** - **[Platform-Specific Caveats](Caveats.md)** - **[User Directory Handling](User.md)** \ No newline at end of file diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index f22b8753f8..434e6fb100 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -148,20 +148,21 @@ if (ENABLE_SDL2) endif() # SPIRV Headers -# We only need SPIRV-Headers iff spirv-tools is bundled -if (SPIRV-Tools_FORCE_BUNDLED OR CPMUTIL_FORCE_BUNDLED) - set(NEED_SPIRV_HEADERS ON) -else() - find_package(SPIRV-Tools MODULE QUIET) - if (NOT SPIRV-Tools_FOUND) - set(NEED_SPIRV_HEADERS ON) - else() - set(NEED_SPIRV_HEADERS OFF) - endif() -endif() +AddJsonPackage(spirv-headers) -if (NEED_SPIRV_HEADERS) - AddJsonPackage(spirv-headers) +# Sirit +if (YUZU_USE_BUNDLED_SIRIT) + AddJsonPackage(sirit-ci) +else() + AddJsonPackage(sirit) + if(MSVC AND USE_CCACHE AND sirit_ADDED) + get_target_property(_opts sirit COMPILE_OPTIONS) + list(FILTER _opts EXCLUDE REGEX "/Zi") + list(APPEND _opts "/Z7") + set_target_properties(siritobj PROPERTIES COMPILE_OPTIONS "${_opts}") + elseif(MSVC AND CXX_CLANG) + target_compile_options(siritobj PRIVATE -Wno-error=unused-command-line-argument) + endif() endif() # SPIRV Tools @@ -205,21 +206,6 @@ if (VulkanMemoryAllocator_ADDED) endif() endif() -# Sirit -if (YUZU_USE_BUNDLED_SIRIT) - AddJsonPackage(sirit-ci) -else() - AddJsonPackage(sirit) - if(MSVC AND USE_CCACHE AND sirit_ADDED) - get_target_property(_opts sirit COMPILE_OPTIONS) - list(FILTER _opts EXCLUDE REGEX "/Zi") - list(APPEND _opts "/Z7") - set_target_properties(siritobj PROPERTIES COMPILE_OPTIONS "${_opts}") - elseif(MSVC AND CXX_CLANG) - target_compile_options(siritobj PRIVATE -Wno-error=unused-command-line-argument) - endif() -endif() - # httplib if (ENABLE_WEB_SERVICE OR ENABLE_QT_UPDATE_CHECKER) AddJsonPackage(httplib) diff --git a/externals/cpmfile.json b/externals/cpmfile.json index cb32a75ed5..aa3a97c128 100644 --- a/externals/cpmfile.json +++ b/externals/cpmfile.json @@ -2,29 +2,34 @@ "vulkan-memory-allocator": { "package": "VulkanMemoryAllocator", "repo": "GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator", - "sha": "1076b348ab", - "hash": "a46b44e4286d08cffda058e856c47f44c7fed3da55fe9555976eb3907fdcc20ead0b1860b0c38319cda01dbf9b1aa5d4b4038c7f1f8fbd97283d837fa9af9772", - "find_args": "CONFIG" + "tag": "v%VERSION%", + "hash": "deb5902ef8db0e329fbd5f3f4385eb0e26bdd9f14f3a2334823fb3fe18f36bc5d235d620d6e5f6fe3551ec3ea7038638899db8778c09f6d5c278f5ff95c3344b", + "find_args": "CONFIG", + "git_version": "3.3.0" }, "sirit": { "repo": "eden-emulator/sirit", - "version": "1.0.1", + "git_version": "1.0.2", "tag": "v%VERSION%", "artifact": "sirit-source-%VERSION%.tar.zst", "hash_suffix": "sha512sum", - "find_args": "CONFIG" + "find_args": "CONFIG", + "options": [ + "SIRIT_USE_SYSTEM_SPIRV_HEADERS ON" + ] }, "sirit-ci": { "ci": true, "package": "sirit", "name": "sirit", "repo": "eden-emulator/sirit", - "version": "1.0.0" + "version": "1.0.2" }, "httplib": { "repo": "yhirose/cpp-httplib", - "sha": "a609330e4c", - "hash": "dd3fd0572f8367d8549e1319fd98368b3e75801a293b0c3ac9b4adb806473a4506a484b3d389dc5bee5acc460cb90af7a20e5df705a1696b56496b30b9ce7ed2" + "tag": "v%VERSION%", + "hash": "b364500f76e2ecb0fe21b032d831272e3f1dfeea71af74e325f8fc4ce9dcdb3c941b97a5b422bdeafb9facd058597b90f8bfc284fb9afe3c33fefa15dd5a010b", + "git_version": "0.26.0" }, "cpp-jwt": { "version": "1.4", @@ -39,22 +44,26 @@ "xbyak_sun": { "package": "xbyak", "repo": "herumi/xbyak", - "sha": "9bb219333a", - "hash": "303165d45c8c19387ec49d9fda7d7a4e0d86d4c0153898c23f25ce2d58ece567f44c0bbbfe348239b933edb6e1a1e34f4bc1c0ab3a285bee5da0e548879387b0", - "bundled": true + "tag": "v%VERSION%", + "hash": "e84992c65ad62c577e2746ec5180132fd2875166d1e6b1521a0ff619787e1645792fe5f6a858fe94ed66f297912b6a6b89a509b5d5f5e81a2db1dd7e6790b1f5", + "bundled": true, + "git_version": "7.30" }, "xbyak": { "package": "xbyak", "repo": "herumi/xbyak", - "sha": "4e44f4614d", - "hash": "5824e92159e07fa36a774aedd3b3ef3541d0241371d522cffa4ab3e1f215fa5097b1b77865b47b2481376c704fa079875557ea463ca63d0a7fd6a8a20a589e70", - "bundled": true + "tag": "v%VERSION%", + "hash": "1042090405c426e339506c179d53e91d4d545ce9c9f53d8f797caa092d589f913a9bcb9c8f31c4c60870acb954c556e305fb6732c66bc3c8f1cd924f9172def9", + "git_version": "7.22", + "bundled": true, + "skip_updates": true }, "oaknut": { + "repo": "eden-emulator/oaknut", "version": "2.0.1", - "repo": "merryhime/oaknut", - "sha": "94c726ce03", - "hash": "d8d082242fa1881abce3c82f8dafa002c4e561e66a69e7fc038af67faa5eff2630f082d3d19579c88c4c9f9488e54552accc8cb90e7ce743efe043b6230c08ac" + "git_version": "2.0.3", + "tag": "v%VERSION%", + "hash": "9697e80a7d5d9bcb3ce51051a9a24962fb90ca79d215f1f03ae6b58da8ba13a63b5dda1b4dde3d26ac6445029696b8ef2883f4e5a777b342bba01283ed293856" }, "libadrenotools": { "repo": "bylaws/libadrenotools", @@ -66,16 +75,18 @@ }, "oboe": { "repo": "google/oboe", - "sha": "2bc873e53c", - "hash": "02329058a7f9cf7d5039afaae5ab170d9f42f60f4c01e21eaf4f46073886922b057a9ae30eeac040b3ac182f51b9c1bfe9fe1050a2c9f6ce567a1a9a0ec2c768", + "tag": "%VERSION%", + "hash": "ce4011afe7345370d4ead3b891cd69a5ef224b129535783586c0ca75051d303ed446e6c7f10bde8da31fff58d6e307f1732a3ffd03b249f9ef1fd48fd4132715", + "git_version": "1.10.0", "bundled": true }, "unordered-dense": { "package": "unordered_dense", "repo": "martinus/unordered_dense", - "sha": "73f3cbb237", - "hash": "c08c03063938339d61392b687562909c1a92615b6ef39ec8df19ea472aa6b6478e70d7d5e33d4a27b5d23f7806daf57fe1bacb8124c8a945c918c7663a9e8532", - "find_args": "CONFIG" + "tag": "v%VERSION%", + "hash": "f9c819e28e1c1a387acfee09277d6af5e366597a0d39acf1c687acf0608a941ba966af8aaebdb8fba0126c7360269c4a51754ef4cab17c35c01a30215f953368", + "find_args": "CONFIG", + "git_version": "4.5.0" }, "mbedtls": { "package": "MbedTLS", @@ -84,29 +95,32 @@ "hash": "6671fb8fcaa832e5b115dfdce8f78baa6a4aea71f5c89a640583634cdee27aefe3bf4be075744da91f7c3ae5ea4e0c765c8fc3937b5cfd9ea73d87ef496524da", "version": "3", "git_version": "3.6.4", - "artifact": "%TAG%.tar.bz2" + "artifact": "%TAG%.tar.bz2", + "skip_updates": true }, "enet": { "repo": "lsalzman/enet", - "sha": "2662c0de09", - "hash": "3de1beb4fa3d6b1e03eda8dd1e7580694f854af3ed3975dcdabfdcdf76b97f322b9734d35ea7f185855bb490d957842b938b26da4dd2dfded509390f8d2794dd", + "tag": "v%VERSION%", + "hash": "a0d2fa8c957704dd49e00a726284ac5ca034b50b00d2b20a94fa1bbfbb80841467834bfdc84aa0ed0d6aab894608fd6c86c3b94eee46343f0e6d9c22e391dbf9", "version": "1.3", + "git_version": "1.3.18", "find_args": "MODULE" }, "vulkan-utility-headers": { "package": "VulkanUtilityLibraries", "repo": "scripts/VulkanUtilityHeaders", - "tag": "1.4.326", + "tag": "%VERSION%", + "git_version": "1.4.328", "artifact": "VulkanUtilityHeaders.tar.zst", "git_host": "git.crueter.xyz", - "hash": "5924629755cb1605c4aa4eee20ef7957a9dd8d61e4df548be656d98054f2730c4109693c1bd35811f401f4705d2ccff9fc849be32b0d8480bc3f73541a5e0964" + "hash": "9922217b39faf73cd4fc1510f2fdba14a49aa5c0d77f9ee24ee0512cef16b234d0cabc83c1fec861fa5df1d43e7f086ca9b6501753899119f39c5ca530cb0dae" }, - "spirv-tools": { + "spirv-tools": { "package": "SPIRV-Tools", "repo": "KhronosGroup/SPIRV-Tools", - "sha": "40eb301f32", - "hash": "58d0fb1047d69373cf24c73e6f78c73a72a6cca3b4df1d9f083b9dcc0962745ef154abf3dbe9b3623b835be20c6ec769431cf11733349f45e7568b3525f707aa", - "find_args": "MODULE", + "tag": "v%VERSION%", + "hash": "b17940433ced72e004c5eeffd7dd411b6afcc6a52ee31de6427d88edceb8172369be8ec8bf5b65708a78bf41fdae264d554aa7750b2209831679ab36bc867567", + "git_version": "2025.4", "options": [ "SPIRV_SKIP_EXECUTABLES ON" ] @@ -114,8 +128,8 @@ "spirv-headers": { "package": "SPIRV-Headers", "repo": "KhronosGroup/SPIRV-Headers", - "sha": "4e209d3d7e", - "hash": "f48bbe18341ed55ea0fe280dbbbc0a44bf222278de6e716e143ca1e95ca320b06d4d23d6583fbf8d03e1428f3dac8fa00e5b82ddcd6b425e6236d85af09550a4", + "sha": "01e0577914", + "hash": "d0f905311faf7d743de686fdf241dc4cb0a4f08e2184f5a3b3b2946e680db3cd89eeb72954eafe6fa457f93550e27d516575c8709cb134d8aecc0b43064636ce", "options": [ "SPIRV_WERROR OFF" ] @@ -132,35 +146,6 @@ "BUNDLE_SPEEX ON" ] }, - "discord-rpc": { - "package": "DiscordRPC", - "repo": "eden-emulator/discord-rpc", - "sha": "1cf7772bb6", - "hash": "e9b35e6f2c075823257bcd59f06fe7bb2ccce1976f44818d2e28810435ef79c712a3c4f20f40da41f691342a4058cf86b078eb7f9d9e4dae83c0547c21ec4f97" - }, - "simpleini": { - "package": "SimpleIni", - "repo": "brofield/simpleini", - "sha": "09c21bda1d", - "hash": "99779ca9b6e040d36558cadf484f9ffdab5b47bcc8fc72e4d33639d1d60c0ceb4410d335ba445d72a4324e455167fd6769d99b459943aa135bec085dff2d4b7c", - "find_args": "MODULE" - }, - "sdl2_generic": { - "package": "SDL2", - "repo": "libsdl-org/SDL", - "sha": "54772f345a", - "hash": "2a68a0e01c390043aa9d9df63d8a20a52076c88bb460ac4e0f33194ca7d9bc8fadbbcc04e7506872ac4b6354a73fbc267c036f82200da59465789b87c7d9e3a4", - "key": "generic", - "bundled": true - }, - "sdl2_steamdeck": { - "package": "SDL2", - "repo": "libsdl-org/SDL", - "sha": "cc016b0046", - "hash": "34d5ef58da6a4f9efa6689c82f67badcbd741f5a4f562a9c2c30828fa839830fb07681c5dc6a7851520e261c8405a416ac0a2c2513b51984fb3b4fa4dcb3e20b", - "key": "steamdeck", - "bundled": true - }, "sdl2": { "ci": true, "package": "SDL2", @@ -175,8 +160,43 @@ "catch2": { "package": "Catch2", "repo": "catchorg/Catch2", - "sha": "644821ce28", - "hash": "f8795f98acf2c02c0db8e734cc866d5caebab4b4a306e93598b97cb3c0c728dafe8283dce27ffe8d42460e5ae7302f3f32e7e274a7f991b73511ac88eef21b1f", - "version": "3.0.1" + "tag": "v%VERSION%", + "hash": "a95495142f915d6e9c2a23e80fe360343e9097680066a2f9d3037a070ba5f81ee5559a0407cc9e972dc2afae325873f1fc7ea07a64012c0f01aac6e549f03e3f", + "version": "3.0.1", + "git_version": "3.11.0" + }, + "discord-rpc": { + "package": "DiscordRPC", + "repo": "eden-emulator/discord-rpc", + "sha": "1cf7772bb6", + "hash": "e9b35e6f2c075823257bcd59f06fe7bb2ccce1976f44818d2e28810435ef79c712a3c4f20f40da41f691342a4058cf86b078eb7f9d9e4dae83c0547c21ec4f97", + "find_args": "MODULE" + }, + "simpleini": { + "package": "SimpleIni", + "repo": "brofield/simpleini", + "tag": "v%VERSION%", + "hash": "6c198636816a0018adbf7f735d402c64245c6fcd540b7360d4388d46f007f3a520686cdaec4705cb8cb31401b2cb4797a80b42ea5d08a6a5807c0848386f7ca1", + "find_args": "MODULE", + "git_version": "4.22" + }, + "sdl2_generic": { + "package": "SDL2", + "repo": "libsdl-org/SDL", + "tag": "release-%VERSION%", + "hash": "d5622d6bb7266f7942a7b8ad43e8a22524893bf0c2ea1af91204838d9b78d32768843f6faa248757427b8404b8c6443776d4afa6b672cd8571a4e0c03a829383", + "key": "generic", + "bundled": true, + "git_version": "2.32.10", + "skip_updates": true + }, + "sdl2_steamdeck": { + "package": "SDL2", + "repo": "libsdl-org/SDL", + "sha": "cc016b0046", + "hash": "34d5ef58da6a4f9efa6689c82f67badcbd741f5a4f562a9c2c30828fa839830fb07681c5dc6a7851520e261c8405a416ac0a2c2513b51984fb3b4fa4dcb3e20b", + "key": "steamdeck", + "bundled": true, + "skip_updates": "true" } } diff --git a/externals/ffmpeg/cpmfile.json b/externals/ffmpeg/cpmfile.json index ff48ce742d..a4933da275 100644 --- a/externals/ffmpeg/cpmfile.json +++ b/externals/ffmpeg/cpmfile.json @@ -5,17 +5,17 @@ "hash": "2a89d664119debbb3c006ab1c48d5d7f26e889f4a65ad2e25c8b0503308295123d5a9c5c78bf683aef5ff09acef8c3fc2837f22d3e8c611528b933bf03bcdd97", "bundled": true }, - "ffmpeg-ci": { + "ffmpeg-ci": { "ci": true, "package": "FFmpeg", "name": "ffmpeg", "repo": "crueter-ci/FFmpeg", "version": "8.0", "min_version": "4.1", - "disabled_platforms": [ - "freebsd-amd64", - "solaris-amd64", + "disabled_platforms": [ + "freebsd-amd64", + "solaris-amd64", "macos-universal" - ] + ] } } diff --git a/externals/libusb/CMakeLists.txt b/externals/libusb/CMakeLists.txt index 77a762d070..a53464ea98 100644 --- a/externals/libusb/CMakeLists.txt +++ b/externals/libusb/CMakeLists.txt @@ -6,18 +6,7 @@ include(CPMUtil) -# we love our libraries don't we folks -if (PLATFORM_SUN) - set(libusb_bundled ON) -else() - set(libusb_bundled OFF) -endif() - -# TODO(crueter): Fix on Solaris -AddJsonPackage( - NAME libusb - BUNDLED_PACKAGE ${libusb_bundled} -) +AddJsonPackage(libusb) if (NOT libusb_ADDED) return() diff --git a/externals/libusb/cpmfile.json b/externals/libusb/cpmfile.json index 0bfa0d7a86..dc69841ab7 100644 --- a/externals/libusb/cpmfile.json +++ b/externals/libusb/cpmfile.json @@ -1,8 +1,9 @@ { - "libusb": { - "repo": "libusb/libusb", - "sha": "c060e9ce30", - "hash": "44647357ba1179020cfa6674d809fc35cf6f89bff1c57252fe3a610110f5013ad678fc6eb5918e751d4384c30e2fe678868dbffc5f85736157e546cb9d10accc", - "find_args": "MODULE" - } -} \ No newline at end of file + "libusb": { + "repo": "libusb/libusb", + "tag": "v%VERSION%", + "hash": "98c5f7940ff06b25c9aa65aa98e23de4c79a4c1067595f4c73cc145af23a1c286639e1ba11185cd91bab702081f307b973f08a4c9746576dc8d01b3620a3aeb5", + "find_args": "MODULE", + "git_version": "1.0.29" + } +} diff --git a/src/common/common_types.h b/src/common/common_types.h index 99fff66bed..6e7e4ec0d9 100644 --- a/src/common/common_types.h +++ b/src/common/common_types.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2012 Gekko Emulator // SPDX-FileContributor: ShizZy // SPDX-License-Identifier: GPL-2.0-or-later @@ -30,7 +33,6 @@ #include #include -#include using u8 = std::uint8_t; ///< 8-bit unsigned byte using u16 = std::uint16_t; ///< 16-bit unsigned short diff --git a/src/core/frontend/applets/cabinet.h b/src/core/frontend/applets/cabinet.h index af3fc6c3d5..157bfe38c6 100644 --- a/src/core/frontend/applets/cabinet.h +++ b/src/core/frontend/applets/cabinet.h @@ -1,9 +1,14 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include +#include + #include "core/frontend/applets/applet.h" #include "core/hle/service/nfp/nfp_types.h" diff --git a/src/core/memory/dmnt_cheat_vm.h b/src/core/memory/dmnt_cheat_vm.h index 1c1ed1259b..de5e81add2 100644 --- a/src/core/memory/dmnt_cheat_vm.h +++ b/src/core/memory/dmnt_cheat_vm.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -5,6 +8,8 @@ #include #include +#include + #include #include "common/common_types.h" #include "core/memory/dmnt_cheat_types.h" diff --git a/src/dynarmic/externals/cpmfile.json b/src/dynarmic/externals/cpmfile.json index 718163baf5..099ded57a4 100644 --- a/src/dynarmic/externals/cpmfile.json +++ b/src/dynarmic/externals/cpmfile.json @@ -1,9 +1,10 @@ { "biscuit": { - "version": "0.9.1", "repo": "lioncash/biscuit", - "sha": "76b0be8dae", - "hash": "47d55ed02d032d6cf3dc107c6c0a9aea686d5f25aefb81d1af91db027b6815bd5add1755505e19d76625feeb17aa2db6cd1668fe0dad2e6a411519bde6ca4489" + "tag": "v%VERSION%", + "hash": "1229f345b014f7ca544dedb4edb3311e41ba736f9aa9a67f88b5f26f3c983288c6bb6cdedcfb0b8a02c63088a37e6a0d7ba97d9c2a4d721b213916327cffe28a", + "version": "0.9.1", + "git_version": "0.19.0" }, "mcl": { "version": "0.1.12", diff --git a/src/dynarmic/src/dynarmic/CMakeLists.txt b/src/dynarmic/src/dynarmic/CMakeLists.txt index 58efcac747..8aa0f41afa 100644 --- a/src/dynarmic/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/src/dynarmic/CMakeLists.txt @@ -2,7 +2,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later include(TargetArchitectureSpecificSources) -add_library(dynarmic +add_library(dynarmic STATIC backend/block_range_information.cpp backend/block_range_information.h backend/exception_handler.h diff --git a/src/dynarmic/src/dynarmic/common/common_types.h b/src/dynarmic/src/dynarmic/common/common_types.h index 8127df3623..711418d97f 100644 --- a/src/dynarmic/src/dynarmic/common/common_types.h +++ b/src/dynarmic/src/dynarmic/common/common_types.h @@ -1,9 +1,12 @@ // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +// TODO(crueter): This is identical to root common_types.h + #pragma once #include +#include #include using u8 = std::uint8_t; ///< 8-bit unsigned byte diff --git a/src/hid_core/resources/applet_resource.h b/src/hid_core/resources/applet_resource.h index 69ea46b957..4b7584b962 100644 --- a/src/hid_core/resources/applet_resource.h +++ b/src/hid_core/resources/applet_resource.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -5,6 +8,7 @@ #include #include +#include #include "common/bit_field.h" #include "common/common_types.h" diff --git a/src/hid_core/resources/npad/npad_vibration.h b/src/hid_core/resources/npad/npad_vibration.h index 6412ca4ab0..59e29b9f90 100644 --- a/src/hid_core/resources/npad/npad_vibration.h +++ b/src/hid_core/resources/npad/npad_vibration.h @@ -1,9 +1,13 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once #include +#include #include "common/common_types.h" #include "core/hle/result.h" diff --git a/src/hid_core/resources/touch_screen/gesture.h b/src/hid_core/resources/touch_screen/gesture.h index d92912bb6e..3fa1933fe8 100644 --- a/src/hid_core/resources/touch_screen/gesture.h +++ b/src/hid_core/resources/touch_screen/gesture.h @@ -1,9 +1,13 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once #include +#include #include "common/common_types.h" #include "core/hle/result.h" diff --git a/src/hid_core/resources/touch_screen/touch_screen.h b/src/hid_core/resources/touch_screen/touch_screen.h index 2fcb6247f1..f56f7b3839 100644 --- a/src/hid_core/resources/touch_screen/touch_screen.h +++ b/src/hid_core/resources/touch_screen/touch_screen.h @@ -1,9 +1,13 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once #include +#include #include "common/common_types.h" #include "core/hle/result.h" diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 4d5238643c..901a39cc9f 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -95,9 +95,10 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include #include -#ifdef HAVE_SDL2 #include #include + +#ifdef HAVE_SDL2 #include // For SDL ScreenSaver functions #endif diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000000..9abd96175b --- /dev/null +++ b/tools/README.md @@ -0,0 +1,21 @@ +# Tools + +Tools for Eden and other subprojects. + +## Third-Party + +- [CPMUtil Scripts](./cpm) + +## Eden + +- `shellcheck.sh`: Ensure POSIX compliance (and syntax sanity) for all tools in this directory and subdirectories. +- `llvmpipe-run.sh`: Sets environment variables needed to run any command (or Eden) with llvmpipe. +- `optimize-assets.sh`: Optimize PNG assets with OptiPng. +- `update-cpm.sh`: Updates CPM.cmake to the latest version. +- `update-icons.sh`: Rebuild all icons (macOS, Windows, bitmaps) based on the master SVG file (`dist/dev.eden_emu.eden.svg`) + * Also optimizes the master SVG + * Requires: `png2icns` (libicns), ImageMagick, [`svgo`](https://github.com/svg/svgo) +- `dtrace-tool.sh` +- `lanczos_gen.c` +- `clang-format.sh`: Runs `clang-format` on the entire codebase. + * Requires: clang diff --git a/tools/clang-format.sh b/tools/clang-format.sh index 77c3c847ad..2deb0a3ade 100755 --- a/tools/clang-format.sh +++ b/tools/clang-format.sh @@ -1,3 +1,6 @@ #! /bin/sh -exec find src -iname *.h -o -iname *.cpp | xargs clang-format-15 -i -style=file:src/.clang-format +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + +exec find src -iname "*.h" -o -iname "*.cpp" | xargs clang-format -i -style=file:src/.clang-format diff --git a/tools/cpm-fetch-all.sh b/tools/cpm-fetch-all.sh old mode 100755 new mode 100644 index 9d5005ec44..1e7ff92a67 --- a/tools/cpm-fetch-all.sh +++ b/tools/cpm-fetch-all.sh @@ -1,4 +1,4 @@ -#!/bin/bash -ex +#!/bin/sh -e # SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later @@ -6,6 +6,12 @@ # SPDX-FileCopyrightText: 2025 crueter # SPDX-License-Identifier: GPL-3.0-or-later -LIBS=$(find . src -maxdepth 3 -name cpmfile.json -exec jq -j 'keys_unsorted | join(" ")' {} \; -printf " ") +# provided for workflow compat -tools/cpm-fetch.sh $LIBS \ No newline at end of file +# shellcheck disable=SC1091 +. tools/cpm/common.sh + +chmod +x tools/cpm/fetch.sh + +# shellcheck disable=SC2086 +tools/cpm/fetch.sh $LIBS diff --git a/tools/cpm-fetch.sh b/tools/cpm-fetch.sh deleted file mode 100755 index 0219845707..0000000000 --- a/tools/cpm-fetch.sh +++ /dev/null @@ -1,236 +0,0 @@ -#!/bin/bash -e - -# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -# SPDX-License-Identifier: GPL-3.0-or-later - -# SPDX-FileCopyrightText: 2025 crueter -# SPDX-License-Identifier: GPL-3.0-or-later - -[ -z "$CPM_SOURCE_CACHE" ] && CPM_SOURCE_CACHE=$PWD/.cache/cpm - -mkdir -p $CPM_SOURCE_CACHE - -ROOTDIR="$PWD" - -TMP=$(mktemp -d) - -download_package() { - FILENAME=$(basename "$DOWNLOAD") - - OUTFILE="$TMP/$FILENAME" - - LOWER_PACKAGE=$(tr '[:upper:]' '[:lower:]' <<< "$PACKAGE_NAME") - OUTDIR="${CPM_SOURCE_CACHE}/${LOWER_PACKAGE}/${KEY}" - [ -d "$OUTDIR" ] && return - - curl "$DOWNLOAD" -sS -L -o "$OUTFILE" - - ACTUAL_HASH=$(${HASH_ALGO}sum "$OUTFILE" | cut -d" " -f1) - [ "$ACTUAL_HASH" != "$HASH" ] && echo "!! $FILENAME did not match expected hash; expected $HASH but got $ACTUAL_HASH" && exit 1 - - mkdir -p "$OUTDIR" - - pushd "$OUTDIR" > /dev/null - - case "$FILENAME" in - (*.7z) - 7z x "$OUTFILE" > /dev/null - ;; - (*.tar*) - tar xf "$OUTFILE" > /dev/null - ;; - (*.zip) - unzip "$OUTFILE" > /dev/null - ;; - esac - - # basically if only one real item exists at the top we just move everything from there - # since github and some vendors hate me - DIRS=$(find -maxdepth 1 -type d -o -type f) - - # thanks gnu - if [ $(wc -l <<< "$DIRS") -eq 2 ]; then - SUBDIR=$(find . -maxdepth 1 -type d -not -name ".") - mv "$SUBDIR"/* . - mv "$SUBDIR"/.* . 2>/dev/null || true - rmdir "$SUBDIR" - fi - - if grep -e "patches" <<< "$JSON" > /dev/null; then - PATCHES=$(jq -r '.patches | join(" ")' <<< "$JSON") - for patch in $PATCHES; do - patch --binary -p1 < "$ROOTDIR"/.patch/$package/$patch - done - fi - - popd > /dev/null -} - -ci_package() { - REPO=$(jq -r ".repo" <<< "$JSON") - EXT=$(jq -r '.extension' <<< "$JSON") - [ "$EXT" = null ] && EXT="tar.zst" - - VERSION=$(jq -r ".version" <<< "$JSON") - - NAME=$(jq -r ".name" <<< "$JSON") - [ "$NAME" = null ] && NAME="$PACKAGE" - - PACKAGE=$(jq -r ".package | \"$package\"" <<< "$JSON") - - DISABLED=$(jq -j '.disabled_platforms' <<< "$JSON") - - [ "$REPO" = null ] && echo "No repo defined for CI package $package" && return - - echo "-- CI package $PACKAGE" - - for platform in windows-amd64 windows-arm64 android solaris-amd64 freebsd-amd64 linux-amd64 linux-aarch64 macos-universal; do - echo "-- * platform $platform" - - case $DISABLED in - (*"$platform"*) - echo "-- * -- disabled" - continue - ;; - (*) ;; - esac - - FILENAME="${NAME}-${platform}-${VERSION}.${EXT}" - DOWNLOAD="https://$GIT_HOST/${REPO}/releases/download/v${VERSION}/${FILENAME}" - PACKAGE_NAME="$PACKAGE" - KEY=$platform - - LOWER_PACKAGE=$(tr '[:upper:]' '[:lower:]' <<< "$PACKAGE_NAME") - OUTDIR="${CPM_SOURCE_CACHE}/${LOWER_PACKAGE}/${KEY}" - [ -d "$OUTDIR" ] && continue - - HASH_ALGO=$(jq -r ".hash_algo" <<< "$JSON") - [ "$HASH_ALGO" = null ] && HASH_ALGO=sha512 - - HASH_SUFFIX="${HASH_ALGO}sum" - HASH_URL="${DOWNLOAD}.${HASH_SUFFIX}" - - HASH=$(curl "$HASH_URL" -sS -q -L -o -) - - download_package - done -} - -for package in $@ -do - # prepare for cancer - # TODO(crueter): Fetch json once? - JSON=$(find . src -maxdepth 3 -name cpmfile.json -exec jq -r ".\"$package\" | select( . != null )" {} \;) - - [ -z "$JSON" ] && echo "!! No cpmfile definition for $package" && continue - - PACKAGE_NAME=$(jq -r ".package" <<< "$JSON") - [ "$PACKAGE_NAME" = null ] && PACKAGE_NAME="$package" - - GIT_HOST=$(jq -r ".git_host" <<< "$JSON") - [ "$GIT_HOST" = null ] && GIT_HOST=github.com - REPO=$(jq -r ".repo" <<< "$JSON") - - CI=$(jq -r ".ci" <<< "$JSON") - if [ "$CI" != null ]; then - ci_package - continue - fi - - VERSION=$(jq -r ".version" <<< "$JSON") - GIT_VERSION=$(jq -r ".git_version" <<< "$JSON") - TAG=$(jq -r ".tag" <<< "$JSON") - SHA=$(jq -r ".sha" <<< "$JSON") - - [ "$GIT_VERSION" = null ] && GIT_VERSION="$VERSION" - [ "$GIT_VERSION" = null ] && GIT_VERSION="$TAG" - - # url parsing WOOOHOOHOHOOHOHOH - URL=$(jq -r ".url" <<< "$JSON") - SHA=$(jq -r ".sha" <<< "$JSON") - - VERSION=$(jq -r ".version" <<< "$JSON") - GIT_VERSION=$(jq -r ".git_version" <<< "$JSON") - - if [ "$GIT_VERSION" != null ]; then - VERSION_REPLACE="$GIT_VERSION" - else - VERSION_REPLACE="$VERSION" - fi - - TAG=$(jq -r ".tag" <<< "$JSON") - - TAG=$(sed "s/%VERSION%/$VERSION_REPLACE/" <<< $TAG) - - ARTIFACT=$(jq -r ".artifact" <<< "$JSON") - ARTIFACT=$(sed "s/%VERSION%/$VERSION_REPLACE/" <<< $ARTIFACT) - ARTIFACT=$(sed "s/%TAG%/$TAG/" <<< $ARTIFACT) - - if [ "$URL" != "null" ]; then - DOWNLOAD="$URL" - elif [ "$REPO" != "null" ]; then - GIT_URL="https://$GIT_HOST/$REPO" - - BRANCH=$(jq -r ".branch" <<< "$JSON") - - if [ "$TAG" != "null" ]; then - if [ "$ARTIFACT" != "null" ]; then - DOWNLOAD="${GIT_URL}/releases/download/${TAG}/${ARTIFACT}" - else - DOWNLOAD="${GIT_URL}/archive/refs/tags/${TAG}.tar.gz" - fi - elif [ "$SHA" != "null" ]; then - DOWNLOAD="${GIT_URL}/archive/${SHA}.zip" - else - if [ "$BRANCH" = null ]; then - BRANCH=master - fi - - DOWNLOAD="${GIT_URL}/archive/refs/heads/${BRANCH}.zip" - fi - else - echo "!! No repo or URL defined for $package" - continue - fi - - # key parsing - KEY=$(jq -r ".key" <<< "$JSON") - - if [ "$KEY" = null ]; then - if [ "$SHA" != null ]; then - KEY=$(cut -c1-4 - <<< "$SHA") - elif [ "$GIT_VERSION" != null ]; then - KEY="$GIT_VERSION" - elif [ "$TAG" != null ]; then - KEY="$TAG" - elif [ "$VERSION" != null ]; then - KEY="$VERSION" - else - echo "!! No valid key could be determined for $package. Must define one of: key, sha, tag, version, git_version" - continue - fi - fi - - echo "-- Downloading regular package $package, with key $KEY, from $DOWNLOAD" - - # hash parsing - HASH_ALGO=$(jq -r ".hash_algo" <<< "$JSON") - [ "$HASH_ALGO" = null ] && HASH_ALGO=sha512 - - HASH=$(jq -r ".hash" <<< "$JSON") - - if [ "$HASH" = null ]; then - HASH_SUFFIX="${HASH_ALGO}sum" - HASH_URL=$(jq -r ".hash_url" <<< "$JSON") - - if [ "$HASH_URL" = null ]; then - HASH_URL="${DOWNLOAD}.${HASH_SUFFIX}" - fi - - HASH=$(curl "$HASH_URL" -sS -L -o -) - fi - - download_package -done - -rm -rf $TMP \ No newline at end of file diff --git a/tools/cpm-hash.sh b/tools/cpm-hash.sh deleted file mode 100755 index da0fb395db..0000000000 --- a/tools/cpm-hash.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -SUM=`wget -q https://github.com/$1/archive/$2.zip -O - | sha512sum` -echo "$SUM" | cut -d " " -f1 diff --git a/tools/cpm/README.md b/tools/cpm/README.md new file mode 100755 index 0000000000..acd7444518 --- /dev/null +++ b/tools/cpm/README.md @@ -0,0 +1,71 @@ +# CPMUtil Tools + +These are supplemental shell scripts for CPMUtil aiming to ease maintenance burden for sanity checking, updates, prefetching, formatting, and standard operations done by these shell scripts, all in one common place. + +All scripts are POSIX-compliant. + +## Meta + +These scripts are generally reserved for internal use. + +- `common.sh`: Grabs all available cpmfiles and aggregates them together. + * Outputs: + - `PACKAGES`: The aggregated cpmfile + - `LIBS`: The list of individual libraries contained within each cpmfile + - `value`: A function that grabs a key from the `JSON` variable (typically the package key) +- `download.sh`: Utility script to handle downloading of regular and CI packages. + * Generally only used by the fetch scripts. +- `package.sh`: The actual package parser. + * Inputs: + - `PACKAGE`: The package key + * Outputs: + - Basically everything. You're best off reading the code rather than me poorly explaining it. +- `which.sh`: Find which cpmfile a package is located in. + * Inputs: + - The package key +- `replace.sh`: Replace a package's cpmfile definition. + * Inputs: + - `PACKAGE`: The package key + - `NEW_JSON`: All keys to replace/add + * Keys not found in the new json are not touched. Keys cannot currently be deleted. + +## Simple Utilities + +These scripts don't really have any functionality, they just help you out a bit yknow? + +- `format.sh`: Format all cpmfiles (4-space indent is enforced) + * In the future, these scripts will have options for spacing +- `hash.sh`: Determine the hash of a specific package. + * Inputs: + - The repository (e.g. fmtlib/fmt) + - The sha or tag (e.g. v1.0.1) + - `GIT_HOST`: What git host to use (default github.com) + - `USE_TAG`: Set to "true" if the second argument is a tag instead of a sha + - `ARTIFACT`: The artifact to download, if using a tag. Set to null or empty to use the tag source archive instead + * Output: the SHA512 sum of the package +- `url-hash.sh`: Determine the hash of a URL + * Input: the URL + * Output: the SHA512 sum of the URL + +## Functional Utilities + +These modify the CPM cache or cpmfiles. Each allows you to input all the packages to act on, as well as a `-all.sh` that acts upon all available packages. + +For the update and hash scripts, set `UPDATE=true` to update the cpmfile with the new version or hash. Beware: if the hash is `cf83e1357...` that means you got a 404 error! + +- `fetch.sh`: Prefetch a package according to its cpmfile definition + * Packages are fetched to the `.cache/cpm` directory by default, following the CPMUtil default. + * Already-fetched packages will be skipped. You can invalidate the entire cache with `rm -rf .cache/cpm`, or invalidate a specific package with e.g. `rm -rf .cache/cpm/packagename` to force a refetch. + * In the future, a force option will be added + * Note that full prefetching will take a long time depending on your internet, the amount of dependencies, and the size of each dependency. +- `check-updates.sh`: Check a package for available updates + * This only applies to packages that utilize tags. + * If the tag is a format string, the `git_version` is acted upon instead. + * Setting `FORCE=true` will forcefully update every package and its hash, even if they are on the latest version (`UPDATE` must also be true) + * This script generally runs fast. + * Packages that should skip updates (e.g. older versions or packages with poorly-made tag structures... looking at you mbedtls) may specify `"skip_updates": true` in their cpmfile definition. This is unnecessary for untagged (e.g. sha or bare URL) packages. +- `check-hashes.sh`: Check a package's hash + * This only applies to packages with hardcoded hashes, NOT ones that use hash URLs. + * This script will take a looooooooooooooong time. This is operationally equivalent to a prefetch, and thus checking all hashes will take a while--but it's worth it! Just make sure you're not using dial-up. + +You are recommended to run sanity hash checking for every pull request and commit, and weekly update checks. \ No newline at end of file diff --git a/tools/cpm/check-hash-all.sh b/tools/cpm/check-hash-all.sh new file mode 100755 index 0000000000..fd8c270392 --- /dev/null +++ b/tools/cpm/check-hash-all.sh @@ -0,0 +1,10 @@ +#!/bin/bash -e + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +# shellcheck disable=SC1091 +. tools/cpm/common.sh + +# shellcheck disable=SC2086 +tools/cpm/check-hash.sh $LIBS \ No newline at end of file diff --git a/tools/cpm/check-hash.sh b/tools/cpm/check-hash.sh new file mode 100755 index 0000000000..85c60aad8c --- /dev/null +++ b/tools/cpm/check-hash.sh @@ -0,0 +1,46 @@ +#!/bin/sh -e + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +# env vars: +# - UPDATE: fix hashes if needed + +# shellcheck disable=SC1091 +. tools/cpm/common.sh + +RETURN=0 + +for PACKAGE in "$@" +do + export PACKAGE + # shellcheck disable=SC1091 + . tools/cpm/package.sh + + if [ "$CI" != null ]; then + continue + fi + + [ "$HASH_URL" != null ] && continue + [ "$HASH_SUFFIX" != null ] && continue + + echo "-- Package $PACKAGE" + + [ "$HASH" = null ] && echo "-- * Warning: no hash specified" && continue + + export USE_TAG=true + ACTUAL=$(tools/cpm/url-hash.sh "$DOWNLOAD") + + # shellcheck disable=SC2028 + [ "$ACTUAL" != "$HASH" ] && echo "-- * Expected $HASH" && echo "-- * Got $ACTUAL" && [ "$UPDATE" != "true" ] && RETURN=1 + + if [ "$UPDATE" = "true" ] && [ "$ACTUAL" != "$HASH" ]; then + # shellcheck disable=SC2034 + NEW_JSON=$(echo "$JSON" | jq ".hash = \"$ACTUAL\"") + export NEW_JSON + + tools/cpm/replace.sh + fi +done + +exit $RETURN \ No newline at end of file diff --git a/tools/cpm/check-updates-all.sh b/tools/cpm/check-updates-all.sh new file mode 100755 index 0000000000..a6eda58bac --- /dev/null +++ b/tools/cpm/check-updates-all.sh @@ -0,0 +1,10 @@ +#!/bin/bash -e + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +# shellcheck disable=SC1091 +. tools/cpm/common.sh + +# shellcheck disable=SC2086 +tools/cpm/check-updates.sh $LIBS \ No newline at end of file diff --git a/tools/cpm/check-updates.sh b/tools/cpm/check-updates.sh new file mode 100755 index 0000000000..bdccf96ca2 --- /dev/null +++ b/tools/cpm/check-updates.sh @@ -0,0 +1,90 @@ +#!/bin/sh -e + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +# env vars: +# - UPDATE: update if available +# - FORCE: forcefully update + +# shellcheck disable=SC1091 +. tools/cpm/common.sh + +RETURN=0 + +filter() { + TAGS=$(echo "$TAGS" | jq "[.[] | select(.name | test(\"$1\"; \"i\") | not)]") # vulkan +} + +for PACKAGE in "$@" +do + export PACKAGE + # shellcheck disable=SC1091 + . tools/cpm/package.sh + + SKIP=$(value "skip_updates") + + [ "$SKIP" = "true" ] && continue + + [ "$REPO" = null ] && continue + [ "$GIT_HOST" != "github.com" ] && continue # TODO + # shellcheck disable=SC2153 + [ "$TAG" = null ] && continue + + echo "-- Package $PACKAGE" + + # TODO(crueter): Support for Forgejo updates w/ forgejo_token + # Use gh-cli to avoid ratelimits lmao + TAGS=$(gh api --method GET "/repos/$REPO/tags") + + # filter out some commonly known annoyances + # TODO add more + + filter vulkan-sdk # vulkan + filter yotta # mbedtls + + # ignore betas/alphas (remove if needed) + filter alpha + filter beta + filter rc + + # Add package-specific overrides here, e.g. here for fmt: + [ "$PACKAGE" = fmt ] && filter v0.11 + + LATEST=$(echo "$TAGS" | jq -r '.[0].name') + + [ "$LATEST" = "$TAG" ] && [ "$FORCE" != "true" ] && echo "-- * Up-to-date" && continue + + RETURN=1 + + if [ "$HAS_REPLACE" = "true" ]; then + # this just extracts the tag prefix + VERSION_PREFIX=$(echo "$ORIGINAL_TAG" | cut -d"%" -f1) + + # then we strip out the prefix from the new tag, and make that our new git_version + NEW_GIT_VERSION=$(echo "$LATEST" | sed "s/$VERSION_PREFIX//g") + fi + + echo "-- * Version $LATEST available, current is $TAG" + + export USE_TAG=true + HASH=$(tools/cpm/hash.sh "$REPO" "$LATEST") + + echo "-- * New hash: $HASH" + + if [ "$UPDATE" = "true" ]; then + RETURN=0 + + if [ "$HAS_REPLACE" = "true" ]; then + NEW_JSON=$(echo "$JSON" | jq ".hash = \"$HASH\" | .git_version = \"$NEW_GIT_VERSION\"") + else + NEW_JSON=$(echo "$JSON" | jq ".hash = \"$HASH\" | .tag = \"$LATEST\"") + fi + + export NEW_JSON + + tools/cpm/replace.sh + fi +done + +exit $RETURN \ No newline at end of file diff --git a/tools/cpm/common.sh b/tools/cpm/common.sh new file mode 100755 index 0000000000..4aff058bdc --- /dev/null +++ b/tools/cpm/common.sh @@ -0,0 +1,32 @@ +#!/bin/sh -e + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +################################## +# CHANGE THESE FOR YOUR PROJECT! # +################################## + +# Which directories to search +DIRS=". src" + +# How many levels to go (3 is 2 subdirs max) +MAXDEPTH=3 + +# shellcheck disable=SC2038 +# shellcheck disable=SC2016 +# shellcheck disable=SC2086 +[ -z "$PACKAGES" ] && PACKAGES=$(find $DIRS -maxdepth "$MAXDEPTH" -name cpmfile.json | xargs jq -s 'reduce .[] as $item ({}; . * $item)') + +# For your project you'll want to change the PACKAGES call to include whatever locations you may use (externals, src, etc.) +# Always include . +LIBS=$(echo "$PACKAGES" | jq -j 'keys_unsorted | join(" ")') + +export PACKAGES +export LIBS +export DIRS +export MAXDEPTH + +value() { + echo "$JSON" | jq -r ".$1" +} \ No newline at end of file diff --git a/tools/cpm/download.sh b/tools/cpm/download.sh new file mode 100755 index 0000000000..426f1f51e6 --- /dev/null +++ b/tools/cpm/download.sh @@ -0,0 +1,100 @@ +#!/bin/sh -e + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +# env vars: +# - UPDATE: fix hashes if needed + +# shellcheck disable=SC1091 +. tools/cpm/common.sh + +download_package() { + FILENAME=$(basename "$DOWNLOAD") + + OUTFILE="$TMP/$FILENAME" + + LOWER_PACKAGE=$(echo "$PACKAGE_NAME" | tr '[:upper:]' '[:lower:]') + OUTDIR="${CPM_SOURCE_CACHE}/${LOWER_PACKAGE}/${KEY}" + [ -d "$OUTDIR" ] && return + + curl "$DOWNLOAD" -sS -L -o "$OUTFILE" + + ACTUAL_HASH=$("${HASH_ALGO}"sum "$OUTFILE" | cut -d" " -f1) + [ "$ACTUAL_HASH" != "$HASH" ] && echo "!! $FILENAME did not match expected hash; expected $HASH but got $ACTUAL_HASH" && exit 1 + + mkdir -p "$OUTDIR" + + PREVDIR="$PWD" + cd "$OUTDIR" + + case "$FILENAME" in + (*.7z) + 7z x "$OUTFILE" > /dev/null + ;; + (*.tar*) + tar xf "$OUTFILE" > /dev/null + ;; + (*.zip) + unzip "$OUTFILE" > /dev/null + ;; + esac + + # basically if only one real item exists at the top we just move everything from there + # since github and some vendors hate me + DIRS=$(find . -maxdepth 1 -type d -o -type f) + + # thanks gnu + if [ "$(echo "$DIRS" | wc -l)" -eq 2 ]; then + SUBDIR=$(find . -maxdepth 1 -type d -not -name ".") + mv "$SUBDIR"/* . + mv "$SUBDIR"/.* . 2>/dev/null || true + rmdir "$SUBDIR" + fi + + if echo "$JSON" | grep -e "patches" > /dev/null; then + PATCHES=$(echo "$JSON" | jq -r '.patches | join(" ")') + for patch in $PATCHES; do + # shellcheck disable=SC2154 + patch --binary -p1 < "$ROOTDIR/.patch/$PACKAGE/$patch" + done + fi + + cd "$PREVDIR" +} + +ci_package() { + [ "$REPO" = null ] && echo "-- ! No repo defined" && return + + echo "-- CI package $PACKAGE_NAME" + + for platform in windows-amd64 windows-arm64 android solaris-amd64 freebsd-amd64 linux-amd64 linux-aarch64 macos-universal; do + echo "-- * platform $platform" + + case $DISABLED in + (*"$platform"*) + echo "-- * -- disabled" + continue + ;; + (*) ;; + esac + + FILENAME="${NAME}-${platform}-${VERSION}.${EXT}" + DOWNLOAD="https://$GIT_HOST/${REPO}/releases/download/v${VERSION}/${FILENAME}" + KEY=$platform + + LOWER_PACKAGE=$(echo "$PACKAGE_NAME" | tr '[:upper:]' '[:lower:]') + OUTDIR="${CPM_SOURCE_CACHE}/${LOWER_PACKAGE}/${KEY}" + [ -d "$OUTDIR" ] && continue + + HASH_ALGO=$(value "hash_algo") + [ "$HASH_ALGO" = null ] && HASH_ALGO=sha512 + + HASH_SUFFIX="${HASH_ALGO}sum" + HASH_URL="${DOWNLOAD}.${HASH_SUFFIX}" + + HASH=$(curl "$HASH_URL" -sS -q -L -o -) + + download_package + done +} diff --git a/tools/cpm/fetch-all.sh b/tools/cpm/fetch-all.sh new file mode 100755 index 0000000000..5c41b5d080 --- /dev/null +++ b/tools/cpm/fetch-all.sh @@ -0,0 +1,10 @@ +#!/bin/sh -e + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +# shellcheck disable=SC1091 +. tools/cpm/common.sh + +# shellcheck disable=SC2086 +tools/cpm/fetch.sh $LIBS \ No newline at end of file diff --git a/tools/cpm/fetch.sh b/tools/cpm/fetch.sh new file mode 100755 index 0000000000..bf45676cfa --- /dev/null +++ b/tools/cpm/fetch.sh @@ -0,0 +1,36 @@ +#!/bin/sh -e + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +[ -z "$CPM_SOURCE_CACHE" ] && CPM_SOURCE_CACHE=$PWD/.cache/cpm + +mkdir -p "$CPM_SOURCE_CACHE" + +# shellcheck disable=SC1091 +. tools/cpm/common.sh + +# shellcheck disable=SC1091 +. tools/cpm/download.sh + +# shellcheck disable=SC2034 +ROOTDIR="$PWD" + +TMP=$(mktemp -d) + +# shellcheck disable=SC2034 +for PACKAGE in "$@" +do + export PACKAGE + # shellcheck disable=SC1091 + . tools/cpm/package.sh + + if [ "$CI" = "true" ]; then + ci_package + else + echo "-- Downloading regular package $PACKAGE, with key $KEY, from $DOWNLOAD" + download_package + fi +done + +rm -rf "$TMP" \ No newline at end of file diff --git a/tools/cpm/format.sh b/tools/cpm/format.sh new file mode 100755 index 0000000000..8d99b4796b --- /dev/null +++ b/tools/cpm/format.sh @@ -0,0 +1,15 @@ +#!/bin/sh -e + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +# shellcheck disable=SC1091 +. tools/cpm/common.sh + +# shellcheck disable=SC2086 +FILES=$(find $DIRS -maxdepth "$MAXDEPTH" -name cpmfile.json) + +for file in $FILES; do + jq --indent 4 < "$file" > "$file".new + mv "$file".new "$file" +done diff --git a/tools/cpm/hash.sh b/tools/cpm/hash.sh new file mode 100755 index 0000000000..27061bd9a4 --- /dev/null +++ b/tools/cpm/hash.sh @@ -0,0 +1,25 @@ +#!/bin/sh -e + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +# usage: hash.sh repo tag-or-sha +# env vars: GIT_HOST, USE_TAG (use tag instead of sha), ARTIFACT (download artifact with that name instead of src archive) + +REPO="$1" +[ -z "$GIT_HOST" ] && GIT_HOST=github.com +GIT_URL="https://$GIT_HOST/$REPO" + +if [ "$USE_TAG" = "true" ]; then + if [ -z "$ARTIFACT" ] || [ "$ARTIFACT" = "null" ]; then + URL="${GIT_URL}/archive/refs/tags/$2.tar.gz" + else + URL="${GIT_URL}/releases/download/$2/${ARTIFACT}" + fi +else + URL="${GIT_URL}/archive/$2.zip" +fi + +SUM=$(wget -q "$URL" -O - | sha512sum) + +echo "$SUM" | cut -d " " -f1 diff --git a/tools/cpm/package.sh b/tools/cpm/package.sh new file mode 100755 index 0000000000..d82b2fcbe9 --- /dev/null +++ b/tools/cpm/package.sh @@ -0,0 +1,203 @@ +#!/bin/sh -e + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +# env vars: +# - UPDATE: fix hashes if needed + +# shellcheck disable=SC1091 +. tools/cpm/common.sh + +[ -z "$PACKAGE" ] && echo "Package was not specified" && exit 0 + +# shellcheck disable=SC2153 +JSON=$(echo "$PACKAGES" | jq -r ".\"$PACKAGE\" | select( . != null )") + +[ -z "$JSON" ] && echo "!! No cpmfile definition for $PACKAGE" && exit 1 + +# unset stuff +export PACKAGE_NAME="null" +export REPO="null" +export CI="null" +export GIT_HOST="null" +export EXT="null" +export NAME="null" +export DISABLED="null" +export TAG="null" +export ARTIFACT="null" +export SHA="null" +export VERSION="null" +export GIT_VERSION="null" +export DOWNLOAD="null" +export URL="null" +export KEY="null" +export HASH="null" +export ORIGINAL_TAG="null" +export HAS_REPLACE="null" +export VERSION_REPLACE="null" +export HASH_URL="null" +export HASH_SUFFIX="null" +export HASH_ALGO="null" + +######## +# Meta # +######## + +REPO=$(value "repo") +CI=$(value "ci") + +PACKAGE_NAME=$(value "package") +[ "$PACKAGE_NAME" = null ] && PACKAGE_NAME="$PACKAGE" + +GIT_HOST=$(value "git_host") +[ "$GIT_HOST" = null ] && GIT_HOST=github.com + +export PACKAGE_NAME +export REPO +export CI +export GIT_HOST + +###################### +# CI Package Parsing # +###################### + +VERSION=$(value "version") + +if [ "$CI" = "true" ]; then + EXT=$(value "extension") + [ "$EXT" = null ] && EXT="tar.zst" + + NAME=$(value "name") + DISABLED=$(echo "$JSON" | jq -j '.disabled_platforms') + + [ "$NAME" = null ] && NAME="$PACKAGE_NAME" + + export EXT + export NAME + export DISABLED + export VERSION + + return 0 +fi + +############## +# Versioning # +############## + +TAG=$(value "tag") +ARTIFACT=$(value "artifact") +SHA=$(value "sha") +GIT_VERSION=$(value "git_version") + +[ "$GIT_VERSION" = null ] && GIT_VERSION="$VERSION" + +if [ "$GIT_VERSION" != null ]; then + VERSION_REPLACE="$GIT_VERSION" +else + VERSION_REPLACE="$VERSION" +fi + +echo "$TAG" | grep -e "%VERSION%" > /dev/null && HAS_REPLACE=true || HAS_REPLACE=false +ORIGINAL_TAG="$TAG" + +TAG=$(echo "$TAG" | sed "s/%VERSION%/$VERSION_REPLACE/g") +ARTIFACT=$(echo "$ARTIFACT" | sed "s/%VERSION%/$VERSION_REPLACE/g") +ARTIFACT=$(echo "$ARTIFACT" | sed "s/%TAG%/$TAG/g") + +export TAG +export ARTIFACT +export SHA +export VERSION +export GIT_VERSION +export ORIGINAL_TAG +export HAS_REPLACE +export VERSION_REPLACE + +############### +# URL Parsing # +############### + +URL=$(value "url") + +if [ "$URL" != "null" ]; then + DOWNLOAD="$URL" +elif [ "$REPO" != "null" ]; then + GIT_URL="https://$GIT_HOST/$REPO" + + BRANCH=$(value "branch") + + if [ "$TAG" != "null" ]; then + if [ "$ARTIFACT" != "null" ]; then + DOWNLOAD="${GIT_URL}/releases/download/${TAG}/${ARTIFACT}" + else + DOWNLOAD="${GIT_URL}/archive/refs/tags/${TAG}.tar.gz" + fi + elif [ "$SHA" != "null" ]; then + DOWNLOAD="${GIT_URL}/archive/${SHA}.zip" + else + if [ "$BRANCH" = null ]; then + BRANCH=master + fi + + DOWNLOAD="${GIT_URL}/archive/refs/heads/${BRANCH}.zip" + fi +else + echo "!! No repo or URL defined for $PACKAGE" + exit 1 +fi + +export DOWNLOAD +export URL + +############### +# Key Parsing # +############### + +KEY=$(value "key") + +if [ "$KEY" = null ]; then + if [ "$SHA" != null ]; then + KEY=$(echo "$SHA" | cut -c1-4) + elif [ "$GIT_VERSION" != null ]; then + KEY="$GIT_VERSION" + elif [ "$TAG" != null ]; then + KEY="$TAG" + elif [ "$VERSION" != null ]; then + KEY="$VERSION" + else + echo "!! No valid key could be determined for $PACKAGE. Must define one of: key, sha, tag, version, git_version" + exit 1 + fi +fi + +export KEY + +################ +# Hash Parsing # +################ + +HASH_ALGO=$(value "hash_algo") +[ "$HASH_ALGO" = null ] && HASH_ALGO=sha512 + +HASH=$(value "hash") + +if [ "$HASH" = null ]; then + HASH_SUFFIX="${HASH_ALGO}sum" + HASH_URL=$(value "hash_url") + + if [ "$HASH_URL" = null ]; then + HASH_URL="${DOWNLOAD}.${HASH_SUFFIX}" + fi + + HASH=$(curl "$HASH_URL" -Ss -L -o -) +else + HASH_URL=null + HASH_SUFFIX=null +fi + +export HASH_URL +export HASH_SUFFIX +export HASH +export HASH_ALGO +export JSON \ No newline at end of file diff --git a/tools/cpm/replace.sh b/tools/cpm/replace.sh new file mode 100755 index 0000000000..501cfda6b1 --- /dev/null +++ b/tools/cpm/replace.sh @@ -0,0 +1,20 @@ +#!/bin/sh -e + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +# Replace a specified package with a modified json. + +# env vars: +# - PACKAGE: The package key to act on +# - NEW_JSON: The new json to use + +[ -z "$PACKAGE" ] && echo "You must provide the PACKAGE environment variable." && return 1 +[ -z "$NEW_JSON" ] && echo "You must provide the NEW_JSON environment variable." && return 1 + +FILE=$(tools/cpm/which.sh "$PACKAGE") + +jq --indent 4 --argjson repl "$NEW_JSON" ".\"$PACKAGE\" *= \$repl" "$FILE" > "$FILE".new +mv "$FILE".new "$FILE" + +echo "-- * -- Updated $FILE" diff --git a/tools/cpm/url-hash.sh b/tools/cpm/url-hash.sh new file mode 100755 index 0000000000..c911dacb37 --- /dev/null +++ b/tools/cpm/url-hash.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +SUM=$(wget -q "$1" -O - | sha512sum) +echo "$SUM" | cut -d " " -f1 diff --git a/tools/cpm/which.sh b/tools/cpm/which.sh new file mode 100755 index 0000000000..c936d0a97f --- /dev/null +++ b/tools/cpm/which.sh @@ -0,0 +1,15 @@ +#!/bin/sh -e + +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +# check which file a package is in +# shellcheck disable=SC1091 +. tools/cpm/common.sh + +# shellcheck disable=SC2086 +JSON=$(find $DIRS -maxdepth "$MAXDEPTH" -name cpmfile.json -exec grep -l "$1" {} \;) + +[ -z "$JSON" ] && echo "!! No cpmfile definition for $1" + +echo "$JSON" \ No newline at end of file diff --git a/tools/dtrace-tool.sh b/tools/dtrace-tool.sh index a8cc4c7bad..4a75848fcd 100755 --- a/tools/dtrace-tool.sh +++ b/tools/dtrace-tool.sh @@ -1,42 +1,59 @@ #!/usr/local/bin/bash -ex + # SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later + # Basic script to run dtrace sampling over the program (requires Flamegraph) # Usage is either running as: ./dtrace-tool.sh pid (then input the pid of the process) # Or just run directly with: ./dtrace-tool.sh + FLAMEGRAPH_DIR=".." -function fail { - printf '%s\n' "$1" >&2 - exit "${2-1}" +fail() { + printf '%s\n' "$1" >&2 + exit "${2-1}" } + [ -f $FLAMEGRAPH_DIR/FlameGraph/stackcollapse.pl ] || fail 'Where is flamegraph?' #[ which dtrace ] || fail 'Needs DTrace installed' -read -p "Sampling Hz [800]: " TRACE_CFG_HZ + +read -r "Sampling Hz [800]: " TRACE_CFG_HZ if [ -z "${TRACE_CFG_HZ}" ]; then - TRACE_CFG_HZ=800 + TRACE_CFG_HZ=800 fi -read -p "Sampling time [5] sec: " TRACE_CFG_TIME + +read -r "Sampling time [5] sec: " TRACE_CFG_TIME if [ -z "${TRACE_CFG_TIME}" ]; then - TRACE_CFG_TIME=5 + TRACE_CFG_TIME=5 fi + TRACE_FILE=dtrace-out.user_stacks TRACE_FOLD=dtrace-out.fold TRACE_SVG=dtrace-out.svg ps -if [[ $1 = 'pid' ]]; then - read -p "PID: " TRACE_CFG_PID - sudo echo 'Sudo!' + +if [ "$1" = 'pid' ]; then + read -r "PID: " TRACE_CFG_PID + sudo echo 'Sudo!' else - [[ -f $1 && $1 ]] || fail 'Usage: ./tools/dtrace-profile.sh ' - echo "Executing: '$@'" - sudo echo 'Sudo!' - "$@" & - TRACE_CFG_PID=$! + if [ -f "$1" ] && [ "$1" ]; then + fail 'Usage: ./tools/dtrace-profile.sh ' + fi + + printf "Executing: " + echo "$@" + sudo echo 'Sudo!' + "$@" & + TRACE_CFG_PID=$! fi + TRACE_PROBE="profile-${TRACE_CFG_HZ} /pid == ${TRACE_CFG_PID} && arg1/ { @[ustack()] = count(); } tick-${TRACE_CFG_TIME}s { exit(0); }" + rm -- $TRACE_SVG || echo 'Skip' + sudo dtrace -x ustackframes=100 -Z -n "$TRACE_PROBE" -o $TRACE_FILE 2>/dev/null || exit + perl $FLAMEGRAPH_DIR/FlameGraph/stackcollapse.pl $TRACE_FILE > $TRACE_FOLD || exit perl $FLAMEGRAPH_DIR/FlameGraph/flamegraph.pl $TRACE_FOLD > $TRACE_SVG || exit + sudo chmod 0666 $TRACE_FILE rm -- $TRACE_FILE $TRACE_FOLD \ No newline at end of file diff --git a/tools/llvmpipe-run.sh b/tools/llvmpipe-run.sh index 8f53d691c2..c3a5a85d41 100755 --- a/tools/llvmpipe-run.sh +++ b/tools/llvmpipe-run.sh @@ -1,15 +1,205 @@ #!/bin/sh # SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later + # This script basically allows you to "dirtily" use llvmpipe in any configuration # llvmpipe will of course, run at negative mach-1 speeds. However this is mainly useful to test that mesa # is properly working on extraneous systems (such as Managarm). This mainly only works with MESA >22.0.0 # Use as follows: ./llvmpipe-run.sh + export MESA_GL_VERSION_OVERRIDE=4.6 export MESA_GLSL_VERSION_OVERRIDE=460 export MESA_EXTENSION_MAX_YEAR=2025 export MESA_DEBUG=1 export MESA_VK_VERSION_OVERRIDE=1.3 export LIBGL_ALWAYS_SOFTWARE=1 -export MESA_EXTENSION_OVERRIDE="GL_AMD_multi_draw_indirect GL_AMD_seamless_cubemap_per_texture GL_AMD_vertex_shader_layer GL_AMD_vertex_shader_viewport_index GL_ARB_ES2_compatibility GL_ARB_ES3_1_compatibility GL_ARB_ES3_2_compatibility GL_ARB_ES3_compatibility GL_ARB_arrays_of_arrays GL_ARB_base_instance GL_ARB_bindless_texture GL_ARB_blend_func_extended GL_ARB_buffer_storage GL_ARB_clear_buffer_object GL_ARB_clear_texture GL_ARB_clip_control GL_ARB_color_buffer_float GL_ARB_compressed_texture_pixel_storage GL_ARB_compute_shader GL_ARB_compute_variable_group_size GL_ARB_conditional_render_inverted GL_ARB_conservative_depth GL_ARB_copy_buffer GL_ARB_copy_image GL_ARB_cull_distance GL_ARB_debug_output GL_ARB_depth_buffer_float GL_ARB_depth_clamp GL_ARB_depth_texture GL_ARB_derivative_control GL_ARB_direct_state_access GL_ARB_draw_buffers GL_ARB_draw_buffers_blend GL_ARB_draw_elements_base_vertex GL_ARB_draw_indirect GL_ARB_draw_instanced GL_ARB_enhanced_layouts GL_ARB_explicit_attrib_location GL_ARB_explicit_uniform_location GL_ARB_fragment_coord_conventions GL_ARB_fragment_layer_viewport GL_ARB_fragment_program GL_ARB_fragment_program_shadow GL_ARB_fragment_shader GL_ARB_fragment_shader_interlock GL_ARB_framebuffer_no_attachments GL_ARB_framebuffer_object GL_ARB_framebuffer_sRGB GL_ARB_geometry_shader4 GL_ARB_get_program_binary GL_ARB_get_texture_sub_image GL_ARB_gl_spirv GL_ARB_gpu_shader5 GL_ARB_gpu_shader_fp64 GL_ARB_gpu_shader_int64 GL_ARB_half_float_pixel GL_ARB_half_float_vertex GL_ARB_imaging GL_ARB_indirect_parameters GL_ARB_instanced_arrays GL_ARB_internalformat_query GL_ARB_internalformat_query2 GL_ARB_invalidate_subdata GL_ARB_map_buffer_alignment GL_ARB_map_buffer_range GL_ARB_multi_bind GL_ARB_multi_draw_indirect GL_ARB_multisample GL_ARB_multitexture GL_ARB_occlusion_query GL_ARB_occlusion_query2 GL_ARB_parallel_shader_compile GL_ARB_pipeline_statistics_query GL_ARB_pixel_buffer_object GL_ARB_point_parameters GL_ARB_point_sprite GL_ARB_polygon_offset_clamp GL_ARB_post_depth_coverage GL_ARB_program_interface_query GL_ARB_provoking_vertex GL_ARB_query_buffer_object GL_ARB_robust_buffer_access_behavior GL_ARB_robustness GL_ARB_sample_locations GL_ARB_sample_shading GL_ARB_sampler_objects GL_ARB_seamless_cube_map GL_ARB_seamless_cubemap_per_texture GL_ARB_separate_shader_objects GL_ARB_shader_atomic_counter_ops GL_ARB_shader_atomic_counters GL_ARB_shader_ballot GL_ARB_shader_bit_encoding GL_ARB_shader_clock GL_ARB_shader_draw_parameters GL_ARB_shader_group_vote GL_ARB_shader_image_load_store GL_ARB_shader_image_size GL_ARB_shader_objects GL_ARB_shader_precision GL_ARB_shader_storage_buffer_object GL_ARB_shader_subroutine GL_ARB_shader_texture_image_samples GL_ARB_shader_texture_lod GL_ARB_shader_viewport_layer_array GL_ARB_shading_language_100 GL_ARB_shading_language_420pack GL_ARB_shading_language_include GL_ARB_shading_language_packing GL_ARB_shadow GL_ARB_sparse_buffer GL_ARB_sparse_texture GL_ARB_sparse_texture2 GL_ARB_sparse_texture_clamp GL_ARB_spirv_extensions GL_ARB_stencil_texturing GL_ARB_sync GL_ARB_tessellation_shader GL_ARB_texture_barrier GL_ARB_texture_border_clamp GL_ARB_texture_buffer_object GL_ARB_texture_buffer_object_rgb32 GL_ARB_texture_buffer_range GL_ARB_texture_compression GL_ARB_texture_compression_bptc GL_ARB_texture_compression_rgtc GL_ARB_texture_cube_map GL_ARB_texture_cube_map_array GL_ARB_texture_env_add GL_ARB_texture_env_combine GL_ARB_texture_env_crossbar GL_ARB_texture_env_dot3 GL_ARB_texture_filter_anisotropic GL_ARB_texture_filter_minmax GL_ARB_texture_float GL_ARB_texture_gather GL_ARB_texture_mirror_clamp_to_edge GL_ARB_texture_mirrored_repeat GL_ARB_texture_multisample GL_ARB_texture_non_power_of_two GL_ARB_texture_query_levels GL_ARB_texture_query_lod GL_ARB_texture_rectangle GL_ARB_texture_rg GL_ARB_texture_rgb10_a2ui GL_ARB_texture_stencil8 GL_ARB_texture_storage GL_ARB_texture_storage_multisample GL_ARB_texture_swizzle GL_ARB_texture_view GL_ARB_timer_query GL_ARB_transform_feedback2 GL_ARB_transform_feedback3 GL_ARB_transform_feedback_instanced GL_ARB_transform_feedback_overflow_query GL_ARB_transpose_matrix GL_ARB_uniform_buffer_object GL_ARB_vertex_array_bgra GL_ARB_vertex_array_object GL_ARB_vertex_attrib_64bit GL_ARB_vertex_attrib_binding GL_ARB_vertex_buffer_object GL_ARB_vertex_program GL_ARB_vertex_shader GL_ARB_vertex_type_10f_11f_11f_rev GL_ARB_vertex_type_2_10_10_10_rev GL_ARB_viewport_array GL_ARB_window_pos GL_ATI_draw_buffers GL_ATI_texture_float GL_ATI_texture_mirror_once GL_EXTX_framebuffer_mixed_formats GL_EXT_Cg_shader GL_EXT_abgr GL_EXT_bgra GL_EXT_bindable_uniform GL_EXT_blend_color GL_EXT_blend_equation_separate GL_EXT_blend_func_separate GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_compiled_vertex_array GL_EXT_depth_bounds_test GL_EXT_direct_state_access GL_EXT_draw_buffers2 GL_EXT_draw_instanced GL_EXT_draw_range_elements GL_EXT_fog_coord GL_EXT_framebuffer_blit GL_EXT_framebuffer_multisample GL_EXT_framebuffer_multisample_blit_scaled GL_EXT_framebuffer_object GL_EXT_framebuffer_sRGB GL_EXT_geometry_shader4 GL_EXT_gpu_program_parameters GL_EXT_gpu_shader4 GL_EXT_import_sync_object GL_EXT_memory_object GL_EXT_memory_object_fd GL_EXT_multi_draw_arrays GL_EXT_multiview_texture_multisample GL_EXT_multiview_timer_query GL_EXT_packed_depth_stencil GL_EXT_packed_float GL_EXT_packed_pixels GL_EXT_pixel_buffer_object GL_EXT_point_parameters GL_EXT_polygon_offset_clamp GL_EXT_post_depth_coverage GL_EXT_provoking_vertex GL_EXT_raster_multisample GL_EXT_rescale_normal GL_EXT_secondary_color GL_EXT_semaphore GL_EXT_semaphore_fd GL_EXT_separate_shader_objects GL_EXT_separate_specular_color GL_EXT_shader_image_load_formatted GL_EXT_shader_image_load_store GL_EXT_shader_integer_mix GL_EXT_shadow_funcs GL_EXT_sparse_texture2 GL_EXT_stencil_two_side GL_EXT_stencil_wrap GL_EXT_texture3D GL_EXT_texture_array GL_EXT_texture_buffer_object GL_EXT_texture_compression_dxt1 GL_EXT_texture_compression_latc GL_EXT_texture_compression_rgtc GL_EXT_texture_compression_s3tc GL_EXT_texture_cube_map GL_EXT_texture_edge_clamp GL_EXT_texture_env_add GL_EXT_texture_env_combine GL_EXT_texture_env_dot3 GL_EXT_texture_filter_anisotropic GL_EXT_texture_filter_minmax GL_EXT_texture_integer GL_EXT_texture_lod GL_EXT_texture_lod_bias GL_EXT_texture_mirror_clamp GL_EXT_texture_object GL_EXT_texture_sRGB GL_EXT_texture_sRGB_R8 GL_EXT_texture_sRGB_decode GL_EXT_texture_shadow_lod GL_EXT_texture_shared_exponent GL_EXT_texture_storage GL_EXT_texture_swizzle GL_EXT_timer_query GL_EXT_transform_feedback2 GL_EXT_vertex_array GL_EXT_vertex_array_bgra GL_EXT_vertex_attrib_64bit GL_EXT_window_rectangles GL_EXT_x11_sync_object GL_IBM_rasterpos_clip GL_IBM_texture_mirrored_repeat GL_KHR_blend_equation_advanced GL_KHR_blend_equation_advanced_coherent GL_KHR_context_flush_control GL_KHR_debug GL_KHR_no_error GL_KHR_parallel_shader_compile GL_KHR_robust_buffer_access_behavior GL_KHR_robustness GL_KHR_shader_subgroup GL_KTX_buffer_region GL_NVX_blend_equation_advanced_multi_draw_buffers GL_NVX_conditional_render GL_NVX_gpu_memory_info GL_NVX_nvenc_interop GL_NVX_progress_fence GL_NV_ES1_1_compatibility GL_NV_ES3_1_compatibility GL_NV_alpha_to_coverage_dither_control GL_NV_bindless_multi_draw_indirect GL_NV_bindless_multi_draw_indirect_count GL_NV_bindless_texture GL_NV_blend_equation_advanced GL_NV_blend_equation_advanced_coherent GL_NV_blend_minmax_factor GL_NV_blend_square GL_NV_clip_space_w_scaling GL_NV_command_list GL_NV_compute_program5 GL_NV_conditional_render GL_NV_conservative_raster GL_NV_conservative_raster_dilate GL_NV_conservative_raster_pre_snap_triangles GL_NV_copy_depth_to_color GL_NV_copy_image GL_NV_depth_buffer_float GL_NV_depth_clamp GL_NV_draw_texture GL_NV_draw_vulkan_image GL_NV_explicit_multisample GL_NV_feature_query GL_NV_fence GL_NV_fill_rectangle GL_NV_float_buffer GL_NV_fog_distance GL_NV_fragment_coverage_to_color GL_NV_fragment_program GL_NV_fragment_program2 GL_NV_fragment_program_option GL_NV_fragment_shader_interlock GL_NV_framebuffer_mixed_samples GL_NV_framebuffer_multisample_coverage GL_NV_geometry_shader4 GL_NV_geometry_shader_passthrough GL_NV_gpu_multicast GL_NV_gpu_program4 GL_NV_gpu_program4_1 GL_NV_gpu_program5 GL_NV_gpu_program5_mem_extended GL_NV_gpu_program_fp64 GL_NV_gpu_program_multiview GL_NV_gpu_shader5 GL_NV_half_float GL_NV_internalformat_sample_query GL_NV_light_max_exponent GL_NV_memory_attachment GL_NV_memory_object_sparse GL_NV_multisample_coverage GL_NV_multisample_filter_hint GL_NV_occlusion_query GL_NV_packed_depth_stencil GL_NV_parameter_buffer_object GL_NV_parameter_buffer_object2 GL_NV_path_rendering GL_NV_path_rendering_shared_edge GL_NV_pixel_data_range GL_NV_point_sprite GL_NV_primitive_restart GL_NV_query_resource GL_NV_query_resource_tag GL_NV_register_combiners GL_NV_register_combiners2 GL_NV_robustness_video_memory_purge GL_NV_sample_locations GL_NV_sample_mask_override_coverage GL_NV_shader_atomic_counters GL_NV_shader_atomic_float GL_NV_shader_atomic_float64 GL_NV_shader_atomic_fp16_vector GL_NV_shader_atomic_int64 GL_NV_shader_buffer_load GL_NV_shader_storage_buffer_object GL_NV_shader_subgroup_partitioned GL_NV_shader_thread_group GL_NV_shader_thread_shuffle GL_NV_stereo_view_rendering GL_NV_texgen_reflection GL_NV_texture_barrier GL_NV_texture_compression_vtc GL_NV_texture_env_combine4 GL_NV_texture_multisample GL_NV_texture_rectangle GL_NV_texture_rectangle_compressed GL_NV_texture_shader GL_NV_texture_shader2 GL_NV_texture_shader3 GL_NV_timeline_semaphore GL_NV_transform_feedback GL_NV_transform_feedback2 GL_NV_uniform_buffer_std430_layout GL_NV_uniform_buffer_unified_memory GL_NV_vdpau_interop GL_NV_vdpau_interop2 GL_NV_vertex_array_range GL_NV_vertex_array_range2 GL_NV_vertex_attrib_integer_64bit GL_NV_vertex_buffer_unified_memory GL_NV_vertex_program GL_NV_vertex_program1_1 GL_NV_vertex_program2 GL_NV_vertex_program2_option GL_NV_vertex_program3 GL_NV_viewport_array2 GL_NV_viewport_swizzle GL_OVR_multiview GL_OVR_multiview2 GL_S3_s3tc GL_SGIS_generate_mipmap GL_SGIS_texture_lod GL_SGIX_depth_texture GL_SGIX_shadow GL_SUN_slice_accum GL_AMD_multi_draw_indirect GL_AMD_seamless_cubemap_per_texture GL_AMD_vertex_shader_layer GL_AMD_vertex_shader_viewport_index GL_ARB_ES2_compatibility GL_ARB_ES3_1_compatibility GL_ARB_ES3_2_compatibility GL_ARB_ES3_compatibility GL_ARB_arrays_of_arrays GL_ARB_base_instance GL_ARB_bindless_texture GL_ARB_blend_func_extended GL_ARB_buffer_storage GL_ARB_clear_buffer_object GL_ARB_clear_texture GL_ARB_clip_control GL_ARB_color_buffer_float GL_ARB_compatibility GL_ARB_compressed_texture_pixel_storage GL_ARB_compute_shader GL_ARB_compute_variable_group_size GL_ARB_conditional_render_inverted GL_ARB_conservative_depth GL_ARB_copy_buffer GL_ARB_copy_image GL_ARB_cull_distance GL_ARB_debug_output GL_ARB_depth_buffer_float GL_ARB_depth_clamp GL_ARB_depth_texture GL_ARB_derivative_control GL_ARB_direct_state_access GL_ARB_draw_buffers GL_ARB_draw_buffers_blend GL_ARB_draw_elements_base_vertex GL_ARB_draw_indirect GL_ARB_draw_instanced GL_ARB_enhanced_layouts GL_ARB_explicit_attrib_location GL_ARB_explicit_uniform_location GL_ARB_fragment_coord_conventions GL_ARB_fragment_layer_viewport GL_ARB_fragment_program GL_ARB_fragment_program_shadow GL_ARB_fragment_shader GL_ARB_fragment_shader_interlock GL_ARB_framebuffer_no_attachments GL_ARB_framebuffer_object GL_ARB_framebuffer_sRGB GL_ARB_geometry_shader4 GL_ARB_get_program_binary GL_ARB_get_texture_sub_image GL_ARB_gl_spirv GL_ARB_gpu_shader5 GL_ARB_gpu_shader_fp64 GL_ARB_gpu_shader_int64 GL_ARB_half_float_pixel GL_ARB_half_float_vertex GL_ARB_imaging GL_ARB_indirect_parameters GL_ARB_instanced_arrays GL_ARB_internalformat_query GL_ARB_internalformat_query2 GL_ARB_invalidate_subdata GL_ARB_map_buffer_alignment GL_ARB_map_buffer_range GL_ARB_multi_bind GL_ARB_multi_draw_indirect GL_ARB_multisample GL_ARB_multitexture GL_ARB_occlusion_query GL_ARB_occlusion_query2 GL_ARB_parallel_shader_compile GL_ARB_pipeline_statistics_query GL_ARB_pixel_buffer_object GL_ARB_point_parameters GL_ARB_point_sprite GL_ARB_polygon_offset_clamp GL_ARB_post_depth_coverage GL_ARB_program_interface_query GL_ARB_provoking_vertex GL_ARB_query_buffer_object GL_ARB_robust_buffer_access_behavior GL_ARB_robustness GL_ARB_sample_locations GL_ARB_sample_shading GL_ARB_sampler_objects GL_ARB_seamless_cube_map GL_ARB_seamless_cubemap_per_texture GL_ARB_separate_shader_objects GL_ARB_shader_atomic_counter_ops GL_ARB_shader_atomic_counters GL_ARB_shader_ballot GL_ARB_shader_bit_encoding GL_ARB_shader_clock GL_ARB_shader_draw_parameters GL_ARB_shader_group_vote GL_ARB_shader_image_load_store GL_ARB_shader_image_size GL_ARB_shader_objects GL_ARB_shader_precision GL_ARB_shader_storage_buffer_object GL_ARB_shader_subroutine GL_ARB_shader_texture_image_samples GL_ARB_shader_texture_lod GL_ARB_shader_viewport_layer_array GL_ARB_shading_language_100 GL_ARB_shading_language_420pack GL_ARB_shading_language_include GL_ARB_shading_language_packing GL_ARB_shadow GL_ARB_sparse_buffer GL_ARB_sparse_texture GL_ARB_sparse_texture2 GL_ARB_sparse_texture_clamp GL_ARB_spirv_extensions GL_ARB_stencil_texturing GL_ARB_sync GL_ARB_tessellation_shader GL_ARB_texture_barrier GL_ARB_texture_border_clamp GL_ARB_texture_buffer_object GL_ARB_texture_buffer_object_rgb32 GL_ARB_texture_buffer_range GL_ARB_texture_compression GL_ARB_texture_compression_bptc GL_ARB_texture_compression_rgtc GL_ARB_texture_cube_map GL_ARB_texture_cube_map_array GL_ARB_texture_env_add GL_ARB_texture_env_combine GL_ARB_texture_env_crossbar GL_ARB_texture_env_dot3 GL_ARB_texture_filter_anisotropic GL_ARB_texture_filter_minmax GL_ARB_texture_float GL_ARB_texture_gather GL_ARB_texture_mirror_clamp_to_edge GL_ARB_texture_mirrored_repeat GL_ARB_texture_multisample GL_ARB_texture_non_power_of_two GL_ARB_texture_query_levels GL_ARB_texture_query_lod GL_ARB_texture_rectangle GL_ARB_texture_rg GL_ARB_texture_rgb10_a2ui GL_ARB_texture_stencil8 GL_ARB_texture_storage GL_ARB_texture_storage_multisample GL_ARB_texture_swizzle GL_ARB_texture_view GL_ARB_timer_query GL_ARB_transform_feedback2 GL_ARB_transform_feedback3 GL_ARB_transform_feedback_instanced GL_ARB_transform_feedback_overflow_query GL_ARB_transpose_matrix GL_ARB_uniform_buffer_object GL_ARB_vertex_array_bgra GL_ARB_vertex_array_object GL_ARB_vertex_attrib_64bit GL_ARB_vertex_attrib_binding GL_ARB_vertex_buffer_object GL_ARB_vertex_program GL_ARB_vertex_shader GL_ARB_vertex_type_10f_11f_11f_rev GL_ARB_vertex_type_2_10_10_10_rev GL_ARB_viewport_array GL_ARB_window_pos GL_ATI_draw_buffers GL_ATI_texture_float GL_ATI_texture_mirror_once GL_EXTX_framebuffer_mixed_formats GL_EXT_Cg_shader GL_EXT_abgr GL_EXT_bgra GL_EXT_bindable_uniform GL_EXT_blend_color GL_EXT_blend_equation_separate GL_EXT_blend_func_separate GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_compiled_vertex_array GL_EXT_depth_bounds_test GL_EXT_direct_state_access GL_EXT_draw_buffers2 GL_EXT_draw_instanced GL_EXT_draw_range_elements GL_EXT_fog_coord GL_EXT_framebuffer_blit GL_EXT_framebuffer_multisample GL_EXT_framebuffer_multisample_blit_scaled GL_EXT_framebuffer_object GL_EXT_framebuffer_sRGB GL_EXT_geometry_shader4 GL_EXT_gpu_program_parameters GL_EXT_gpu_shader4 GL_EXT_import_sync_object GL_EXT_memory_object GL_EXT_memory_object_fd GL_EXT_multi_draw_arrays GL_EXT_multiview_texture_multisample GL_EXT_multiview_timer_query GL_EXT_packed_depth_stencil GL_EXT_packed_float GL_EXT_packed_pixels GL_EXT_pixel_buffer_object GL_EXT_point_parameters GL_EXT_polygon_offset_clamp GL_EXT_post_depth_coverage GL_EXT_provoking_vertex GL_EXT_raster_multisample GL_EXT_rescale_normal GL_EXT_secondary_color GL_EXT_semaphore GL_EXT_semaphore_fd GL_EXT_separate_shader_objects GL_EXT_separate_specular_color GL_EXT_shader_image_load_formatted GL_EXT_shader_image_load_store GL_EXT_shader_integer_mix GL_EXT_shadow_funcs GL_EXT_sparse_texture2 GL_EXT_stencil_two_side GL_EXT_stencil_wrap GL_EXT_texture3D GL_EXT_texture_array GL_EXT_texture_buffer_object GL_EXT_texture_compression_dxt1 GL_EXT_texture_compression_latc GL_EXT_texture_compression_rgtc GL_EXT_texture_compression_s3tc GL_EXT_texture_cube_map GL_EXT_texture_edge_clamp GL_EXT_texture_env_add GL_EXT_texture_env_combine GL_EXT_texture_env_dot3 GL_EXT_texture_filter_anisotropic GL_EXT_texture_filter_minmax GL_EXT_texture_integer GL_EXT_texture_lod GL_EXT_texture_lod_bias GL_EXT_texture_mirror_clamp GL_EXT_texture_object GL_EXT_texture_sRGB GL_EXT_texture_sRGB_R8 GL_EXT_texture_sRGB_decode GL_EXT_texture_shadow_lod GL_EXT_texture_shared_exponent GL_EXT_texture_storage GL_EXT_texture_swizzle GL_EXT_timer_query GL_EXT_transform_feedback2 GL_EXT_vertex_array GL_EXT_vertex_array_bgra GL_EXT_vertex_attrib_64bit GL_EXT_window_rectangles GL_EXT_x11_sync_object GL_IBM_rasterpos_clip GL_IBM_texture_mirrored_repeat GL_KHR_blend_equation_advanced GL_KHR_blend_equation_advanced_coherent GL_KHR_context_flush_control GL_KHR_debug GL_KHR_no_error GL_KHR_parallel_shader_compile GL_KHR_robust_buffer_access_behavior GL_KHR_robustness GL_KHR_shader_subgroup GL_KTX_buffer_region GL_NVX_blend_equation_advanced_multi_draw_buffers GL_NVX_conditional_render GL_NVX_gpu_memory_info GL_NVX_nvenc_interop GL_NVX_progress_fence GL_NV_ES1_1_compatibility GL_NV_ES3_1_compatibility GL_NV_alpha_to_coverage_dither_control GL_NV_bindless_multi_draw_indirect GL_NV_bindless_multi_draw_indirect_count GL_NV_bindless_texture GL_NV_blend_equation_advanced GL_NV_blend_equation_advanced_coherent GL_NV_blend_minmax_factor GL_NV_blend_square GL_NV_clip_space_w_scaling GL_NV_command_list GL_NV_compute_program5 GL_NV_conditional_render GL_NV_conservative_raster GL_NV_conservative_raster_dilate GL_NV_conservative_raster_pre_snap_triangles GL_NV_copy_depth_to_color GL_NV_copy_image GL_NV_depth_buffer_float GL_NV_depth_clamp GL_NV_draw_texture GL_NV_draw_vulkan_image GL_NV_explicit_multisample GL_NV_feature_query GL_NV_fence GL_NV_fill_rectangle GL_NV_float_buffer GL_NV_fog_distance GL_NV_fragment_coverage_to_color GL_NV_fragment_program GL_NV_fragment_program2 GL_NV_fragment_program_option GL_NV_fragment_shader_interlock GL_NV_framebuffer_mixed_samples GL_NV_framebuffer_multisample_coverage GL_NV_geometry_shader4 GL_NV_geometry_shader_passthrough GL_NV_gpu_multicast GL_NV_gpu_program4 GL_NV_gpu_program4_1 GL_NV_gpu_program5 GL_NV_gpu_program5_mem_extended GL_NV_gpu_program_fp64 GL_NV_gpu_program_multiview GL_NV_gpu_shader5 GL_NV_half_float GL_NV_internalformat_sample_query GL_NV_light_max_exponent GL_NV_memory_attachment GL_NV_memory_object_sparse GL_NV_multisample_coverage GL_NV_multisample_filter_hint GL_NV_occlusion_query GL_NV_packed_depth_stencil GL_NV_parameter_buffer_object GL_NV_parameter_buffer_object2 GL_NV_path_rendering GL_NV_path_rendering_shared_edge GL_NV_pixel_data_range GL_NV_point_sprite GL_NV_primitive_restart GL_NV_query_resource GL_NV_query_resource_tag GL_NV_register_combiners GL_NV_register_combiners2 GL_NV_robustness_video_memory_purge GL_NV_sample_locations GL_NV_sample_mask_override_coverage GL_NV_shader_atomic_counters GL_NV_shader_atomic_float GL_NV_shader_atomic_float64 GL_NV_shader_atomic_fp16_vector GL_NV_shader_atomic_int64 GL_NV_shader_buffer_load GL_NV_shader_storage_buffer_object GL_NV_shader_subgroup_partitioned GL_NV_shader_thread_group GL_NV_shader_thread_shuffle GL_NV_stereo_view_rendering GL_NV_texgen_reflection GL_NV_texture_barrier GL_NV_texture_compression_vtc GL_NV_texture_env_combine4 GL_NV_texture_multisample GL_NV_texture_rectangle GL_NV_texture_rectangle_compressed GL_NV_texture_shader GL_NV_texture_shader2 GL_NV_texture_shader3 GL_NV_timeline_semaphore GL_NV_transform_feedback GL_NV_transform_feedback2 GL_NV_uniform_buffer_std430_layout GL_NV_uniform_buffer_unified_memory GL_NV_vdpau_interop GL_NV_vdpau_interop2 GL_NV_vertex_array_range GL_NV_vertex_array_range2 GL_NV_vertex_attrib_integer_64bit GL_NV_vertex_buffer_unified_memory GL_NV_vertex_program GL_NV_vertex_program1_1 GL_NV_vertex_program2 GL_NV_vertex_program2_option GL_NV_vertex_program3 GL_NV_viewport_array2 GL_NV_viewport_swizzle GL_OVR_multiview GL_OVR_multiview2 GL_S3_s3tc GL_SGIS_generate_mipmap GL_SGIS_texture_lod GL_SGIX_depth_texture GL_SGIX_shadow GL_SUN_slice_accum GL_ANDROID_extension_pack_es31a GL_EXT_EGL_image_external_wrap_modes GL_EXT_base_instance GL_EXT_blend_func_extended GL_EXT_blend_minmax GL_EXT_buffer_storage GL_EXT_clear_texture GL_EXT_clip_control GL_EXT_clip_cull_distance GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float GL_EXT_compressed_ETC1_RGB8_sub_texture GL_EXT_conservative_depth GL_EXT_copy_image GL_EXT_debug_label GL_EXT_depth_clamp GL_EXT_discard_framebuffer GL_EXT_disjoint_timer_query GL_EXT_draw_buffers_indexed GL_EXT_draw_elements_base_vertex GL_EXT_draw_transform_feedback GL_EXT_float_blend GL_EXT_frag_depth GL_EXT_geometry_point_size GL_EXT_geometry_shader GL_EXT_gpu_shader5 GL_EXT_map_buffer_range GL_EXT_memory_object GL_EXT_memory_object_fd GL_EXT_multi_draw_indirect GL_EXT_multisample_compatibility GL_EXT_multisampled_render_to_texture GL_EXT_multisampled_render_to_texture2 GL_EXT_multiview_texture_multisample GL_EXT_multiview_timer_query GL_EXT_occlusion_query_boolean GL_EXT_polygon_offset_clamp GL_EXT_post_depth_coverage GL_EXT_primitive_bounding_box GL_EXT_raster_multisample GL_EXT_read_format_bgra GL_EXT_render_snorm GL_EXT_robustness GL_EXT_sRGB GL_EXT_sRGB_write_control GL_EXT_semaphore GL_EXT_semaphore_fd GL_EXT_separate_shader_objects GL_EXT_shader_group_vote GL_EXT_shader_implicit_conversions GL_EXT_shader_integer_mix GL_EXT_shader_io_blocks GL_EXT_shader_non_constant_global_initializers GL_EXT_shader_texture_lod GL_EXT_shadow_samplers GL_EXT_sparse_texture GL_EXT_sparse_texture2 GL_EXT_tessellation_point_size GL_EXT_tessellation_shader GL_EXT_texture_border_clamp GL_EXT_texture_buffer GL_EXT_texture_compression_bptc GL_EXT_texture_compression_dxt1 GL_EXT_texture_compression_rgtc GL_EXT_texture_compression_s3tc GL_EXT_texture_cube_map_array GL_EXT_texture_filter_anisotropic GL_EXT_texture_filter_minmax GL_EXT_texture_format_BGRA8888 GL_EXT_texture_mirror_clamp_to_edge GL_EXT_texture_norm16 GL_EXT_texture_query_lod GL_EXT_texture_rg GL_EXT_texture_sRGB_R8 GL_EXT_texture_sRGB_decode GL_EXT_texture_shadow_lod GL_EXT_texture_storage GL_EXT_texture_view GL_EXT_unpack_subimage GL_EXT_window_rectangles GL_KHR_blend_equation_advanced GL_KHR_blend_equation_advanced_coherent GL_KHR_context_flush_control GL_KHR_debug GL_KHR_no_error GL_KHR_parallel_shader_compile GL_KHR_robust_buffer_access_behavior GL_KHR_robustness GL_KHR_shader_subgroup GL_KHR_texture_compression_astc_hdr GL_KHR_texture_compression_astc_ldr GL_KHR_texture_compression_astc_sliced_3d GL_NVX_blend_equation_advanced_multi_draw_buffers GL_NV_bgr GL_NV_bindless_texture GL_NV_blend_equation_advanced GL_NV_blend_equation_advanced_coherent GL_NV_blend_minmax_factor GL_NV_clip_space_w_scaling GL_NV_conditional_render GL_NV_conservative_raster GL_NV_conservative_raster_pre_snap_triangles GL_NV_copy_buffer GL_NV_copy_image GL_NV_draw_buffers GL_NV_draw_instanced GL_NV_draw_texture GL_NV_draw_vulkan_image GL_NV_explicit_attrib_location GL_NV_fbo_color_attachments GL_NV_fill_rectangle GL_NV_fragment_coverage_to_color GL_NV_fragment_shader_interlock GL_NV_framebuffer_blit GL_NV_framebuffer_mixed_samples GL_NV_framebuffer_multisample GL_NV_generate_mipmap_sRGB GL_NV_geometry_shader_passthrough GL_NV_gpu_shader5 GL_NV_image_formats GL_NV_instanced_arrays GL_NV_internalformat_sample_query GL_NV_memory_attachment GL_NV_memory_object_sparse GL_NV_non_square_matrices GL_NV_occlusion_query_samples GL_NV_pack_subimage GL_NV_packed_float GL_NV_packed_float_linear GL_NV_path_rendering GL_NV_path_rendering_shared_edge GL_NV_pixel_buffer_object GL_NV_polygon_mode GL_NV_read_buffer GL_NV_read_depth GL_NV_read_depth_stencil GL_NV_read_stencil GL_NV_sRGB_formats GL_NV_sample_locations GL_NV_sample_mask_override_coverage GL_NV_shader_atomic_fp16_vector GL_NV_shader_noperspective_interpolation GL_NV_shader_subgroup_partitioned GL_NV_shadow_samplers_array GL_NV_shadow_samplers_cube GL_NV_stereo_view_rendering GL_NV_texture_array GL_NV_texture_barrier GL_NV_texture_border_clamp GL_NV_texture_compression_latc GL_NV_texture_compression_s3tc GL_NV_texture_compression_s3tc_update GL_NV_timeline_semaphore GL_NV_timer_query GL_NV_viewport_array GL_NV_viewport_array2 GL_NV_viewport_swizzle GL_OES_compressed_ETC1_RGB8_texture GL_OES_copy_image GL_OES_depth24 GL_OES_depth32 GL_OES_depth_texture GL_OES_depth_texture_cube_map GL_OES_draw_buffers_indexed GL_OES_draw_elements_base_vertex GL_OES_element_index_uint GL_OES_fbo_render_mipmap GL_OES_geometry_point_size GL_OES_geometry_shader GL_OES_get_program_binary GL_OES_gpu_shader5 GL_OES_mapbuffer GL_OES_packed_depth_stencil GL_OES_primitive_bounding_box GL_OES_rgb8_rgba8 GL_OES_sample_shading GL_OES_sample_variables GL_OES_shader_image_atomic GL_OES_shader_io_blocks GL_OES_shader_multisample_interpolation GL_OES_standard_derivatives GL_OES_tessellation_point_size GL_OES_tessellation_shader GL_OES_texture_border_clamp GL_OES_texture_buffer GL_OES_texture_cube_map_array GL_OES_texture_float GL_OES_texture_float_linear GL_OES_texture_half_float GL_OES_texture_half_float_linear GL_OES_texture_npot GL_OES_texture_stencil8 GL_OES_texture_storage_multisample_2d_array GL_OES_texture_view GL_OES_vertex_array_object GL_OES_vertex_half_float GL_OES_viewport_array GL_OVR_multiview GL_OVR_multiview2 GL_OVR_multiview_multisampled_render_to_texture" + +# This was automated via a script so I might have missed some +ext="GL_AMD_multi_draw_indirect GL_AMD_seamless_cubemap_per_texture GL_AMD_vertex_shader_layer GL_AMD_vertex_shader_viewport_index" +ext="$ext GL_ARB_ES2_compatibility GL_ARB_ES3_1_compatibility GL_ARB_ES3_2_compatibility GL_ARB_ES3_compatibility GL_ARB_arrays_of_arrays" +ext="$ext GL_ARB_base_instance GL_ARB_bindless_texture GL_ARB_blend_func_extended GL_ARB_buffer_storage GL_ARB_clear_buffer_object GL_ARB_clear_texture" +ext="$ext GL_ARB_clip_control GL_ARB_color_buffer_float GL_ARB_compressed_texture_pixel_storage GL_ARB_compute_shader GL_ARB_compute_variable_group_size" +ext="$ext GL_ARB_conditional_render_inverted GL_ARB_conservative_depth GL_ARB_copy_buffer GL_ARB_copy_image GL_ARB_cull_distance GL_ARB_debug_output" +ext="$ext GL_ARB_depth_buffer_float GL_ARB_depth_clamp GL_ARB_depth_texture GL_ARB_derivative_control GL_ARB_direct_state_access GL_ARB_draw_buffers" +ext="$ext GL_ARB_draw_buffers_blend GL_ARB_draw_elements_base_vertex GL_ARB_draw_indirect GL_ARB_draw_instanced GL_ARB_enhanced_layouts" +ext="$ext GL_ARB_explicit_attrib_location GL_ARB_explicit_uniform_location GL_ARB_fragment_coord_conventions GL_ARB_fragment_layer_viewport" +ext="$ext GL_ARB_fragment_program GL_ARB_fragment_program_shadow GL_ARB_fragment_shader GL_ARB_fragment_shader_interlock GL_ARB_framebuffer_no_attachments" +ext="$ext GL_ARB_framebuffer_object GL_ARB_framebuffer_sRGB GL_ARB_geometry_shader4 GL_ARB_get_program_binary GL_ARB_get_texture_sub_image GL_ARB_gl_spirv" +ext="$ext GL_ARB_gpu_shader5 GL_ARB_gpu_shader_fp64 GL_ARB_gpu_shader_int64 GL_ARB_half_float_pixel GL_ARB_half_float_vertex GL_ARB_imaging" +ext="$ext GL_ARB_indirect_parameters GL_ARB_instanced_arrays GL_ARB_internalformat_query GL_ARB_internalformat_query2 GL_ARB_invalidate_subdata" +ext="$ext GL_ARB_map_buffer_alignment GL_ARB_map_buffer_range GL_ARB_multi_bind GL_ARB_multi_draw_indirect GL_ARB_multisample GL_ARB_multitexture" +ext="$ext GL_ARB_occlusion_query GL_ARB_occlusion_query2 GL_ARB_parallel_shader_compile GL_ARB_pipeline_statistics_query GL_ARB_pixel_buffer_object" +ext="$ext GL_ARB_point_parameters GL_ARB_point_sprite GL_ARB_polygon_offset_clamp GL_ARB_post_depth_coverage GL_ARB_program_interface_query" +ext="$ext GL_ARB_provoking_vertex GL_ARB_query_buffer_object GL_ARB_robust_buffer_access_behavior GL_ARB_robustness GL_ARB_sample_locations" +ext="$ext GL_ARB_sample_shading GL_ARB_sampler_objects GL_ARB_seamless_cube_map GL_ARB_seamless_cubemap_per_texture GL_ARB_separate_shader_objects" +ext="$ext GL_ARB_shader_atomic_counter_ops GL_ARB_shader_atomic_counters GL_ARB_shader_ballot GL_ARB_shader_bit_encoding GL_ARB_shader_clock" +ext="$ext GL_ARB_shader_draw_parameters GL_ARB_shader_group_vote GL_ARB_shader_image_load_store GL_ARB_shader_image_size GL_ARB_shader_objects" +ext="$ext GL_ARB_shader_precision GL_ARB_shader_storage_buffer_object GL_ARB_shader_subroutine GL_ARB_shader_texture_image_samples" +ext="$ext GL_ARB_shader_texture_lod GL_ARB_shader_viewport_layer_array GL_ARB_shading_language_100 GL_ARB_shading_language_420pack" +ext="$ext GL_ARB_shading_language_include GL_ARB_shading_language_packing GL_ARB_shadow GL_ARB_sparse_buffer GL_ARB_sparse_texture GL_ARB_sparse_texture2" +ext="$ext GL_ARB_sparse_texture_clamp GL_ARB_spirv_extensions GL_ARB_stencil_texturing GL_ARB_sync GL_ARB_tessellation_shader GL_ARB_texture_barrier" +ext="$ext GL_ARB_texture_border_clamp GL_ARB_texture_buffer_object GL_ARB_texture_buffer_object_rgb32 GL_ARB_texture_buffer_range GL_ARB_texture_compression" +ext="$ext GL_ARB_texture_compression_bptc GL_ARB_texture_compression_rgtc GL_ARB_texture_cube_map GL_ARB_texture_cube_map_array GL_ARB_texture_env_add" +ext="$ext GL_ARB_texture_env_combine GL_ARB_texture_env_crossbar GL_ARB_texture_env_dot3 GL_ARB_texture_filter_anisotropic GL_ARB_texture_filter_minmax" +ext="$ext GL_ARB_texture_float GL_ARB_texture_gather GL_ARB_texture_mirror_clamp_to_edge GL_ARB_texture_mirrored_repeat GL_ARB_texture_multisample" +ext="$ext GL_ARB_texture_non_power_of_two GL_ARB_texture_query_levels GL_ARB_texture_query_lod GL_ARB_texture_rectangle GL_ARB_texture_rg" +ext="$ext GL_ARB_texture_rgb10_a2ui GL_ARB_texture_stencil8 GL_ARB_texture_storage GL_ARB_texture_storage_multisample GL_ARB_texture_swizzle" +ext="$ext GL_ARB_texture_view GL_ARB_timer_query GL_ARB_transform_feedback2 GL_ARB_transform_feedback3 GL_ARB_transform_feedback_instanced" +ext="$ext GL_ARB_transform_feedback_overflow_query GL_ARB_transpose_matrix GL_ARB_uniform_buffer_object GL_ARB_vertex_array_bgra" +ext="$ext GL_ARB_vertex_array_object GL_ARB_vertex_attrib_64bit GL_ARB_vertex_attrib_binding GL_ARB_vertex_buffer_object" +ext="$ext GL_ARB_vertex_program GL_ARB_vertex_shader GL_ARB_vertex_type_10f_11f_11f_rev GL_ARB_vertex_type_2_10_10_10_rev" +ext="$ext GL_ARB_viewport_array GL_ARB_window_pos GL_ATI_draw_buffers GL_ATI_texture_float GL_ATI_texture_mirror_once" +ext="$ext GL_EXTX_framebuffer_mixed_formats GL_EXT_Cg_shader GL_EXT_abgr GL_EXT_bgra GL_EXT_bindable_uniform" +ext="$ext GL_EXT_blend_color GL_EXT_blend_equation_separate GL_EXT_blend_func_separate GL_EXT_blend_minmax" +ext="$ext GL_EXT_blend_subtract GL_EXT_compiled_vertex_array GL_EXT_depth_bounds_test GL_EXT_direct_state_access" +ext="$ext GL_EXT_draw_buffers2 GL_EXT_draw_instanced GL_EXT_draw_range_elements GL_EXT_fog_coord GL_EXT_framebuffer_blit" +ext="$ext GL_EXT_framebuffer_multisample GL_EXT_framebuffer_multisample_blit_scaled GL_EXT_framebuffer_object" +ext="$ext GL_EXT_framebuffer_sRGB GL_EXT_geometry_shader4 GL_EXT_gpu_program_parameters GL_EXT_gpu_shader4" +ext="$ext GL_EXT_import_sync_object GL_EXT_memory_object GL_EXT_memory_object_fd GL_EXT_multi_draw_arrays" +ext="$ext GL_EXT_multiview_texture_multisample GL_EXT_multiview_timer_query GL_EXT_packed_depth_stencil" +ext="$ext GL_EXT_packed_float GL_EXT_packed_pixels GL_EXT_pixel_buffer_object GL_EXT_point_parameters" +ext="$ext GL_EXT_polygon_offset_clamp GL_EXT_post_depth_coverage GL_EXT_provoking_vertex GL_EXT_raster_multisample" +ext="$ext GL_EXT_rescale_normal GL_EXT_secondary_color GL_EXT_semaphore GL_EXT_semaphore_fd" +ext="$ext GL_EXT_separate_shader_objects GL_EXT_separate_specular_color GL_EXT_shader_image_load_formatted" +ext="$ext GL_EXT_shader_image_load_store GL_EXT_shader_integer_mix GL_EXT_shadow_funcs GL_EXT_sparse_texture2" +ext="$ext GL_EXT_stencil_two_side GL_EXT_stencil_wrap GL_EXT_texture3D GL_EXT_texture_array" +ext="$ext GL_EXT_texture_buffer_object GL_EXT_texture_compression_dxt1 GL_EXT_texture_compression_latc" +ext="$ext GL_EXT_texture_compression_rgtc GL_EXT_texture_compression_s3tc GL_EXT_texture_cube_map" +ext="$ext GL_EXT_texture_edge_clamp GL_EXT_texture_env_add GL_EXT_texture_env_combine GL_EXT_texture_env_dot3" +ext="$ext GL_EXT_texture_filter_anisotropic GL_EXT_texture_filter_minmax GL_EXT_texture_integer" +ext="$ext GL_EXT_texture_lod GL_EXT_texture_lod_bias GL_EXT_texture_mirror_clamp GL_EXT_texture_object" +ext="$ext GL_EXT_texture_sRGB GL_EXT_texture_sRGB_R8 GL_EXT_texture_sRGB_decode GL_EXT_texture_shadow_lod" +ext="$ext GL_EXT_texture_shared_exponent GL_EXT_texture_storage GL_EXT_texture_swizzle GL_EXT_timer_query" +ext="$ext GL_EXT_transform_feedback2 GL_EXT_vertex_array GL_EXT_vertex_array_bgra GL_EXT_vertex_attrib_64bit" +ext="$ext GL_EXT_window_rectangles GL_EXT_x11_sync_object GL_IBM_rasterpos_clip GL_IBM_texture_mirrored_repeat" +ext="$ext GL_KHR_blend_equation_advanced GL_KHR_blend_equation_advanced_coherent GL_KHR_context_flush_control" +ext="$ext GL_KHR_debug GL_KHR_no_error GL_KHR_parallel_shader_compile GL_KHR_robust_buffer_access_behavior" +ext="$ext GL_KHR_robustness GL_KHR_shader_subgroup GL_KTX_buffer_region GL_NVX_blend_equation_advanced_multi_draw_buffers" +ext="$ext GL_NVX_conditional_render GL_NVX_gpu_memory_info GL_NVX_nvenc_interop GL_NVX_progress_fence" +ext="$ext GL_NV_ES1_1_compatibility GL_NV_ES3_1_compatibility GL_NV_alpha_to_coverage_dither_control" +ext="$ext GL_NV_bindless_multi_draw_indirect GL_NV_bindless_multi_draw_indirect_count GL_NV_bindless_texture" +ext="$ext GL_NV_blend_equation_advanced GL_NV_blend_equation_advanced_coherent GL_NV_blend_minmax_factor" +ext="$ext GL_NV_blend_square GL_NV_clip_space_w_scaling GL_NV_command_list GL_NV_compute_program5" +ext="$ext GL_NV_conditional_render GL_NV_conservative_raster GL_NV_conservative_raster_dilate" +ext="$ext GL_NV_conservative_raster_pre_snap_triangles GL_NV_copy_depth_to_color GL_NV_copy_image" +ext="$ext GL_NV_depth_buffer_float GL_NV_depth_clamp GL_NV_draw_texture GL_NV_draw_vulkan_image" +ext="$ext GL_NV_explicit_multisample GL_NV_feature_query GL_NV_fence GL_NV_fill_rectangle" +ext="$ext GL_NV_float_buffer GL_NV_fog_distance GL_NV_fragment_coverage_to_color GL_NV_fragment_program" +ext="$ext GL_NV_fragment_program2 GL_NV_fragment_program_option GL_NV_fragment_shader_interlock" +ext="$ext GL_NV_framebuffer_mixed_samples GL_NV_framebuffer_multisample_coverage GL_NV_geometry_shader4" +ext="$ext GL_NV_geometry_shader_passthrough GL_NV_gpu_multicast GL_NV_gpu_program4 GL_NV_gpu_program4_1" +ext="$ext GL_NV_gpu_program5 GL_NV_gpu_program5_mem_extended GL_NV_gpu_program_fp64 GL_NV_gpu_program_multiview" +ext="$ext GL_NV_gpu_shader5 GL_NV_half_float GL_NV_internalformat_sample_query GL_NV_light_max_exponent" +ext="$ext GL_NV_memory_attachment GL_NV_memory_object_sparse GL_NV_multisample_coverage GL_NV_multisample_filter_hint" +ext="$ext GL_NV_occlusion_query GL_NV_packed_depth_stencil GL_NV_parameter_buffer_object GL_NV_parameter_buffer_object2" +ext="$ext GL_NV_path_rendering GL_NV_path_rendering_shared_edge GL_NV_pixel_data_range GL_NV_point_sprite" +ext="$ext GL_NV_primitive_restart GL_NV_query_resource GL_NV_query_resource_tag GL_NV_register_combiners" +ext="$ext GL_NV_register_combiners2 GL_NV_robustness_video_memory_purge GL_NV_sample_locations" +ext="$ext GL_NV_sample_mask_override_coverage GL_NV_shader_atomic_counters GL_NV_shader_atomic_float" +ext="$ext GL_NV_shader_atomic_float64 GL_NV_shader_atomic_fp16_vector GL_NV_shader_atomic_int64" +ext="$ext GL_NV_shader_buffer_load GL_NV_shader_storage_buffer_object GL_NV_shader_subgroup_partitioned" +ext="$ext GL_NV_shader_thread_group GL_NV_shader_thread_shuffle GL_NV_stereo_view_rendering GL_NV_texgen_reflection" +ext="$ext GL_NV_texture_barrier GL_NV_texture_compression_vtc GL_NV_texture_env_combine4 GL_NV_texture_multisample" +ext="$ext GL_NV_texture_rectangle GL_NV_texture_rectangle_compressed GL_NV_texture_shader GL_NV_texture_shader2" +ext="$ext GL_NV_texture_shader3 GL_NV_timeline_semaphore GL_NV_transform_feedback GL_NV_transform_feedback2" +ext="$ext GL_NV_uniform_buffer_std430_layout GL_NV_uniform_buffer_unified_memory GL_NV_vdpau_interop" +ext="$ext GL_NV_vdpau_interop2 GL_NV_vertex_array_range GL_NV_vertex_array_range2 GL_NV_vertex_attrib_integer_64bit" +ext="$ext GL_NV_vertex_buffer_unified_memory GL_NV_vertex_program GL_NV_vertex_program1_1 GL_NV_vertex_program2" +ext="$ext GL_NV_vertex_program2_option GL_NV_vertex_program3 GL_NV_viewport_array2 GL_NV_viewport_swizzle" +ext="$ext GL_OVR_multiview GL_OVR_multiview2 GL_S3_s3tc GL_SGIS_generate_mipmap GL_SGIS_texture_lod" +ext="$ext GL_SGIX_depth_texture GL_SGIX_shadow GL_SUN_slice_accum GL_AMD_multi_draw_indirect" +ext="$ext GL_AMD_seamless_cubemap_per_texture GL_AMD_vertex_shader_layer GL_AMD_vertex_shader_viewport_index" +ext="$ext GL_ARB_ES2_compatibility GL_ARB_ES3_1_compatibility GL_ARB_ES3_2_compatibility GL_ARB_ES3_compatibility" +ext="$ext GL_ARB_arrays_of_arrays GL_ARB_base_instance GL_ARB_bindless_texture GL_ARB_blend_func_extended" +ext="$ext GL_ARB_buffer_storage GL_ARB_clear_buffer_object GL_ARB_clear_texture GL_ARB_clip_control" +ext="$ext GL_ARB_color_buffer_float GL_ARB_compatibility GL_ARB_compressed_texture_pixel_storage" +ext="$ext GL_ARB_compute_shader GL_ARB_compute_variable_group_size GL_ARB_conditional_render_inverted" +ext="$ext GL_ARB_conservative_depth GL_ARB_copy_buffer GL_ARB_copy_image GL_ARB_cull_distance" +ext="$ext GL_ARB_debug_output GL_ARB_depth_buffer_float GL_ARB_depth_clamp GL_ARB_depth_texture" +ext="$ext GL_ARB_derivative_control GL_ARB_direct_state_access GL_ARB_draw_buffers GL_ARB_draw_buffers_blend" +ext="$ext GL_ARB_draw_elements_base_vertex GL_ARB_draw_indirect GL_ARB_draw_instanced GL_ARB_enhanced_layouts" +ext="$ext GL_ARB_explicit_attrib_location GL_ARB_explicit_uniform_location GL_ARB_fragment_coord_conventions" +ext="$ext GL_ARB_fragment_layer_viewport GL_ARB_fragment_program GL_ARB_fragment_program_shadow" +ext="$ext GL_ARB_fragment_shader GL_ARB_fragment_shader_interlock GL_ARB_framebuffer_no_attachments" +ext="$ext GL_ARB_framebuffer_object GL_ARB_framebuffer_sRGB GL_ARB_geometry_shader4 GL_ARB_get_program_binary" +ext="$ext GL_ARB_get_texture_sub_image GL_ARB_gl_spirv GL_ARB_gpu_shader5 GL_ARB_gpu_shader_fp64" +ext="$ext GL_ARB_gpu_shader_int64 GL_ARB_half_float_pixel GL_ARB_half_float_vertex GL_ARB_imaging" +ext="$ext GL_ARB_indirect_parameters GL_ARB_instanced_arrays GL_ARB_internalformat_query GL_ARB_internalformat_query2" +ext="$ext GL_ARB_invalidate_subdata GL_ARB_map_buffer_alignment GL_ARB_map_buffer_range GL_ARB_multi_bind" +ext="$ext GL_ARB_multi_draw_indirect GL_ARB_multisample GL_ARB_multitexture GL_ARB_occlusion_query" +ext="$ext GL_ARB_occlusion_query2 GL_ARB_parallel_shader_compile GL_ARB_pipeline_statistics_query" +ext="$ext GL_ARB_pixel_buffer_object GL_ARB_point_parameters GL_ARB_point_sprite GL_ARB_polygon_offset_clamp" +ext="$ext GL_ARB_post_depth_coverage GL_ARB_program_interface_query GL_ARB_provoking_vertex GL_ARB_query_buffer_object" +ext="$ext GL_ARB_robust_buffer_access_behavior GL_ARB_robustness GL_ARB_sample_locations GL_ARB_sample_shading" +ext="$ext GL_ARB_sampler_objects GL_ARB_seamless_cube_map GL_ARB_seamless_cubemap_per_texture" +ext="$ext GL_ARB_separate_shader_objects GL_ARB_shader_atomic_counter_ops GL_ARB_shader_atomic_counters" +ext="$ext GL_ARB_shader_ballot GL_ARB_shader_bit_encoding GL_ARB_shader_clock GL_ARB_shader_draw_parameters" +ext="$ext GL_ARB_shader_group_vote GL_ARB_shader_image_load_store GL_ARB_shader_image_size GL_ARB_shader_objects" +ext="$ext GL_ARB_shader_precision GL_ARB_shader_storage_buffer_object GL_ARB_shader_subroutine" +ext="$ext GL_ARB_shader_texture_image_samples GL_ARB_shader_texture_lod GL_ARB_shader_viewport_layer_array" +ext="$ext GL_ARB_shading_language_100 GL_ARB_shading_language_420pack GL_ARB_shading_language_include" +ext="$ext GL_ARB_shading_language_packing GL_ARB_shadow GL_ARB_sparse_buffer GL_ARB_sparse_texture" +ext="$ext GL_ARB_sparse_texture2 GL_ARB_sparse_texture_clamp GL_ARB_spirv_extensions GL_ARB_stencil_texturing" +ext="$ext GL_ARB_sync GL_ARB_tessellation_shader GL_ARB_texture_barrier GL_ARB_texture_border_clamp" +ext="$ext GL_ARB_texture_buffer_object GL_ARB_texture_buffer_object_rgb32 GL_ARB_texture_buffer_range" +ext="$ext GL_ARB_texture_compression GL_ARB_texture_compression_bptc GL_ARB_texture_compression_rgtc" +ext="$ext GL_ARB_texture_cube_map GL_ARB_texture_cube_map_array GL_ARB_texture_env_add GL_ARB_texture_env_combine" +ext="$ext GL_ARB_texture_env_crossbar GL_ARB_texture_env_dot3 GL_ARB_texture_filter_anisotropic" +ext="$ext GL_ARB_texture_filter_minmax GL_ARB_texture_float GL_ARB_texture_gather GL_ARB_texture_mirror_clamp_to_edge" +ext="$ext GL_ARB_texture_mirrored_repeat GL_ARB_texture_multisample GL_ARB_texture_non_power_of_two" +ext="$ext GL_ARB_texture_query_levels GL_ARB_texture_query_lod GL_ARB_texture_rectangle GL_ARB_texture_rg" +ext="$ext GL_ANDROID_extension_pack_es31a GL_EXT_EGL_image_external_wrap_modes GL_EXT_base_instance" +ext="$ext GL_EXT_blend_func_extended GL_EXT_blend_minmax GL_EXT_buffer_storage GL_EXT_clear_texture" +ext="$ext GL_EXT_clip_control GL_EXT_clip_cull_distance GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float" +ext="$ext GL_EXT_compressed_ETC1_RGB8_sub_texture GL_EXT_conservative_depth GL_EXT_copy_image GL_EXT_debug_label" +ext="$ext GL_EXT_depth_clamp GL_EXT_discard_framebuffer GL_EXT_disjoint_timer_query GL_EXT_draw_buffers_indexed" +ext="$ext GL_EXT_draw_elements_base_vertex GL_EXT_draw_transform_feedback GL_EXT_float_blend GL_EXT_frag_depth" +ext="$ext GL_EXT_geometry_point_size GL_EXT_geometry_shader GL_EXT_gpu_shader5 GL_EXT_map_buffer_range" +ext="$ext GL_EXT_memory_object GL_EXT_memory_object_fd GL_EXT_multi_draw_indirect GL_EXT_multisample_compatibility" +ext="$ext GL_EXT_multisampled_render_to_texture GL_EXT_multisampled_render_to_texture2 GL_EXT_multiview_texture_multisample" +ext="$ext GL_EXT_multiview_timer_query GL_EXT_occlusion_query_boolean GL_EXT_polygon_offset_clamp" +ext="$ext GL_EXT_post_depth_coverage GL_EXT_primitive_bounding_box GL_EXT_raster_multisample GL_EXT_read_format_bgra" +ext="$ext GL_EXT_render_snorm GL_EXT_robustness GL_EXT_sRGB GL_EXT_sRGB_write_control GL_EXT_semaphore" +ext="$ext GL_EXT_semaphore_fd GL_EXT_separate_shader_objects GL_EXT_shader_group_vote GL_EXT_shader_implicit_conversions" +ext="$ext GL_EXT_shader_integer_mix GL_EXT_shader_io_blocks GL_EXT_shader_non_constant_global_initializers" +ext="$ext GL_EXT_shader_texture_lod GL_EXT_shadow_samplers GL_EXT_sparse_texture GL_EXT_sparse_texture2" +ext="$ext GL_EXT_tessellation_point_size GL_EXT_tessellation_shader GL_EXT_texture_border_clamp GL_EXT_texture_buffer" +ext="$ext GL_EXT_texture_compression_bptc GL_EXT_texture_compression_dxt1 GL_EXT_texture_compression_rgtc" +ext="$ext GL_EXT_texture_compression_s3tc GL_EXT_texture_cube_map_array GL_EXT_texture_filter_anisotropic" +ext="$ext GL_EXT_texture_filter_minmax GL_EXT_texture_format_BGRA8888 GL_EXT_texture_mirror_clamp_to_edge" +ext="$ext GL_EXT_texture_norm16 GL_EXT_texture_query_lod GL_EXT_texture_rg GL_EXT_texture_sRGB_R8" +ext="$ext GL_EXT_texture_sRGB_decode GL_EXT_texture_shadow_lod GL_EXT_texture_storage GL_EXT_texture_view" +ext="$ext GL_EXT_unpack_subimage GL_EXT_window_rectangles GL_KHR_blend_equation_advanced GL_KHR_blend_equation_advanced_coherent" +ext="$ext GL_KHR_context_flush_control GL_KHR_debug GL_KHR_no_error GL_KHR_parallel_shader_compile" +ext="$ext GL_KHR_robust_buffer_access_behavior GL_KHR_robustness GL_KHR_shader_subgroup GL_KHR_texture_compression_astc_hdr" +ext="$ext GL_KHR_texture_compression_astc_ldr GL_KHR_texture_compression_astc_sliced_3d GL_NVX_blend_equation_advanced_multi_draw_buffers" +ext="$ext GL_NV_bgr GL_NV_bindless_texture GL_NV_blend_equation_advanced GL_NV_blend_equation_advanced_coherent" +ext="$ext GL_NV_blend_minmax_factor GL_NV_clip_space_w_scaling GL_NV_conditional_render GL_NV_conservative_raster" +ext="$ext GL_NV_conservative_raster_pre_snap_triangles GL_NV_copy_buffer GL_NV_copy_image GL_NV_draw_buffers" +ext="$ext GL_NV_draw_instanced GL_NV_draw_texture GL_NV_draw_vulkan_image GL_NV_explicit_attrib_location" +ext="$ext GL_NV_fbo_color_attachments GL_NV_fill_rectangle GL_NV_fragment_coverage_to_color GL_NV_fragment_shader_interlock" +ext="$ext GL_NV_framebuffer_blit GL_NV_framebuffer_mixed_samples GL_NV_framebuffer_multisample GL_NV_generate_mipmap_sRGB" +ext="$ext GL_NV_geometry_shader_passthrough GL_NV_gpu_shader5 GL_NV_image_formats GL_NV_instanced_arrays" +ext="$ext GL_NV_internalformat_sample_query GL_NV_memory_attachment GL_NV_memory_object_sparse GL_NV_non_square_matrices" +ext="$ext GL_NV_occlusion_query_samples GL_NV_pack_subimage GL_NV_packed_float GL_NV_packed_float_linear" +ext="$ext GL_NV_path_rendering GL_NV_path_rendering_shared_edge GL_NV_pixel_buffer_object GL_NV_polygon_mode" +ext="$ext GL_NV_read_buffer GL_NV_read_depth GL_NV_read_depth_stencil GL_NV_read_stencil GL_NV_sRGB_formats" +ext="$ext GL_NV_sample_locations GL_NV_sample_mask_override_coverage GL_NV_shader_atomic_fp16_vector" +ext="$ext GL_NV_shader_noperspective_interpolation GL_NV_shader_subgroup_partitioned GL_NV_shadow_samplers_array" +ext="$ext GL_NV_shadow_samplers_cube GL_NV_stereo_view_rendering GL_NV_texture_array GL_NV_texture_barrier" +ext="$ext GL_NV_texture_border_clamp GL_NV_texture_compression_latc GL_NV_texture_compression_s3tc GL_NV_texture_compression_s3tc_update" +ext="$ext GL_NV_timeline_semaphore GL_NV_timer_query GL_NV_viewport_array GL_NV_viewport_array2 GL_NV_viewport_swizzle" +ext="$ext GL_OES_compressed_ETC1_RGB8_texture GL_OES_copy_image GL_OES_depth24 GL_OES_depth32 GL_OES_depth_texture" +ext="$ext GL_OES_depth_texture_cube_map GL_OES_draw_buffers_indexed GL_OES_draw_elements_base_vertex GL_OES_element_index_uint" +ext="$ext GL_OES_fbo_render_mipmap GL_OES_geometry_point_size GL_OES_geometry_shader GL_OES_get_program_binary" +ext="$ext GL_OES_gpu_shader5 GL_OES_mapbuffer GL_OES_packed_depth_stencil GL_OES_primitive_bounding_box" +ext="$ext GL_OES_rgb8_rgba8 GL_OES_sample_shading GL_OES_sample_variables GL_OES_shader_image_atomic" +ext="$ext GL_OES_shader_io_blocks GL_OES_shader_multisample_interpolation GL_OES_standard_derivatives GL_OES_tessellation_point_size" +ext="$ext GL_OES_tessellation_shader GL_OES_texture_border_clamp GL_OES_texture_buffer GL_OES_texture_cube_map_array" +ext="$ext GL_OES_texture_float GL_OES_texture_float_linear GL_OES_texture_half_float GL_OES_texture_half_float_linear" +ext="$ext GL_OES_texture_npot GL_OES_texture_stencil8 GL_OES_texture_storage_multisample_2d_array GL_OES_texture_view" +ext="$ext GL_OES_vertex_array_object GL_OES_vertex_half_float GL_OES_viewport_array GL_OVR_multiview GL_OVR_multiview2" +ext="$ext GL_OVR_multiview_multisampled_render_to_texture" + +export MESA_EXTENSION_OVERRIDE="$ext" "$@" diff --git a/tools/optimize-assets.sh b/tools/optimize-assets.sh index 07facc8fa0..b7d52330f2 100755 --- a/tools/optimize-assets.sh +++ b/tools/optimize-assets.sh @@ -1,6 +1,9 @@ #!/bin/sh -e + # SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later -# Optimizes assets of eden (requires OptiPng) + +# Optimizes assets of Eden (requires OptiPng) + which optipng || exit -find . -type f -name *.png -exec optipng -o7 {} \; +find . -type f -name "*.png" -exec optipng -o7 {} \; diff --git a/tools/reset-submodules.sh b/tools/reset-submodules.sh deleted file mode 100755 index 6fdfe0bcdb..0000000000 --- a/tools/reset-submodules.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -ex - -# SPDX-FileCopyrightText: 2024 yuzu Emulator Project -# SPDX-License-Identifier: MIT - -git submodule sync -git submodule foreach --recursive git reset --hard -git submodule update --init --recursive diff --git a/tools/shellcheck.sh b/tools/shellcheck.sh new file mode 100755 index 0000000000..719c717cf2 --- /dev/null +++ b/tools/shellcheck.sh @@ -0,0 +1,11 @@ +#!/bin/sh -e + +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + +# fd is slightly faster on NVMe (the syntax sux though) +if command -v fd > /dev/null; then + fd . tools -esh -x shellcheck +else + find tools -name "*.sh" -exec shellcheck -s sh {} \; +fi \ No newline at end of file diff --git a/tools/update-cpm.sh b/tools/update-cpm.sh index 30e400209d..8bd8df2b83 100755 --- a/tools/update-cpm.sh +++ b/tools/update-cpm.sh @@ -1,3 +1,6 @@ -#!/bin/sh +#!/bin/sh -e -wget -O CMakeModules/CPM.cmake https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/get_cpm.cmake +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + +wget -O CMakeModules/CPM.cmake https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/CPM.cmake diff --git a/tools/update-icons.sh b/tools/update-icons.sh index da54156665..a2c1ae8ebf 100755 --- a/tools/update-icons.sh +++ b/tools/update-icons.sh @@ -1,8 +1,11 @@ #!/bin/sh -e + # SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later + # Updates main icons for eden -which png2icns || [ which yay && yay libicns ] || exit + +which png2icns || (which yay && yay libicns) || exit which magick || exit export EDEN_SVG_ICO="dist/dev.eden_emu.eden.svg" diff --git a/tools/url-hash.sh b/tools/url-hash.sh deleted file mode 100755 index a54dec8bb2..0000000000 --- a/tools/url-hash.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -SUM=`wget -q $1 -O - | sha512sum` -echo "$SUM" | cut -d " " -f1 From 191dd892e57abad3c56f939e83514ab16dec64ed Mon Sep 17 00:00:00 2001 From: Bix Date: Sun, 5 Oct 2025 05:41:20 +0200 Subject: [PATCH 04/24] [android] Legacy build flavor (#51) This adds a "legacy" build flavor, similar to the genshinSpoof flavor. The legacy flavor uses a white icon bg, alongside building with `YUZU_LEGACY=ON`, which applies the previously-made SD865 patches iff that value is truthy. Co-authored-by: Bixthefin <114880614+Bixthefin@users.noreply.github.com> Co-authored-by: Calchan Co-authored-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/51 Reviewed-by: MaranBr Reviewed-by: CamilleLaVey Reviewed-by: crueter Co-authored-by: Bix Co-committed-by: Bix --- CMakeLists.txt | 7 ++ src/android/app/build.gradle.kts | 98 ++++++++++++------ .../src/main/legacy/drawable/ic_icon_bg.png | Bin 0 -> 39026 bytes .../main/legacy/drawable/ic_icon_bg_orig.png | Bin 0 -> 448880 bytes src/core/arm/nce/arm_nce.cpp | 2 +- src/video_core/buffer_cache/buffer_cache.h | 15 ++- .../buffer_cache/buffer_cache_base.h | 21 +++- src/video_core/host1x/host1x.cpp | 9 ++ src/video_core/host1x/host1x.h | 7 ++ .../texture_cache/texture_cache_base.h | 9 ++ .../vulkan_common/vulkan_memory_allocator.cpp | 2 + 11 files changed, 135 insertions(+), 35 deletions(-) create mode 100644 src/android/app/src/main/legacy/drawable/ic_icon_bg.png create mode 100644 src/android/app/src/main/legacy/drawable/ic_icon_bg_orig.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f192887f7..f436c0a183 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,6 +227,8 @@ endif() # TODO(crueter): CI this? option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" ON) +option(YUZU_LEGACY "Apply patches that improve compatibility with older GPUs (e.g. Snapdragon 865) at the cost of performance" OFF) + cmake_dependent_option(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID" OFF) cmake_dependent_option(YUZU_ROOM_STANDALONE "Enable standalone room executable" ON "YUZU_ROOM" OFF) @@ -324,6 +326,11 @@ if (UNIX) add_compile_definitions(YUZU_UNIX=1) endif() +if (YUZU_LEGACY) + message(WARNING "Making legacy build. Performance may suffer.") + add_compile_definitions(YUZU_LEGACY) +endif() + if (ARCHITECTURE_arm64 AND (ANDROID OR PLATFORM_LINUX)) set(HAS_NCE 1) add_compile_definitions(HAS_NCE=1) diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts index e8d8141711..c85da039cb 100644 --- a/src/android/app/build.gradle.kts +++ b/src/android/app/build.gradle.kts @@ -57,8 +57,8 @@ android { } defaultConfig { - // TODO If this is ever modified, change application_id in strings.xml applicationId = "dev.eden.eden_emulator" + minSdk = 28 targetSdk = 36 versionName = getGitVersion() @@ -72,8 +72,30 @@ android { buildConfigField("String", "GIT_HASH", "\"${getGitHash()}\"") buildConfigField("String", "BRANCH", "\"${getBranch()}\"") + + externalNativeBuild { + cmake { + arguments.addAll(listOf( + "-DENABLE_QT=0", // Don't use QT + "-DENABLE_SDL2=0", // Don't use SDL + "-DENABLE_WEB_SERVICE=1", // Enable web service + "-DENABLE_OPENSSL=ON", + "-DANDROID_ARM_NEON=true", // cryptopp requires Neon to work + "-DYUZU_USE_CPM=ON", + "-DCPMUTIL_FORCE_BUNDLED=ON", + "-DYUZU_USE_BUNDLED_FFMPEG=ON", + "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", + "-DBUILD_TESTING=OFF", + "-DYUZU_TESTS=OFF", + "-DDYNARMIC_TESTS=OFF" + )) + + abiFilters("arm64-v8a") + } + } } + val keystoreFile = System.getenv("ANDROID_KEYSTORE_FILE") signingConfigs { if (keystoreFile != null) { @@ -94,7 +116,6 @@ android { // Define build types, which are orthogonal to product flavors. buildTypes { - // Signed by release key, allowing for upload to Play Store. release { signingConfig = if (keystoreFile != null) { @@ -103,7 +124,6 @@ android { signingConfigs.getByName("default") } - resValue("string", "app_name_suffixed", "Eden") isMinifyEnabled = true isDebuggable = false proguardFiles( @@ -116,7 +136,6 @@ android { // Attaches 'debug' suffix to version and package name, allowing installation alongside the release build. register("relWithDebInfo") { isDefault = true - resValue("string", "app_name_suffixed", "Eden Debug Release") signingConfig = signingConfigs.getByName("default") isDebuggable = true proguardFiles( @@ -132,7 +151,6 @@ android { // Attaches 'debug' suffix to version and package name, allowing installation alongside the release build. debug { signingConfig = signingConfigs.getByName("default") - resValue("string", "app_name_suffixed", "Eden Debug") isDebuggable = true isJniDebuggable = true versionNameSuffix = "-debug" @@ -140,19 +158,62 @@ android { } } + // this is really annoying but idk any other ways to fix this behavior + applicationVariants.all { + val variant = this + when { + variant.flavorName == "legacy" && variant.buildType.name == "debug" -> { + variant.resValue("string", "app_name_suffixed", "Eden Legacy Debug") + } + variant.flavorName == "mainline" && variant.buildType.name == "debug" -> { + variant.resValue("string", "app_name_suffixed", "Eden Debug") + } + variant.flavorName == "genshinSpoof" && variant.buildType.name == "debug" -> { + variant.resValue("string", "app_name_suffixed", "Eden Optimized Debug") + } + variant.flavorName == "legacy" && variant.buildType.name == "relWithDebInfo" -> { + variant.resValue("string", "app_name_suffixed", "Eden Legacy Debug Release") + } + variant.flavorName == "mainline" && variant.buildType.name == "relWithDebInfo" -> { + variant.resValue("string", "app_name_suffixed", "Eden Debug Release") + } + variant.flavorName == "genshinSpoof" && variant.buildType.name == "relWithDebInfo" -> { + variant.resValue("string", "app_name_suffixed", "Eden Optimized Debug Release") + } + } + } + android { flavorDimensions.add("version") productFlavors { create("mainline") { dimension = "version" - // No need to set applicationId here + resValue("string", "app_name_suffixed", "Eden") } create("genshinSpoof") { dimension = "version" - resValue("string", "app_name_suffixed", "Eden Optimised") + resValue("string", "app_name_suffixed", "Eden Optimized") applicationId = "com.miHoYo.Yuanshen" } + + create("legacy") { + dimension = "version" + resValue("string", "app_name_suffixed", "Eden Legacy") + applicationId = "dev.legacy.eden_emulator" + + externalNativeBuild { + cmake { + arguments.add("-DYUZU_LEGACY=ON") + } + } + + sourceSets { + getByName("legacy") { + res.srcDirs("src/main/legacy") + } + } + } } } @@ -162,29 +223,6 @@ android { path = file("../../../CMakeLists.txt") } } - - defaultConfig { - externalNativeBuild { - cmake { - arguments( - "-DENABLE_QT=0", // Don't use QT - "-DENABLE_SDL2=0", // Don't use SDL - "-DENABLE_WEB_SERVICE=1", // Enable web service - "-DENABLE_OPENSSL=ON", - "-DANDROID_ARM_NEON=true", // cryptopp requires Neon to work - "-DYUZU_USE_CPM=ON", - "-DCPMUTIL_FORCE_BUNDLED=ON", - "-DYUZU_USE_BUNDLED_FFMPEG=ON", - "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", - "-DBUILD_TESTING=OFF", - "-DYUZU_TESTS=OFF", - "-DDYNARMIC_TESTS=OFF" - ) - - abiFilters("arm64-v8a") - } - } - } } tasks.register("ktlintReset", fun Delete.() { diff --git a/src/android/app/src/main/legacy/drawable/ic_icon_bg.png b/src/android/app/src/main/legacy/drawable/ic_icon_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..3327014f8fac1561a461ab1f5c9f435d2e513b66 GIT binary patch literal 39026 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 literal 0 HcmV?d00001 diff --git a/src/android/app/src/main/legacy/drawable/ic_icon_bg_orig.png b/src/android/app/src/main/legacy/drawable/ic_icon_bg_orig.png new file mode 100644 index 0000000000000000000000000000000000000000..a9fc55a4f547aa7c0056087462b4d7ea2176cef6 GIT binary patch literal 448880 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≪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�Na%z?0f@3Mig^hnqY~RWP|{wglT`mG zK8&&8>CAnCN5sjbO}Yp3MpgDqDkc`6+14{$^{l6Dp6U=6V?`lk{Hb@{g`Fze2Re87 z^dj^V!-eE~(B|(jl3PEt!qRVdhY~;j&#(D^3(Xl9rB&xmS*Hp^Mtu$thwD#@BKb}o zi#v8qc@zNzLn>Eh&AIIw1&7&I&VN|LAdu*3^rlOe%|hYH_(9Ce(Re3>G3)S7DR-RQ zCyi0-pQXzkg+QCr)pGfo^9P!Z)|MrPDWbfk>2E_UvIq!XXU|j+KyMXKe{HD{%oxyy zu)@egh&Y~Ov0G)Ie)1vAle^jMqa(xiCQl3xYyiFLjp)*Lh@yjeV0Tj%rnq(G43)x_pK46>tIDF7g}YALiUTPbNzPHi^A-W-&w$WHT;HF{%`Fm!RCHvxZCUsxYVN!%5n;Kdv&rv`0?e}pC7P8d z^Iy~{^NBZKMmChLbmffE5!t?SKVqG7t?=UMi$fk-`lQ0>da}I5ED0frqYHjz7+M5- zWoUHkc6i*+8U_w3%xoR(NT&4+7!+6oaS_P4B9lV(<|k5=V?yFQUsR`OAoC} z?mG(VraY%k>uaTz^7t&gXV`j)sXBUyhvk;w7 ziy!PtJva%6-phYSt(yRO*GSz=18G{=wY#~yv>kl<6d$*Z^Xk>?#>E~Picltc$*?S;j4dQxT~ zzpP1T&(>q=wz7(gOtfER3A)u-YBetlf&hMtC(~=VLLvJ!7%fraGeZ=&+3hL+s?7bn zP=!$JVe%GdK_}aBM3DHJRt={XH)4BOG=FQt+w^>Qyf`U%7{Smx{Xg5nqB}F zA{g1B-U$_-T#fx0l-LpUG$V)qYuC& z(g@JoN%?I_FKW!Fx2;{Z*eO<;dk7pO-?~8h%3?0Lt(;F~X@&Y~QpPLtV%Yuz6Sc%h zrg)l?P|?I%yC$QBj36KrY`sbU;~Nx9LKa0Tk4f{)zK}(tGfDzg_#IAK8?eA#fWV&w zO)e8FZR}7i{bRwpi44Lz68A#M4@Xqxfe-z1tvouO(XvbIb|sithxO;p%r_&B3LC{l)XuK?o9`b?-Ke5hs$TZ!fN> zFzqf_k6Tc^>$qwG)Ko3aPeWOdKxtVvMic?L{3gxFRJL%0yZN@4uTzSz*?jP8AfI8> z(|*n6zm3q0D}s^mg%;K=e+??Op~kLSy8kSk!w7TgInesGz`B+?Ui0I2jhkOvi0?b1 z0cOm;F-GlX(y`W8q=JVEF(zK$0FZHJcP`4@U#{eTNpdDY+PThmSJkM8M&ef-S4kVl49`qh3nZGqk50Rf37w0VMWkYwmH9)t0@vJX}a<$Bb51MMr& z%Y;n!r&?izhzDaIr4zi0~<@0OZu(mIcs^N5a>PG=eu}TEXZy?R4WEZ%HqQ zF)7E3S2fyPP-3GKT)&k%)T{$}z?`}M&e=Vm9|04&3Xt)G|KjmCIIS;`knKQI#_H?Z z9fdvJ)kSS-tJbo+pE<=^jG-#uoGR>|X-FOMD>jrOY)yhlo8tKzzMp)35Mp_zBN)rf zui7>|j>Ur~IMsqnU4zBv^IMBKSQwUq#Uo!gXWw5MvI5j~6!ohrDB7Ifr`hc+Ik8`c zxTC?ilwKD%6cm~K#le3F^9M9ET3-cJd0)^)cS;~xK3^ztN$V}$q*4qblH0@jUU$fw zEF|m)dC)urb-5`;h>BAlGAdv+Vr&HT8(MD`)@?Xai2NK&@+684rGii|Y+#!|g(}NY zO&z$Jw)^Wn~NSKzUI~A=F;BS`mCguVlMVCAlxn^am| zaa@v#(?r4$iAHRnn7H*^vkS7b;fu9vMNLoaa8UtjJBpQDRpBms^Yj#K!8rCaK~O8c z(6JO+1gy9s#!VN7Kf$gsNc5%m!kx~qUGc91bv79y#v<|ShZ(4JSR4~K#JS?#8=Vg2rYzc zMvQS=FvQOweBqX#Aw8@nSU^MMqoKYXb(#sX{kw4g>oToxk<=GVzozCx78|*wtA7Q! z5Z`gJ4a4Cs%Rhu%=Stkm>epouw!hJJ-fWydLgdLP#fWH)SnO~-az2(Iot^SVL8gGx zcL$T(H}$jkXPc?OC~Zhts49iJM8A#cnrXP3{Pxb_W7&SO=l`tp2)^~W658vs?DUV# zTTU)9w?PWLZEPZVoT12TV`O+GYV4I?MzF66)LN>aed*Uj=T>k{@PQHO z|C;pE1Q?HNwY8-tsDj?m0tW`s#hA!CUqyS6jxd#UDNAlBh%q(H@ff%CApmr(_5y*q zBu=55Iw~onWYYdTc*w28FnztY$^U}#81Dd3(Hmq zDFa(lZ=DQ2mM2@Dyf<;2hf;O_g2h%Oq}$f8S^?b`x^MRwdYl_-t!c3p0(3^YdL834 zSa{_|RQ!-|KbQP^hG&Tg2s-(~W@&H2HIVAmCDKEA@%y7+xg z2Q3VX|Hif~H!tvy&{B&@{Ow9qs`O^VO!6R0e3g8a6zQKWPB0yky2vF{LziwOnp+R#TH!Ou)i-wPH26-8Wx|3=%_N<5t;LlEIz`cA7)*QNU zgrS#1riZPOi?74c6g&*T|4rDx<=wsc{bhlbA8#H*?1q_HI?t+LKUGq>ReY&VDAXk~{Je z$z^aN$FD7N-M9+TMosREQU*FfVn-Qm36lLKbc+@L#Ke1oVPb&ptjsMVWjv4C$yWbg z6e5KmyjF<(473+u(}n3b{^{BxPcYn5VLS^1pN_l)YmJvEWQ^+CkfodO~kw6+5ApPusXp2MF8k*Z5Z|CnafzKtGCqoMu7r+@Ktf>e__&33}^R4$EeRP+6Z zU2<L~*reCFuLH z*_TH$W0KfkAX-`knH4ZsqMefF=35&@AXH79J+*!t2Kf(8zkR~_2^ow_D zVhAbGjgk{s_GAlA-3vy$E305wtv$9;O<;0R_xUMco&E4l`G8R=ozG%~X@-0=q_i@@ z-X@NTkX)cC|Nn~yhkVZt9ddm_nFs?&8s$~`Pi@&X&bxvr0pE-@$7-KP)bIc7C{<)7 zu##va4(LWopYK-*5UKbl&(S&`-1JmMGzGs@cwCY*W`}cMSZPaXjr)1U`MqRys_N(t z1Wb5+O&Ypc;HA01Hiqs|$teXD25vnAAtahrqJNf2HXh<3SoP+;4zV2eyxA_647s#W z0JI3VRQwl#Sz@F_wo9Ftr|G+O3j)*Md-d-8{rQ;$jLH6N1>EF9Z2uosUmX@@_q-3w z0!uI5Ez;fHAxO8>A|fCu-QBH#bW5j%f&wleA<`nvE=YHG{Z@S6@9+Km$+cY9^E~IA znYrhld*;Y5d#!oDWJo#VY@EwM-i8;7TC1D*3!MHCD6KF>S;A|p5mc^`HLxbcUleIf zj*L0#{Z?5=K*ZE4{(n5|A4An;fP7x857Q(_SP_KKW!Slc0{gv-a4v}{)Qe$7?l`w~ zDZaAL3U1h-U--H{hNs5#v(8}yR#GY}6ON7K%Q6?W=M3U_XFAw%x@W_tq$%_9d=~|u z&fssX3dK2c_i7g19oF!#zsFgRIPATp_ETzk6>BN_@mHZbF%HIGkjxc^w2R3tUjs6W zg+}DLX}uF{n%zD9#8M#wccm>d$NEeJD3c8ySWiWla^qAt0p(UNd&e z38#&HQTe2>mc)P*(j6ifMXPAM@R#8JbL<1DkT+tUeoDhZoqQ!~QohPk(hw6e-1;8C zQN<#eS4OO1e9GGR=fZIY?H$REjRW(`kK9*9Y@S?tdN4}Lv8je6{S+-v`+ZcA1a_6k2!2o6@IuOy}LWFT);tvKHEQxU6fU~yC!DU?fm+2f*xC-xgQLd0nhM;$; zO~1u`q;bQast1SyYF2GRrV7n#2eJKbT(Z#Rku8H^#kvg`>Tk#LM%pcF;A_s)HTL{;(Kx-`Pez|u`FOzOEOT1`;Z*$3SeP(VK zH2&xnG{p4FXOXuxkVDB@%-J#6Fk*P-g<*ez;0EPWRih{w%Q+|F$IgS`P;{$=gGjLn z4LmRLvwHks?#hQW`A@cYj06L$*blAqeb1S(- zrVm*u(eT24nblj|9*?PBim#-fBE)K)x_k}W^jno7*ZWrAFO@I;t%N){?VUs~YHm?++ka zke2dlY0|_K^_uB%aR zsuim35GH8!eBZ>`n&nmY0ObL5YE8Z-dfzLS@>wy00ri&{H!sx0Z7XGTxhdc(O!Fj| z4RjMI*dO0JzE@|u#|7+)L}61sCcTKT3>uai3C21)?(6;)tpWaFqKRZZuk6JS8?9bi z#{iN{Q)Z#B)G4=z33)*+2Z&+O@D0!l#GRn`H;97hp94t&ob7>VyBFJAxqj+_*_9L1 zTY(_>(rsFpstH&|vA*nWZ-(Lry3*>uaayKLC(iPUq;df}2#~F8>FDSvW!5CeT$_`k zBkI@v^hKj?gRXqs+i?Id1>6(mA9@#)o*ibkq(S3+MKtheQ3i*+5OEhMOc9dFLXvp(|f6Z+E`*CNSfu{m>Yr8H6Ff#{aTs&-u>PnWN^@X3iZx{gE&xzWPT+l&7Jeit77l$3l2OAp@Mk}MQ?oVm-mOyMKVKyW z!9-5Emx;+?L&2QmzD&?7V?!VcTh$U~CnX1+_{iaNxq@m_pL^%bwhwkx)PTowa{G#& zuiAOoLUveuG@{w>R>Vc1u>(Iv14R&J5=6u?MMmaA`oizafxZuGm5U0DQhFAb=p&A{ z-7eHNFk>0gK<-z0f=8K;c{ro2G$kD?bFI<6MYON{VN^_b5#8Q5Dp}_swdvd;2C}G} zuk870vl9u=BT2N&?U4S+_&51RRdzxJrbD@dlKw%~q{u}5Lzw%!Owd=rhIGBr6OL#J zGH;N#h>l?@0Uz0rOy0LP;ZqaUw2D?^=Sg4=}SFL_}* z?Qy8T-Ey&)Q#apB>_xmKv zA0)zIk}*6<5~1h2zhm`y$dUP6@C@&7|0qffr4b5l*a%|ZFu;pfOLA{?G>|e?{=*(X zg+MY^*u{%fJ%$r}UB+d~-Etz%;WNWpXv&Tyd7-68o+HN}1!x2neezVJk1#^;fncR9 znvvI+cA7r?kZIQ-K1G>fs_DYq$ zR2R^B`aNF}iDtM-rKhNLBz{!&SJXm#Xdl&;tdfmw2%4HK%dg(vO&i*z!M&0)XEVLyG(pHJ7D5VpNR79SQO9bC+`lI*Wc!#z5nzNn|8Z)q{n zvT(kZ9Lkyg>U`arTilyCtQIY{j`HG{uSnMdk6kM9FTDCP%Ou1_x2hxnd+;I|YM+H% za|~~+WcId~&$a^N0p^-h2vM1g4^G~z-)8yc_KhaVc=D5A2D8H0)se5l|dl1CZEzHB7 zCTzTJt=`^fq_g|2RqY(xIcc0wQh>+o@X7q(6Z~PqGq8n3{U;+>UAY5cdwC@Sx#cCTO zRd!R39tv{*VBlrY`~Io6^AA;)z_xe@8D5tz7_A38N!$>}nom4(W^Io%g5AkW^Jj8* zCs~5tonUQ?g+hnmBwk5A4Kj=P(#dbmA*{W-DFJfW5BKuJ{Wo9qYYVKP7@w(MV7PC* zCf3`6(J`e7Y#VwM^I{!{DyYeHd_2HBYH-g&)}hV#zc(=omC+KrCLYBsJbL>vi30`o znGqHBO!X`Qz)%Sq)nmqz8!ZkKs11CC$@<$B9+>FE8V+NS|12Lw{=G{A$rZ>aK3c?9 z7ljlN-_EI9JB6jq@qcLsD8yM|5v-qpzE^Ehf&{46cT1dPeO#7&gc%Y6%0S-J@p;s{ z9i!N+Rhy306`iD1ZVGaH#oONkerb|7ToKKh{}0(SdaRl_Y~%OToSqkKKpD>0BqVXf zM|!C2ML?5gn?f@unItm#?ayn2Zxi=J zOeFt9d&n>VTKTe6G~TkqKioVvd9td%co<**WznZP@f)n zTzOJ2c=>h};6~S~_w>M>_7H~>04rS2{?EFP9- zu~^~*FgIN`%dYddRYG$NCO=kT>Hdd zr#MbO0U1y@LCy%Y=pUKA7LRP5t7os=QUUUyk2a#py^VKqQ64Y<`1id2!+w?G2frou ztE)XQdP!7W=_Zia7+q`;(3Do|>`v!K_6EB$9xLoVIaFcCN-mmHiag|MQRn<-hS+>Hx zC5F9RGwACHY(v*$dz*$JhXkZPwg`5fD=xZc82e*isNCvz>6Gm*y$~G^-OtS#my*oOpFeyP$%(G`JY`&Tb&2KS{`N%zP5OxM=IkGkJ?htm#MgxeXNiHfv zB9YA~oxgG>i89hQ+XLAWqZk+(?bB%Q@@k4%VzNJ@#+8 z;truz__AnK8QB}{;1tzt*|}jV^@>R1Lw4B`--4{t0E%Qt9Wk6gA$_k_F*rx6CpEcl zBIzr~-9S-M2{jNCbalMFKKE>?q`R2fI!mOU>{?kUh^L-?^y zBRm4^d3{kcdg^?z9OjMpW^lxjKFfp;EM3O07cH;jA1uxM4EN$R%3vOJ`>H+>^MA=2 zf^$I>n+933;S^oIiLWX@iThw=?#flnUEJn2rY(FA@7zSTV2^q^RrB&iKG%vpl>kNDFZKFIn@EhroY7v+!E(6(Fjiq-W`yGDndKDIZJu(2> zhiJ<#F9Od(Nr@pOlk63|dXM)${42lF7Vev?3W0s=Jrnfh$w*O}jO)o!l^(Ynvh2t? zLV*apl(tf*w00hVzcRnv`(`s7)%CMy%zseHpLF}dX0sWP?pW7@mjZXw8e0{whl06Z z5aj^#fUYcT1#ICcds9tg&4+Jot3sySLYalK9y{W#*9%e(EKMh zET_7-@ig(!`OIKe+8@1JmVFjr<(=z&68!p#vVf!ZHWnrL-!n{Jc8?pxt+U5E_l=)WVU( z?ad#`DV`ajCbg-t4)=*wy3@P30!0iV9S|djod{y=IM`Zxcp{VzZ9qNJo9otGs(h|X zm09l)%NWLEQ`RnbFr@2)B@>G3F||jLH*ygtlm{!~{PkK4=&%5FiJqB|MLI$VZ=VVI zu>G@*4@lEOKG@!`ddGep+~Zl;jqF39`@HfH)7iR?vdz}7mNAa$rVho zBvB4mBdJ_DL9?vAQj!vuaATw^<6CVf0O*NH)BaE?)xuvI0~cvoS(8VzG5rV2;NT-= zqvhGx==7!bUJQwrdpqG`SeQY*Te|{V?eP61zUulh+8&4rR1a_FAP|l}u)yKWYUo() zba_AbJg@RyFda1x)PJ56XPJEN{)X4rr9{cpg%eETloNK3A7KRYaw&6l3d^4D@!Re0l z72YvdhAD=Pr`*lrtHT8AZ=oW4J z3jhw)g^)AV5kZs$Hw93TBZ~v2qRxMEsTy{f?6TzzpKQqAEQFxYClkebA(1g*grI<- zIkeT<^g`w26t7my)ajy*NxqW1oNvU2fuB#!fT%OK5b?5<3v#+-(~*Gm4wrtiead_J;?#bkSd zRX5?G{*5x87=Rbzuf9ALMak09m&LHJk_Vivjk4cDCSNtO3}1~DZn+rY4NvVL1bCMn ztgo^zF7x~NI5~$u#}@Wb(F=LP66zo9&$Qb7a$drCK>3A?yV|1Vus!7fS#aY2mkvQt z0ZrrKY4fAzLKn9Ct)mvQUgp}gZX0-Q zAKV%uLyZ%=IjwH+P0uem{9*D5wYNVMW-@BVNF@k_Pgl9SeAO|^H%P+^XewNtOHab} z&;;$oBCU}+6)A=t`8G4Wy}pv*web02K~Q%da6*9)`xP6} zHb(7ht#q?s?xOqB-AaHZ-AWHbl!!`1%o6HGJniS9dK$yhk$`BrC%(*XJZv$Np#|X_bSqWuLV3S36|Cytq{_ zB`logL5D)WEp$ARlXu-uw|U`RdvDZH0NLEcLGo;z?F)qAMcKM{Xe;~-hODj8#gD&s z1=1B5H3Ut6|H5?iKN#K@Bvbh8-VJx`je*kF<<n!{@pc;&h)jn`z?pX@~WN4PCmY zK2gmv$!x|;I?<{dJj##sci3%_=1Mcu5ph1(();-cAX_`^bsTeWKyH3MkBNo0WFG!Z z=gjZz2dt#^%Ay1})kh(obIjgOR<(#?hwJo4=|eKNjSr1NjJIcv8>&-YUc}A%M4k!a zA&`$t>538*{ZdAE9XhIn;)fgZI{0~95VNri^-cM&9IyyGpy`F+Z@O>6mLQ^B`d6LF zyz$ogS3Uj)!g#bQ#nt|)VT~hJy416m<~LLn=szIgl2J#b$87O$4-&}gpU%c|4K7U+ z*7&qsk#{KO)E?r@4(s@^y9PDW@Ej9Wb~5BGKkwr`tfH%e{|Cc}fRO8zm1BO#!w=ee zhXira%3p?vjahOCf7s(VxA3A!;DMkqK0&DAgSUErC6%#Lte2anZ`l1V+?sp|l7ZQ! z(LWOW#_C;%w)*AWhjTSiHY%i7&TSR}u&<>1&vo@{zd7HY1Z=&L^o+SV{TgJB)}(WJ zgGh*dE8PEr7&1j9TKt<|7t!%+;|c9xx;4E=izrg>U3$f?Df~oDEFw7;MTX^!cH8Uq z+7Yi^tsFd{$RgIM7wqOMhtYbljkIb+7*2-$L9eBhaL+-q9sVqADAV!&8G`p0sTgYA z113?xAJLMrPw0!FJEQo=F%%<@mM=qq7hI76+d9B-^pvu-|2Z||_={Pzsy3fROH<>p zZw#w@5~j+#J;hl$bs;Ku!^e?+$AEdwk22mCWbnr#5)B}9Z-RbwgS(W){g9rw7a5~YVYqh$!ld^XBVxV=JoG5|1AGsVZ$^E^0W(I zgLV-wGm(^uQ@gyV`t!MZ^?=Dh$`ZYvpClRDk*OMt+1PD1@5(kwnh;7cFnDn?^!%E^ z2a~Z^vVL_Y*x}R)6jjs0XVKFs`H26TPILV!G!-!_?tv?R54ssFrt1b9SN7@wj602UcERa4F2=Yqw2M24vv|1K+@|rdsC>)V z=_`1NZl&IT!ui)kq{-n6S`(PhRKJ}9otG@`G@6z3YMQ8PjR#<{on59oFeAA~3>T7gUHcke7`YTjuU&GReOKx>r_Z5O&P2Q;f(JASceH-HAtuXRGQ6{SF^ss~kNJ6x!vntjNne0EZA0_KNClg7 zufn0XgOpTD1f^~5@W5{un?6R$^gXTo3cEV!h7T~0g*9h4U9zjl8hhcu93vP#9UIQHfBd`oigoqD&VL7|(cB4on6c{P`~gx#45 zhoXW^l@+Jw7^SyAjos;BW!`H@C26dlnPXMs`;G1NTeOvk+d|#XWfF1_H6W&gu0H7{ zK7fZ-0B>rdgnfT{>(%O)j*q$-W%VNhX&aj~(=|6yN4wU1D6F|tQW9wo6umzn#51I2 zU+$35Ox!P9eOlUP)XFY`czW$N@-1@Ev>gZw+uX|}Wc}A%h?IQx-5X_<7t45A28Q3Ua?B|DkO~gT)AVGWAZtfzqSx(W6h7Sc}0)<>@er;6)i@`>`g&c z_;{bC#HmkV6rIOko9M);e1 zCF(MCEBuRSeDYr=x{JJdAY^RjL8}~W$mrIhV@$sqs|4=k$Nng(9+Ro>bZ5J-*({}j z<+hw^hF^G`+`4qp%_;YdjZ^Oet`{##29a+hzhN6IvGKh3thKG&ky6=ggHP)X{d2+{ zL69Z!CKV-bMviIeLYK$AfwE4P+5QB!J>>V~rG6WiTAMD|$Gj75;|SkBjUF;7*XA>B zl6jp}V;g%s1kY!umr3qB#(bnrRKy$(KQr&$iy57h4Q^^!tNu;2C(wy9OGz^ZdNLwR zt`rx^*J7Yji%QP>xa(ZJ!c+tH9y9I9f83881Q&VQ!GH-zIfbaw?Q|7pb8SwqP;zGK zE)&qtokG za~19So6LG{Ejk-tr((QRX4$h8@AvCZtF``;h=}j^X9T>UBa2-Lpv7jx1lPVuSj}Q> zw8XcGBdfJ0AQ8|bqEpZTt+%cr%M7=d(%R1&7$YLFr+hFr8q86{G9urG>=~zJB6$(! zF>dvWs6|0ys2lnm`9NJ01|ru(3nZ!OvYOH2vFg=$sUn~~MDl6pOIScCbuUKZ9T`Rw z!^FD)?j0{I3ND=}(w!MM3^G};CH%PLHW-59y*3%)d3YW+@|<;ojrl)FRSy>ss z7;rW@O(EV2 zFIJ1BpK%Y>rH)1(>BQ4$mGIAXy zO%*u^cn1$dI(Miu#X!3|Tt7cG9uwcuSLoqyb6-BNVc)vBEV{@`Wy;6zz=Cay8X3@v z{qif!Fbq`IWa7yJ5%+>NC41*WUf zS^ZBj5i#vmDY&+`6U9}r?j97}$?h4o#=43Stx}?fy?HjUj!O3I%>}tJ1(`S-Vc2T|j)Ykop+mC| zNA^L7kY$u9NK2gU*Jel?wN3Y(BP{G1i>OfcQgeRjp0cY!59^RDqw}~v-}6i90gT%; z?BtM^!`VI()=2TA>K~~2w{{tF3YwmkB(w4*|M9fhbk4EqW#d^Vx1R8RdrpI=0!_6Q z-mLL1F*Sxe1C>b86u;-0C1}ya zGH&odyY-c!l=>$OzwPxfdTrQ7h|I00l?uaJ0zc10Gdv|FUirrKx4&|(8;4B!ZW@xc zv8(f&PXT6y5HCDKA|n+a-1lY>YQ?HqMEwTQcm#1YPc>hZ2}?m|uC#V+EQiNUhjecQ z1PLT@1QU~WwZw$f79U|pMeVB{G(`M59E)OY4`@4Enq1Py>qY~05+qKNG0^Xq8h2&c z5h%J$k1(G@kFN(DRgm-fv8UPYqqa+zXyEF)En@U~#pKnNoO}iM@MI(X|1e0%^rOnq zsKwJmufm*6Nn80X!+ev2CjwWub*`uIukQPb6gb)1Rq)NSk?x^0Mt+oBA-Xu%q_zNS zl>6@8ATT~AO|gitgw12o0WM$zxIkNwK}U86SAJz;Bh?o5hQBS2G9Lc+<)BI1wJ~)x zA0i~&Ut2so5g*^jQKaYy`x%ftE($Oy``4(&K+r4#nqh(Ut@%UJ`je}$P|ppT@laB- z_HneM>L*3XVmtO>ZlLpZT<)~k?zCbTBeUHcVwHTor)Kf+CO~!4%8)9QptYA` znd~N`x+_RbTi~IFOX~))91UO$oYmTD+!)eRYxzMvDkIN!WYoZKl08 z)*`36PWo8v?+BMa{6siZ8w3f!#Z&4}BzPCMlD@ca(ivmvUYMgUnFc?26zJPLZHkI* zhBKn*?ZWreE7a7kc0Bz0{qbEs9PaxRCS;Uk(fIR6>P~_1(jw7IU?=0}5cSci-?|KfVN^Q@~Hn1s5 z6F@j8CM2~aZg?5ZDzC45kS>e9q2b0x`%2yJ-*fSh@~Po3&Jsno#SjNu$fdGYpSvh* zUw@-OYwRRU*_N%gZ!M)BJX00Gd(JXgwK#F``O6&ng~m}{FZT(KRN1rALPw|rTmBwK zNG|wbKQn0Nd(GJNqc_go8Nxp7XDYCb1&dkzIvG6Q@M(Ix$}T#7CxEngs=n$vya%v>qXuCCU*(7JsFowLA4JrW3E<->H2$DA+wyD-+<3CAKFz2NYxi! zc_6F|8i5bVC@FG@_DpUZnY2y+peez?Oy|z?k#Y0`9^hgPJ+c|85tPdxp+cI`XUDp5 zUN4Noe)BF+-D*2)bjqJD%tis+by_kmA7 zpN4@()yT&BW+n4}Uh+Dmp~~N~Ixor7t>z$i5JgV6t7PZ`N2C2D!X8O4Pj4hXkR{`w zMcwqq`F3|3;m3I}jS~u!rA=WaLaB}6s1K)jw!c|d83zPztY>3qq5d>tAZln!rJqdI+_6?dfO;(r8Al)Ixqv;LGh1kJbENCp+SBA(A&EIDHY7H9N*O z-_esE&pCW@O)UfS)Su~xPbDZ>%JKQqd*7^`@Vp6%Gg(0=e@-3`Lla*I>=^)Ae;OVO_NU42xRAAXFd8D%`h$Z^{;dqYYy(bMjJTI`~J zTW6SJNRk^eOk;^qoytL!fzX{%cJe_@u+#-uON~-dQj=Q+p#(t;UU8ly8{sI~sQMwR zqSx6?&nGpvV@wlIl|T*N+g|kavc>HsX?n5lNhY3f&keOh-_S4lv#IQF@_6xX4?nyF0(&Oepw9 z_ft6333SljchO^z9?b*Qnu{6w743Q8qHf%Jgd29~5V!m-vb3=|pn!u);L$Mk5;e!2 zd?r^A0=@{WeP(|!F&cnT{clEeZb9lF;NY$Z1M}%Q@AsHoD@zenBxtO0D7CbMKQ8&> zV&1^8A75)dg@`%980~q|2@pQ-;uVku)H0@0D%-!?EQjx#A!W88pa&(ccbIyO4cKkm zslj^+N%X;xYzG3!A2&F+EYCdb%S?7$BNt^eN>agKslWz0P)E;@FrEn zynWEc2QM#mluV3ey|Ss92?4!MGA`*BrpzGp+xfI(+{uwy;yv=BN8aX!I(a93bvb|5 zKjfGmoSNZmpi+jD?;{0@VtG~5Mz&?EuuUcL?oeClZdmGvd|I9aj(kO-g=uAbEm-$r(Mrb)M;ywdn54TF~8)A4Iv z9W*k7-n3)9tM6^M#CzkUlB&LCz=T*Re^dbKTC~Zk>5QQX*EY>LQmB3qu6$!PYg(2J z(jZfpR5xRB+x@z#_bLOhDbWK&bl`e9@|A!4m5$wi_W2L*1p=Im!Wg=K(N9Dw6+H60 zXp8juCClqWa1v?uEAEc#UOVZ@EdI%JolL~qpqp2kJyHt7*J^cj1lYU^j8=LSu2wH-#H96_BNoUi*HWrn|2N0f=TMyjA; z^}g<{^MR@OXYRkYWTS*cOV5IImDR=n)1P=2Oz^%E#yPY`vT3+!kw45^w`(&UL_F#1 z8n|6tYEOS44+1{^ZQyG~#Ydau5o_b$4tX-d=%8Pq^(~)T_kx5@!XQXf6bs)-x;Lek)Gy2oHV3J>A(5=q85-0cC|K7d*-PDB6U<<=WQL-`TazBiOLo#CMCFX zj&l7J4)X~uaewrV5l>F)o1ey&q$?p75oufuL_1sw)xS zL#-cS>(B?Hr^w{U2i0q#&jm*S^SdLipNw0!fzNJVtJlAbyZ*+*jb|t@bbcbbmp_c~ zV;Qn^gZOuS>m@QPYvhcPdYF?N{DKK^rS}oDqAZ2FoU?uGKXaKt)1M&q92uJaL}6pH zIq2~M?O0v>@%sUDqK@2cq>UJW{%7b_PHNX5ovNh&b?pxhZWH7!ivL2D7e&yV=IF7Q zVx)(l{Cs5drFX@p`1`O>&aaWqEZkQHIscURmg#l@!2gRL7)XFTi2OoH)i70x$aEJR$=Mkjgvoq(J+n&&K?9&*525m?834@`F&chzr|DcoKe_d^g$gMcArvdlvDX6?*Fb1V4mQ zr8;AmyHH%~olu>mwlEGJwYM-^f(z`;>C;iPEC|>XvMc_^`Pd|HZt?RM4l^7v9f_ud zM7lc0yG8xON2AWva*HxRTanPiA6kbn74Zt6Y^;pSwN*}$dnnmioAau=z79;bqY95T zH-)B&@2~6<>dXi+H=E99Fwa@0f_WQ#3tU|O`a@n;dK4aLQNueUL`HChXkDXI3O;@$ zSI`q9c25pG*yV|+4q(1as5Vot+DJpt6lmjE*kG}_^Atd}^W|O;nTg;(R`?KD>Xd@F zUwD%<*G9d;Gug1@Y(MoSH0hdWQ(o{KkgC}YyG*469aXUXP)mIjW=hs0=CG{iV>R}X zTMQr2#~@?1>bHa=(f|{mcHM8B@)HC6fOUoiH2(Zj{1CQ~>64?8Nb6x0EFZ!fR_P#d zH?qb3kxP**wj&kCgFd2pn0rC;b%MGyO#)V@G#n?`*=Kngh{JgC1lVP&MO0#6e^0W8 zbAA0pCb0hJiSNF#MOYzj>_%j0qp0Z>Y|K;A(5dJ4OdQRcZ;Sk98hzxYg5YId|6_J7 zUG4w6^AJ5CBqt6T^ueYU~jviaA zEiCL7)*`;wC|1V!bHmLD|GA)qY5rztT8U%jybnIep2!!YObeq97X&?Ud=t$={I3?k z8q_f5p?bI@flWvTwE39FR|xU6{;viG8S(uv{KaP(_Ud&mzhUM3GoM*Yc^r#(+@0$_ zH+VQJF@YR$%EAd;8OX?K{fV?%^h>Jnx3VQ319dT?mZDuu>AoPQqyX8{R+YglPQvSX z5%ya_o03ixhSIckGPkt94KHyS^e*6EACV`e4sRwIi9RHk>+(o(ijD4Kv>tFp{P3Tj zvOn=`n|RL1d3OH3ji<|8t%S3;DO*W?!9v#{K|I8+qs&u2Et4hhHY+j1p8u zau@K%F%Dl(1tj=4ZTM25=TavasA4)7zO9fsu9c8t*NOFo`jf>GPX11#(|>f0G9ap0 znJ<&!QM?Hkgk27wT+^SMw8qtpu=l&})%r+{TgQS76K)QEaa74m=7rGLTV*`=4eB`S z$n(p9Rb6i~^2mCW3Eoq^`1}h)@~X)NBiDnrjg? zl(0EBN+0+6ZMpUCUx+LpjBrs~U4Tztd3YiQ#tI|jTXF*nxoqp{m~CDpgeU*@U}e+} zQ}~K7J9qp7K0H4gZ3Y=N1cUXGJjIFW^OY!&0U6vO9lLbo#wbJm|GUA$pryA0q6{)1Me*N$I>}9$2z?PUqH!v&DYTpLjBEnV%vQ0`;{X1gKllNzX9PO z07N$k?#gvfYqS_0DRN<|S#L7E2raAN0)>pw2ZOaP2zBpUZ3^B!?D_u$5qv-?Qrz1$ z%|hF&7ews+6;7WVN+^j&aOB;}{GN=26;jDT$N~Q6dj}L9MN25Qd8G*D^pD;M)qfmb z5<~E!k~8e9k$d-CD>=4Gfbn~>JJfgYK})}Jo>>I&#!Yh{?*)2j*&rV35E{&@T_4$Z zXJOe9t}j_iLj6B)^5>5b3mGK7cW4sYmE)eutyua>AEi0kqkevr51o&@X6rt_K*1YY z(StnBMuW|o(+F!~rVdAsQI|)Cp<>RQ`lAle1BK)Z76W&alSHN@4)>VC7w~G1sTC%W z`>l4VVet*&u^d}SE8iI1e|WGWD_j37ydGshs#4{__*&1SNUPjNh;LAFcfFojLPC{` zzyWl?NPHxIVBE=(r&rG|$=bW6Hr2oV$A5nNH`VZ`1}w(xoxe~V+jAwQK!cki)8M$) zrZVmbFT}HC>r_rZ(nRD=ceFyj!N~?p_NQ?@~uFmv!O`_u_xPi zYLQUOk=*R!(^Xl4-N~n9!c95sRrLiiB&%druKM#hf%+W44h&>zW|F-0-vWRhw`c-n zcC%q-lT)(OE*+7qx{sC5{&wE|`#}$1PC_?&q%fUCJTR9kX~sI|=PQMYIa#yf_jq4c zdSf&G^R3hft6A|4)(**52*K7Oi#L>DDE-s8;7G4uTq#&%eXzH+@2BWRO8A{~q&)-9 zz}Ys4sE!`pCjWYfQvUrQMsQ*;EuNuOpvVQa!|FmtpVPraVEVes=FRr9$t|K#x#)+G zbM#3`!RLM~`$Z;+wg;hS)#l?)<|!i7^NXnGNP^i+h0;dx{Qme|_=@O}8LV-$5z6is z4Dd+!haLk5yPo6?^z8d_o1eetuZC6Z%c1o-7Z@bPx&Aaho+(q`x}4*zd;P5 zu<1Y_S>jmbCmL$br?t%(&#K^Leq8)MJ&AF8UM;a$m=#6F`oV}yv5>=q&I|(k0-b6j z#tB}~s8qSC`If-DtQYvnd-f zPV{K8St~=xch$>bRp6J!0wDmNi1dO(O9GwC)<7F`nJ8sHB>l;JpeVZ1f%SoDHF@U< z(RWrsI&Px%W>O4ogLgVkaT0ll#}Z6yPmFL&{&IFAfpjhF} ziH`4!HUr2s=(eCg1#y*FD^@4hj~kxzNBcRFA25v{oFY}A{qZEwPxKIaHS(8wSf#tP z+&ri$!El3&`T+j2$~OUL*Qf4R@po1sC~;y5&AO6&_>6xRU@f`Q)d^xzpdV0?UmGY; z8-6M#QRVSqx_|9>5d_RCK*FFI%9S)Fyi`fGyS&bAqe=>vb42{ps4@~8Wn;!J{Cd!1 zySaZuH)g3)R9Q0T%Yqca%P)$R9A?G~8?R?F?dPxwnQKhdhKUGSHYf2xT4z}uU&Wrt zO$@E4DA`G=uHuJB3duMd18opPGbtTTs~@^H>Hc(J8eQZ%U0yM%WIq=)3Uwui;RS>$ zJj)7*VG!Cnp3@CSionK@`yO9Z_<&@-bsyO zi)3n9-}nGU&fFxP)-PVaJ?$Nl_DBA+Y)s&KLDh`9La-3`H{9DrjAGFRqP|>-3es|P znrH~W{B^uCY95h9#-V-1=|js8tr8tewt6k_Qrr7e87NFHYM{h5zZ{(;2Gb3*d-crP z%<5Yw6ixeHu6#>#@CoN`NH0f^8~YUIOQdHeNs@LY`w7AAbMfH>T`$X;$a`IOZ$2-A zFCC2hh@$wN;9%>AWUA^I{wEqY|@4cP5|&K!}!%2B9f7gE8dYcH7W_y6`ev)g`1+saRAu4#nr#+f&xgkcbE7&=M1-j zvl@pk$%#Tbkv9@gEZ!W^#SJhWdN{J4%1Cgq3hOQiyU}dROA`o433ibiL+;_H8F-z4 zUVfOXK|i6?p9+|C8#bBxs4lw*Pzvwbci!@tlm7!R4%9*62f8~1WFJb8uAf-pUY7<| za+4|`Sw3SXqDGM{8aHP2LLz5+z*|aSkm@qp)273*5X7ir`4av#4o|oDd78|9s?NHJ zsR?e@iXr^p#kCf1>_jFyz%5jOGuT>N+2ehz<7so6R!4W~fuPSvwY)j3gwM+zzn-dX z3rZM3l1>aBuM!{Ul}@zI??2g&rQ65MgZo*wDWB`FpVJ-qqTilTe3x7n$2xS_q`;cW zHTCvUDmGMIUnQ%2|F9<#AeYy(Q)1_-qw9rd+bm1Ur;(%bPzgu+I}f^oZS3QT7J_AM zgH!lL^e<-mgLY5`AWKN$+7HK{J9%pcA!X!x8TxHP)h#@&!h`K^OI|j9fvc#(J02$7 zE42lM%Fy2mND)%r5uy?~;H@L9Pkv(fD-4PthX@&MlG<`r!!oB2a$!LVS>kX{*`ehn z)0uGaR}=cC`n)3d)!jA8Ji@l-8sbQ?s4^DMvR@Lf>Nn0+K}G^ZhGWZ@Du}_bQUs38 z4`tM89AszN3$C0ty5crUrEC4CKh%xhlGaD>H>1d+brl@konH)JN~P}?N*A^qcE0kH z*+5*#is<7<0UYLh@r}h9qsYVSEr)o3@1TA}0}`w!p5DQgM>xnFk8~mu42+h4CXYTC zGL&*BnOSxsx?U@K3X4-Iu)~p2%?NgOC(B%;OfyNbAVe96M?xmpc;B29`C~t}uG_mM z$(sgIUuQ?S6km{c(zgL(F23;1)lJjqRdkPJcri75CDTTZk!H)~ENTxL2;J|6=OJ2jv5Bt)6yFa52 zrBzDlOOEg4H?CYkUm?vzW!6%ppe+4iB3d=$hiR_;K+Vi^s;Q^Qy36xJf2#)7I}aKw+_ta)c%uI zfkJ2%=?06{ain%O+uymZO%y|l!DM`k<7uly$0_YTZGi|D*BLQ>H6R$0b)BJP!l0kV zK5(D7RrsgmPKO?Xs16Tf_oVnWXb_kE#@H9RbNXbKHheOFdZ$mMwhz;K}_Mwcast=Az-WaQZ(@3R%c5wW!X2SHdF_=EC^@xO&U5 zD8nsWco+s4dO*5Eq@<)%Iwe%P5fP9s=@?R4kZzEYM!GwsyBp~ky1{S2z0bGL`N?$+ zGw=I6tJl5mB?1}ybG(wK4Yr$NRbLm<5bO~rHAdSzTx#_*b;h)qC%q|PuhMX@%z{%* z!p9Yz^ltAVp)2sgQqNasZkgE?EI2-+egUTnKjSlr=-6;@?sF%W~b3>?KT3k~^I~9CAd@_+rk)oXn#|;q{cUqFTXxi&+4{~mj%{`=B zV}8WbToZcLG-Bl4#@g7cmnmf0<7l&NP3e?hHoSN4F|@>0qMc#8^6=ZC#bKXC#ZyS& z!Oi2hwC{F>-i(->4(js$zNA9K+r$}Y8x<1PBDlu+M2gIsekQk~jy$uq#DDqnMbww_J!5f~AN|ccQKgiw3 zP=*0$gdkejGl6tvW>#d)R6I^$j5V$_^naD_NB!wUh=O7 zl@B(DagL{y%>?RWyaB*zy^KrqGFmnvsajJ~5lKgV5!i`|rbC1PMSMl)e{U_z)|ejZ z4t7Z1-r$SH&E>XFw~ZbKmu8VO=P{F9DS? zaPg=1*r7RhRN!~}rwbYi2gIf#KKG@^4!ibBkA{Bn=4NC_%?!&B+f9a0Y5KooKPFf9 z_mnbSZp5@){sx=tztIS)zF`5C1c`o>Q${y@sAwj|^F8g~z2xLHvez;bgr08~AXBv> zNh0GJ9Ynnq*LtdQP)brUe5Vz0`bP9#;C)XR7*h9r-LN<@_~;#${GamZM$A%bn{U!4 z6~&m{eMN6B?+CNx)vyX8r^U*~ny?L!I=muhXkRH|P^eMYD|pB}1}poafTobTaQ&=z z!GYz<(_|}(mK4KCS*MPhVZ?7N(TP7+@H^!8>emQ2$2w1SUm{)6k$>AU^4l7*J9Sxd zT~ek|O!PuVh%jiDAnI7+V+#+)cxCSYMy%|BoE96N@^Zpc26#%eQizk$I?CCw*cHw4 zwSIqF!}xe-Xte_yR|t;dj8KFC`?pT-xlkiz3JTJa)Mk%B~ zg|bQc^!=enx(lNMmX>o;KwAR0*kT$@g=BT!5J}8D)TMaJ3wD*OyGdKn71^}zrB?ps zIDqqg7z6{Bngoo)QB2J6e;Z$bkQ|-e@O?9*&Ef9$F_ zb)XYY!zm%v|3N%#KD?Dx?~R7w9?1}?80%zMe01q}h@5lk^_DTm@!@A?{t&!acoYjB zV6pC2lSt${Sd`zz;p2A7pEEM<>@@Dk!L23=X^-6t^$))>~cvLUwA!gGS z=u?&s7H#POl~j0Neq{jcl19al(7|PT8%d$ye6-Zn_nqf&f`9#e8ZKU&S|NHZB_6-R8({REu*75BmY(sjk37Rn%V2C z;^|-(EB0Qo1oM_s%N{e6FqI*xqk*%)HW|qvqUUtGh+9g!J!vz30rkOmfk+bM_8$4P z6Z3;VnW@XLftu*HcS}rxvr29#h>YMWy@r-W4AE@IrLDw5^+yxXdJHBSUod5;``gc7 zToH+~Q%g`jWqG9>*@ivv*Dhv%8J9pnMPM4dx%6J3W4FpxD8(G7XM38Afb z@A*QmFOQF;_g@@sZ|Zv?!Kmg{P$`DH2HkZOj>^c!DVb-{N^qN`yf7%79=%y1Er7IG z*`3=#QDqE}aEFfZp+jJG_sG|aDQh*+GD3mJF>&N*nf*wp3YAaAO|L z*<1&%tIKbtQZ^Pm;ol!aj|_&#{C1=No5X80L}Tl%mkZtm^iGeRTv~`Bn2G)U*-{%t z6na3}v(9&4PcCiYp=645^b%r=x|yQxP8ziL>P#gu|||f zN|}Ec;BlUVIl1#G^55#Z(SaK?d%sJe{n;7oa5hrePgAXoQNgPsIb7X;EG4cy1N(dG zNPP5FR$-riLAxfbtF>TSK@pe9K(@(EB+DT#`JsagY^x0WQv^q1*J#Q)KJCH z;1=ZP#^J+7;ZfV>msPo!bnZ$JW({1tA7lT}GHKKdKkdarh;r^-j zMTw-&TQW4{k%zy_sd>@-YQMX_`k?v(2{=nleruyrJ4dE*<^I}9glIw#h71@KW4xAE zod5^<9!H=G6-`OhR6;Uc{HHA7iWNw8R#r}Ik7C@p;;eJ!P_=Fxj_C-?n5Tg0c?v8q zQk;+NpZv1c^(@hIulrNyHD^LUX$DswEGU48O>zBm(YWDK>;1>0*L9kg0)$o!QH^$; zZh`X(0gaj%e}3Srw%(x_Q+FPEESZvF5}dTfv~6Wz*h zt}uA3FH+mm^5$;`%wE4to3{Yd2UuaX$l2<#?rjm9F@-{0f&uM`)L5@1;!V)getaW2 z8=BjrZj?_M9?~npDyepejNlDy)HzClAX#TjX){3PlM+WWSH$`oLfQpih7s&h(N;u* zp>&Y1eUw*IHD}f*+61C(R}-Psq<(+x*fF6fxY*+`DH4e*g;9Q6ENvShakZqTpY$M`gIj zDId8d@~YhGxIL*#)(oU`S;vPQA5+}5pHo8gQtfpsSQ|wywjKmbpsketU8!3xK>NOJ zvuttdU-@Ghtcpe8sXM>Mdz1N^D?dE0ztRzlpc>oU@%SsCneYpJ8`r+)ZiMZR8ce1Y zE%;nr?J%mH;*ToIm=(KD7~al8_EOlpSUC3;6a7 z^xrrLkuft?*_HBy#_c);NRt4TX3lqY5f%Dhxa1Pa)$bnEDj^lx%XIeXSsCB^UDDjS zcn$yA_&oXc{c517&4WFgN%=U-;Dimv`NUGmA7%ExsyBqg&mFxGzEM0W=7leS$MwoW z&^goH{JMPJTwV6z#1cxuvj*v;P+S=)=RWic9mL{U+)8S38NpG$RQ(4<^`Jn|d@xkB zceZlmOFWqtr(P+H^Sicf;2@y+zSiI=z^_a(LQ5;Vx6aHSd7LsJYMYZ)<@vU>RrBi< zk<@jJ=2J**0y?siEHdmgh*)J1=o9zthwry`PbY%$$Dv6(*e>g=sb4HT54G6U#S3gZ ziMk~V%edfo&USnO+N1`onm84Z@5Eqaa{8w&Nr;9E!?zojDjNHrllHxACj4wxKl~>= zN(RKcX0VAb6+moJ-V$3Jtc!j>i9`dt`%fmB9R}y$Jx1%(IRU`lQHq{dv8ox(Z zAK!%Td@-k7r31gqbsET2c`wyDhloRc8q27YareT?5EB6rais!Y>8t8UKq6qY%lzwB z%IqiHzdYuzP8kv(McNP>e3a~tNgdLA6^X|47SI&Lx?dGu*=?Z|d9q4ywr3IA*Cz5h z%;Zg`=Ma@@JtIgSQs#XAJ9$Z#`T~n~U|1JnOm_4~&FU)F*!qgS8`o?H;$bLl3)tve zv)2e8NI-@A)`;&@6?(LTKlKq|pd-zN7ICaB_~loC%ji~xMXBo&j_-6$J_OV4H2m=Z z&?A0?{L7xm5jdz@L_iXl89Z=q+L4R>yjE#0Go_MZr@2zs@V%1Kvf4cN>WsJZlU?5m?}`^Ux2WJL|rtf$1#@v=zoEPlt2XNU<*l&^aWBRR1?g| z#ch3-_9s%%m%C*CzCd@9?Ru(1__xMGR-|)ppL_hoDX0cRYs%{~nFgkyyz z!40=44saBcXF;{t>l>qEqK#Um8=_iU7FhC=s#aobVeNLKvh0?rho@*u=OdaW53M zxF)g@{)+{8lM(YT#dQU}*~|a9Tz9QRUJM)y7jZn3KRN60TiVKX z;XB>(TWOtp2rx+6Ck~+7K)My?*1m?^&6q#~A!BvTSRlZ-=n*%c6wQULd+HrvBjBEp zZ4o=5+zNRZTP@eL92R!L-vkVO1v*L%NH%q2#@u^hWixPpL3&8pPjce^^SJo9(uXJX zqsulLpNh{bQ|ynoWO#@Id|tyurC-oloxE)lCfA#&4c$eXlOZomnQU8M)fekduF&a6 z*_pw(Y^{=3SlUdgah?;zgd1uvw676Q#SKnhHnrurN@4=*-evNg82)y^4>(GtyIk5# zn`=-2@hvBfm+|&RQ3wy%F$hIwlQvjcelOqpFWwCPye|U)&0{lM#x1G1+kDEU@ddEZ z4IeRREjLU3)H8wiDt_*=r(HY+pW%Y5Scm?9pk%1RenB;DXiZvI*qW^LsWRM zoPJu97N~1|c}>2*f%LvXL&n-po*v|d1HGAGKZ&Ftr~B;p1_Ao~;u2LF!+-e7588!^ z|EUt^pvLo813$J6`d0mWrNrH(g5jC?ZfY=8reX8wNOYOH`}Fz_ug`F@y6`An2HxIj z42qZa`$QuyWj-*~GwiKyjhb3v_>SiBogUMDbSfVr*1=gP!J62HvOYNwtE=Zn!SN}wp3LUXNQKUhwo2%hKAb`xe>r5 zg9@BPEmtz$j$-ghw7SROf7aM|M|Vq>Pj6g`blG@w7>f};_J9G@yrhaL&L6nS-hb`y zX9Ew5_`pTwrFWfT%>AeQ3_oME!9SX&6~HVNNI7^#Qi|)l^?*~nkKlICjFM#<4R`SA-y-64ExlZll1CK5lR5ALA&lepAU~Un z!bTDKQ|rXOXK*&#aRXpYA5+8}Hf2ws5FHPAwDKzoV98B-;>>QdF5#C>hPl~$i|-Wo zE8&f_DdeJxk%q`=1+_f;IGK!!kc9QPR0_#fs+7#n%^n)6Sx-)a0vLuvrWpl!b+c{j zShAA1$E1VHva3R&TR!Kkx!mo#9upNRZ}Wl~VaYL=)W4@Kqx{>{9?T(2`DN|&qzJvS zXv`lJoUg0uNdn&}ggXMoL}hChaCzrtt4dCo0){k0f11U>J|!Q>xUX*bB9oEMAR50O zg2`*%U12ieXTN_ti!#H^Fo_WnV~qxt!dYoVBLD3?+B`|TY<|mQd^pYF*_~Z=(3X{| zV)WmW@fW2AF5Hzq&u6gg%lch7H#wL{un-zo*#0C?I^qC-!k2bRTaj9r-x?eP)J9Cm z372)+FBzKp=BcV;aCN~2%-*#BOoj2V<)9G*es zsgQ^GN;+RrhPe@;9Y~V)6%pCOA49QD5AzoZT$x*8RFG-55_`TLZ7+eYG804JTUWc5 zUl5E9!P@No0O`(}z&NCrriPe9Oa{SmqOC<#M1&R*bV5afWi}%<_Q9(v#PHv6;{ zvtLROIdItR<9CT4rP!*WPj*|THawHLy^NP}IBK%gJI8ixM==Xvcpi8}Y!v{Qt?|~o zHApkWG`DH{fj1S$hMqEhF_riIROICH=1eomb~|PLXlvm*J;p5XXtZe(lAkf*A<*T_ zu|7Z0G&%Y9@D20d(?9MEnWvv6@_e64ex%|)X%2HoVlyL~mKfA%v{n_}wKyZ$1Bz-CGUvMRieZ6{ zh7lzI*Jr<+`;*?7RY^)$TFGbbfUUvZs3mWm+4cEbQ8FFyi7=XbUWO#W=4nXm-Ez2| z-kcEJ$({1Xim<45`!j!EN-Bqf0Uqa`ojAsq>s4uV6p>s!UyaoUw{JFz)5Dl4wkaIQ zSKWhE_K_spGPCHGhME%~_%nU+1#J6@&{jBU)DN+mY*zH&y-1=_2eqM4=XkHu*wcTr zs!80$nwFvyA`m0_S$0)BYkz}LKe%gF%R1it&LU0A2um!So)KA&R_7@6k zr%7zTS(=r;iJf-InWF=`1Ye=>&R^O-*YXU8WionTZV(elVdua%sKF2N(S5@=OKBfK zB>xWK=(a=Ode(OE@C5B82s~~0>XiWy=sJ4duktm8bxHP9)w(q!2g+heFtu37n}dCb zg7!pD7d~9VTL@2IRRQst4!XI69ag)lGs?a2Z}B;=nA!ow45x^%fZ{95Ft|4U)O-%S zeAy{2wZBEI9%wUJJOHPM0Q)QhH$rhsT`7*Eohu2}JR>vbszJi@?sN0H}=Yeh_o%Kh2Y?}f=FP%nHslOe?6%>K|e`BLvE_D6W{34SE4 zIFO7NLPX-nM=Yx62c#dRR~zv}pzGPn5R#ynAr*z$oyX|Lu`Le7{_$mZt`r*Q*%eI z-NBAiG19Q4J*zPDY*b1Vz8@kUHtSx2?`db}9onk1iKZ}S+?67rnR$hMy=^(DL*O{rVe|0T>EFQxcp-}pw{)Ka}fV@oMSukHkr?*c!) zYF_}+b1-RCy>h6!#;SYS8ZSUfrX~g(2fH^vgoCx~4?`Lw9@n}~H|%=gc)dBp{(MI_ z-%fu)*W{^uvyThSv!NF;k8d%(p{a1rP@ph-=9RAe;lgz7QvH?3DUtXdg>$t{q!RUO5ZQt7da*4>7v&Y}ae%(*k zqJD(UR$QpGHCQ~oPk8MihI+nAdRh>af%5l3*J(+=MW0)5*f|6+6?Qty-|Tm7fqbcK zCAb|RExwgHgv1R`;}NJ;`~gS_kWFjO0^sZ~7G3#B^b~Vp$0kq~-l1%yy<}#`w{y0e zg{2ZK?fcY=*@#=KBpVSlZVImL_UA5mjj-C%&;O>o@qyJZa(9R{aNp28(~iD=CM=eX zIxS$@RP0AZ!ZAgGb&_6iB+O*ra<0->&gz5nl4W2H7*>yaa74`o(ZL(A^SJFIqZF6D zgx}l@C-APMEz3Gh#n@3VZ0|+p&eW#eoIS31$qwYx^PeNS-H9R)@+3zXbKWuO<#Xgs zP3f-v8Fn|UHr_AY2!&$O#jlK#IyAHHq?c!jU6}eWaJHx9js`{5SCD#LyxSY>o$wcy zyz`Uwblw_Ny1jsvDhGvC^-S%N{<7IhJ-nG@JXY_b_(nCd*Dfy8Y@~5WL;+8bK2ePf zGV5>><b7-XO3#t<8|cDG>=Q(? zOapYK=rcl$(j0unqbdeoK+T#yB-=f2li$u{@+w^^zy_Jzg}(e5q2k$VyN`aTWf``e zRCS4&K7L=@BNnFcgz|+-(6riMw2QDXk7a!8{L=<0QE??qA4|00lz9FeW4hjciMQla z12ZbKMoNlU?O)m3YDXGeRH=c?XhaYHC7~my^<9UVaYs(ORer58$sBy31(hKT7tf5L z*HaC32_KxCVQ7rZOzFWkqwj2A+#=Fc@m(>f1`Vd?R6vIB@_J_T_m@oanfadA9&Zf? zQ$4enshM)5ofma>48F+3*s_5gEs#@A4ZaJHgkrI)(ufC6s;ywD;-Bd`{x{CLdI1~_ zP-Z;78hqhhU_CPaaloUX9eWZ^vlW;@4%|xg$iS{r{m0ec94hLFq($5PZtJ1q+iblm zcB3|PN8D-DG-7W_nAr27Y*KL?$kZbWi1zD$c(_jSoL?_&lv zM*y0DqE~kTP7#&E7$DI+U89^u(DWK-h$gp!W7WMnIT>L9stdY=i9Ql^B^BVdGpZ2m zKUBCogW%}e@-FFG?EIMr|Ls0*6C_%sPw+#(w~`1mp6Wq0Ec@Ki9^3o5C#OE!mZBkCq#=JQM(h7Im0`e#ieZ`;mBPg_5068}YMKeSF&+D`i!l1M?3 zwbJdjVKbmA7??(^h!RPx+mANQ95btx*@K2rn0e!<3~q#9tJ88*kV{K0R&y>pgJ1H2 z;lWFVEymWff8`t*P}y}x?7#q#I^`kff~`t#f)-n463*XR>!F}A*<9&QdJPxAWf=wb za!!Or&0mK6Q}s7@k;e_ZQ$pNNO@Jd|(C%E@T4JYxB~nZ9G;vrcog2d3vjJyKGR#=Q zOIq%Q09XnK?gi5{LmB%Kio39X=b3PYZTHOXzY;we0uxySk7h#2qJ~#c>z)6k1D>vr zT?k*IVOaBrtcXhN!?(f8F&bLMRy0nH<=A@*`@ukDGf<^z(Z)8QR)(pM zCm6a_?3(@6`rh>TE^CC}|I)mj*KzA?QieX3iCKK*0SkGUMr&E)eVETko%tXA2C&^@ z4FcX(2Ot~@ZU=HY8(*X*>Q)}K-!TZLx&p`sAWe?7P&z(C# zKU5Oop}^R=APdIjD(b15>%ps}zz*`2FM}8pM2*LihTrtQJzNsy1v3!v|S;0-6vd^*lv5U!aG3CBB&bNMnP6{6<5k z>F&0ft3_Xq&2aHR=N0QpMBY5$x!i?|JiHTd5TEt|p_a|Jx| z?UC|nm)D^;<}LS%zP@M7eZXtH^7|Xea)_=i1SUsq_$I8(vEFA^r**hc96#W&|dzWuy#gzZr z!{InJbh%y=g+_(X)OSQ>oCyuuYQM~5-b z16~?WYyXnG-BS!|Z0(9n*i)y20k z@?-w9W<^~hqeZYFYr~#uo59v!1sB-cjL!A>`{ilr)JP;ghO_?6;CERi-pM5t3l7bP zv>{51;az;S*g|DfZNb;(3(-bCn6*V9bxIVq$0*tk;zN2^;Yq*djJs$4F$=k{DBOv# z?<2m4o8e$kD=|EJ!4*dtD))tEwi1OWxV=Z@O~mByqu-hbh#~-^YFbBVX68Rq%zLcAA}#&+=m!v} z*?j<&QFkEd>u($1YkK!{N&68Lr7Xc>jZ#*U5ATkM7W75B1Vj=B615}AUe}s+@LdSZ zgz}#Mw$mvr$=E^VRtA%$-M-Pt7XnNFvfSwR zN*N;H@16o7`E%=2i1g%!*l0#*9hzsNw~-r`eRV3mC^EEe<$_AaVK2=LMrvLZbzTw$ z-D7P`H_d__xvJ!P3)lm}pC%8W@(NonF9t3`s*j;w0Z2c)f8o8&`HKsbra#hShhdb? z`ErL@S0f4^|GuVJ+UmYWJ`;Pk;Axt8LF1Xtc;q#8{G+1Wnfpk@LPLz7@7}tRyz~svEp6M~Ag3lO70)pobLU!`0ofN@o8C4XYPVym_;* zrg_rw07R)}o1F=~T6cM0$Wu%3*JZKbY4a33n`^Z+C(~VTYmnUie5kUxU~4MC9BS~l z+Qubp;*nJ&PSUWU(oCJrXx0x#ryJkgU_DN9uz9zE+pZAX2^;uagsVv7bNoZ?mF^tR zCDF+DM17$@3HtEDuO#(M=$YF~(3c3n2kf9Dmt`FLcA8p|^b`r%w6PBVI#PlW^|$<0 zl@{`BAdvuo|F9FZNGxtBorHMuiH!RS4+z8UVy^y9s#eeBS8eC0Y;xXKJOIEk(~hb1 zt*X4}*Tm7-BGJU|%3!##9B$ETB!}q^d!klS&hMSK(Rd8&HPr~$s(X)#z?bHxJq?~c zCKn;13#2Q_AuzD9)|^+Hi_FK)1XG*_E$yhWJn)Dc0^eza*X5t+T=;g#$EvX{c;?ci z$e2qsRNYLIvS-ZmSj1eV5;M+e8{0g3gleQxnc}B@HMiyhHJh&-)lxoc1*0W^yvUdw zwC3?A!Pm5PCT3=9Vcq3c#D*r1F6CJpX2V90WeFADdX2#seSUVPL1)Mc1-^Bm!!)P1 z;BtyYJ{(uXslQ0?CQ8!XmUI8xRnzRpVj>F5SDbb7@)*uj4}sa#Px&1Qviv*a5*au8 zR6b21rk2j99_;s6^4oVn72zjm3Wjb#3@wZHOv>Oa1{R&1to&uiCazl&sHx?d$P_I8 zyTX~A#`ZU%4)kZ&eEu(Qb$<-6te)|(MSI3H;>$nP8WJR_JdBlw&adZdNcFbtFa!08 z0!F?|?X2Pf@8Z(iYi>lB_kObOJ@rtju%QjU)ck zNX?FpF!Ywe%kZ~PUgVB**|&z*g>wIvnm~Xp5uy`7uV2>4tZ!T8!&gvK7z~B~qJthH z&F;m%V`yjlO|@v*S-t=)&e59r`7yp`udW2w-o1r*GlX6ghePM!A_*VrhAf&)QfLpf z(d;2WPFYWE-xE563Q&fbxr*N9hY1S(Ytd(eTYpW!-a~o7_{9fp+B_o`!pi#Q-t(Lt5y{nadE9OiivL_*{b9G$EJn@7H7jC){vq#V<}#ZXI+Nt0k17_ zoAz+dMs%|kigs1}uNQB4wGp$g44;|%+d2}*i7YMh>wQ~X91yNt=6X-OwYeJ1`V>Qm z8#012Km;xH5{;k9t~BiF6anzcE=ec zUpB(H1{G0dX)4BHw%X2`zXdUyRfY*Urp%DB zq~!ha%yv~lF-6)`Od%y1$5ixPwnCdGaB&a?Asp>7d>d@_vzUrKjwSv@Pum|YC*GjE z`s`J^DOpiu8t6a{17;dedUN2CK6Lt;1cv9O&ND&Iz2O7?rUA%#cCr>EOeeeT(F)aw ze|oQE34q<#)i0mTo}v5hDb{?qMcOUj+6Z+0acIAZfmSA#9=JA1gmcFXvXHMGZhQBL z(tb1`%T&x@yYsfS-{2Q+r)b(eU>K;ZS-putKELfj$z~| zb2=1^lOpblPT)GZ^QT~(-!tnp7ANDK*aVZ$WJL?exxJz=yb;2_#q1n%oE9{3`)N8O zOngNV#H7)q`MdJWyP{IrBlxMOShI&7ueYm>@7vMC~Rj^*(Yu8@JhYY+%Zvb*=^ zW$U|8(A)W~esCM@X%jAT{lM`0;)_zoFU2%$0itL*9jY6LWA3dd+}+crr2?Ct;a!mF z+W5&);$5g{Xc(j@@OLqWKXyWf+Ul{E5EUHdRs)XE_98!G-?h1heQ|e5Yh@N#-E@X9 zpNyN;iARR`nKyfIo?+_~8HQ6#h0`me8Cxy9wy-TSt#3gBt+^{{9MRtCpr+Qat9UlT2TR+uF46m+L*V;f}xzGI16J1(zCnWMjKtvSKg*{NHAs=u)Zaqg_*)S z-&ZI6N`AdXzQ31SDX=7UHZ2 zXR_5|6Dc%)zg=)w#XxEIM332|DR25tk)QZaiOXIA;e^n)vdU`t=w~G6)y&UnPCxh5 zaGkp$1ssgesvTaP9SXI^4dO2>JQ!!p z$H0clp)CZr^8)ToAGTBH!##wLY(<9hjIOFO_WgLH(_Y+!lo@NTdP?ekZuBDEWD9_y zxqNK9=fBa!?Qtu*g_on^L=8i{nKMsu!G#!4(x4Av&rG#q(y-)3wPa6{W5C8Su`|}` zt*pYNRsbC;UpzTVtyAHwAaSl<>VG_l~m4&tHS@ zJUuDIT^kF3m0D)n)ZjXzUuVAGKs0O zY=qb2!^#7I&jUY(C*oS3)fSOjL$xiBBOPq5Ti1wL$KUhH8U9)k_!3u3mN&l}{3N$T z;7*vJNhQCqudg=#2T7Ek#gz?lbIe5dWudss-2TJbAj7wMU$NQyNHjXc75@YEd&C3! z01%f`RQVGs-yk*ZuV7|ZQg{%E{ndgtraf*v8JY&NFbM02-#m5m0*tJBn zFBlMf1@+EvnU2I-ALX|TRG`733`ZhBJd)`ui#F$9+%NJpPqN#!|EvU1FIsH<@upXd zJQVGxY?NqZBDHFf9!D;kR1v-ZcxzBKoaTJ*?~4;=bHtc{(?8cYUiygJWb!b4_l}y? z1DnoKA7c0qtvQ1Nl)zZP*H#L&n`k}6$L?n3a#@}ou;b*b%mihcvL@8jYV8|EdCGNl zw_*f|{x!wMJ%^}>jQrL;P zP^%2*-3+QLcW?XmT9i!O@8++%45muG|CxO_Exr#xcbcaX)v?6a*J{{7!#wu6ryl?a ze8Z$XidRxem6IL{D2o1_ELzLv=IS1)e#z@UdgE}uq@GxQ!eWycmO(QmB~AGuxYbE;NAzJmR^5#3a0 zV!p}Nh<vu%tQ2cN6UuX<+;C{@8|KQ0WBeBC$2!VN56{M@+L1qVB$ z(WR#!oMZK%ANu+ne4qNM1&|pWX!`PN*_xz7BSlH94Dw9nirxF+tZ?*krVDO%Ja7;^ zh8fW*aBl3Cp*CJrhKeI$W+bcXjW&^to)O|(D)!$vot=)>Pp)en4E#0K{taHYN<&t7 zvAOIlu@|yW1PP1uJA#UDGd8$Mev45iK7$>)6SEY*HNBhK#Lriy1Am)6EDu6$--H+u z(7id5dch2Sb4zsuZ=iRVRsH7F`bvQYodqWVP?7#Hcl*#It^2?NJrPSsXq&l~dfpjh zx=o?O>_XZssWkdrwt{X(G%hM?)IUxPlHGavSAF)!?Prja^CE^?ivU3``l~6Q=^P(6 z|idb`jHX9xzH$Nan(+4j}*Shjji1tSSuUk(1M}y`pWkbUupGW z+urUFuc~Oe^YVv@21lBjV@2weUUQz3!`^>(e_i;u0y@a%6RN6Tx%*06!2#ZnU0`w= z9~g<5v9t3u1~n~GxNV}qRz}W2mBXEwiH-luxq^lne$NGaij^>;r73Bc9=gKYZhg95w}WejOn#@hss*N@ zL*v2Od(R|*T(bnjwj9g)DL>kN6K>ME%5GEb2BLqim|}(WiMuQb93>@LF}vDY$u$W! zkJZx=@B=7^WYj?YFBT+q5H1?%?SjO304j%W7+G6ItWkikQg>VWbDyN{3CI{M z8EmU(Pd|NAc*FsVr z%paEJZB2!4k{ymB5EkBb`Jv{Y$%4;tz#%H({zIOI@Wpmd=Fo{zd5tf= zI;6bZx<&#uB^ZGxVr0$|1++t@E7s~I_M_6#Bj$e>D?cfSflO=ddP_uy?O(HaIfUwSsvRUh(OK`+fA*#LiDs`eHWtjU$fw?YPZ^*!UwM~0wcjQl<>7-X zHZEIU&jO-=0KCn8?$5sEdPD0JWe7+)Ag%6i^S2QSt;isT@rWZRf4)zjRj?O|Ul0cl ztuYR@D<>X;dz&uE(Nmvh)FOgfXSzQd%{7lt_HqvNsm6+LuVcNEomO18#f4#($afbhK1>Z0+ z^_^9isHvK&gj_M`RUxT)rYM$FeZDg3#)RVVM_Dks!(G=Ku$~FmMPB%M#PI(1H{UjaUaOcF|m~mNA*0jBO3(zwF@W2si+Jc2$nY3U$>q1^ZB;&XfL+k zt`JVgWo#o5t{Pzunt93kI``wgm&psAv38EUL>FN)c33tWI2p7Pq^NC~q(x2jwrHHx zf$O9fDgrJkqIL2n)Yhsw(7?1fe1>J=}n5a zqwU9C;Z58|QOosq=fu_%Y(wXI0!CrSrkx`+_yv%EYX0O!o=#y(3b5)cS~``w;IMe} zMPI;d=`_*)!&!EdehMO{$hyxMAAZj>k^+I$W+tMf(eV3EneQHct1063bsaMhgb)Lx zC?ybx0|vQ~q-}Fp1!hIZV1nQgJtsA(v;m7Y&JTSkg|ky?gYnY@Xidypy-G|+1W>|V z|*3_5}{8?+1n`uLx|dbqs3pgHqC?Ukx2pvDcyb- zTiUv?*Tl|kQQA;3zTR^X@g?+=Eng+KM>ba7IBqf6bO|v@?P7HBQGDZ z?4@Jq-Opr;(kS{%q>iuF2XA88sWb=G=TI$}Ys2uGy)&_uYa^Dx%U^?fehZ`z{|)yH z^pqiQ;z}S42x@nthEpPa8*wEfTzqnF`xFS)MO4|Ljsp@wvR@l*$op!4GtBh4=Reov z^_Daiz$x>6{zH(+qW^#Z!)O?yTe7`2zk55v7VI4c<9=lk9sWGv&}xIJfe>{No7<}C zGkg3f;U3}VEOqBSrl7hA{vgh$9x}rJNRlN5!r>lzz~^Mx#0_RPpq!sS-d};v3aevQ z2TEr!r&{5q1WQ#Cqe@z$m3t9Vi1Pcc-#@T88o{b`di#$>tNUXAoG)(~N;4Q_(rkxS z-Uw?RJ!EY$i2DhGudJC)9S_b-@{11{s7el`E+bIV9q@+ANI^N)IgL{rk!-LTZOlLW zP-i!{dwTwnqcitY5v(i!{hqYYw`#r_Rg-f?pIn|p`!6qly^dv!|BwzDe$^ABWSIaE zZ}3CIk-lQtt0sLT>swW&n#|ijpQ8O^oDT!NW^>W z3{T(mLy5*2J*&qZYE67q5OVO$22`)@U+AUa@sNOW>61BY`<^gJJA=u$mGO=a{|zq*pK)ck-5qWHpc z6Nhg%<`8&^CRu9bU*jsDH~86a&s8b#oxum?;F@(O1SF4&roxHQ_j~iD^;ACkWP`El zXAe)JZQIFj%!KpU=pLCw&S1+Qu9`RW*@7PuU%&XE^DGKsS{_ zBK`9ZxKe)fLXQ8TnfV_ZYx@Rtc!v8@%WsYQ&O{^Td;m}Ad$+v5JjX&*DN&2O`Y&cB zy88CR*x~X&36eR!s-w;EUygpsaMI!>N3uEyS}3j;Vi05`iv!xH%DPoqiUQCf(2bWE z1_OeNgj*zA?&BZ})A%C0()!b~7wSWv(OcIAR>s52U5S>}+rn*&zCmKO+TJw_1^@7F8QHO+gs>snrVMW=ZTAAmPJSbldiBf=i#lsLB(X&6&<& zr&Jy;g=&|`ih_dF(zM_Y*zvDzIaxE$2!fQX{+}pDeC0h@(v46(IOA^TFIw)eTHqpx zZi9xiYsOalrcL}}bIxLgvCPs%fHt+shyCn5(Lqt#&@V__E>#$`rrgO=NFl)WtyU9V z>GQbIEDJ_An5COXV_gC*Ry5rJbqV9JP?Fb=-ina8u1_3`%BR0As;TQkKT!s{q|jpC zXg$2wXh$~=YA@rZpRS<-|@8c(@V&?}pVm#Xq;m4kEpEJj9bEGN zsvvx}#?OZ_;75nz{yB?F=Lv6U6E`AejL~s`mdpX!%Yv3{caa|`w*$C4t9@c4&l(`H zdmI!82ii-e43hRglUFOucI~OWnPs-1Sk@Ik{m0f@!dt}9l`zq0u1GKhHP^vSmup@2dhYy-7Z;?4{i!^ z?s}ls-+3=D(+iU@QD5%OO>Q~-aoy~3ZEj({{D!>zs-4)!?S^1#rvO!-ZPTT>RU5&C zu%)~_<*+Kv3xI%{`Wo=7;9u@a2sIUZjv6_A+q(J*yRKMTzFzew@AH}LmY*vkMSH<@ z_s2c&T9KjV-g*Y>sQ5@FteqYL5rv$VYnicV(E3YZUn;c%0P8;nhW~kO_?J^riHad^ zKd*2?rxy54@;tumLU-JKB>nr@C+`6`5sG$dxZV*K2?(PNw z=@#jdZibc=K|mT2P`W#%1f-?AV;qL=fp7Gj^FHT!-|r8Y`!{><6??6Ht?SAplFZ2E zJptgD+`SQ9%TG8AaDVljp^Gz&@y$kv^*-s;n%tyx69r(aP`lE$9 zKvrA1y2f!`*z>MYDqL;zJOk zqsWDDUJ{uioZtTooK05+vLK00F&e*t$e1s@eJtu?Wrdty>q4$41*zijaF$|~supRv zJ-DIQ{^H;cnz75@xQg8}QP_KZk2F`N!HfD4|RlA(1&m(aX3o4VF zsq#*2NN5LC4oJ;--2Vhs0j!IdnnRo^V!T5(%mrSYgf?32eFGgP0OAn*-YS`u zDN+sj?@shTS9tIU9g<(Ilf^c1xtYMMG+%V8{q(hzB&M8mtuebCFq8?4&o-Qb)h++K zI#}1vLfI@5Y0t_qSz0iWx@@njVBD;ZqsW=0{1GR5(t*S)tfoxO%-SM(~zy(|Ys z@k+gJZOUT#Ej4#ykN-$IP$ElKdY6Vez!M=93EpIobebu71EuWF#5|&PrKV$E4=oh8 zc+@Zww#CAh6V?YwCg$LeR}9CUmcnyKlPxx2QCb1u_N~G#B^v zM#-4-{vV9^e~bhOhSGMiiRircbRXM_XIlsp7uvxqnku z;K?G!xHVe*rLF7wWZP%GU$548u_ZR_a^P3bmCN@vc=kg>*!9>sSoB31M*S&u&SUJd zcI|gRLNFaf(yp@ggNg&kuUS!fCu_~MnSR$4U5T_IBXsvw%|pw~&bZ``2UY9K-8+X2 z<0Eg9PLoncD#J6g~PL4S^41Rj;T*#*N7eW*bS@S%5N%-C%Q_AZYrqCR) z$h9jES|d-15fkC8X`#*mnfEd{^;WY?%3GZV+ z1T=v$(!=3Evx9=UeywP~G=L7wXyS1tf98qO$YQTODW?^D*IzX!S-Q(hXS=F5+KAHP z;ra+&VAIv^alO;-&wSDU9rwz>A#IP!!3PW0?;8Nw`;WR&sSaB9Dn5pLN%4ec+U!U- ze;x^YhvE4)l_jKxcmJJ({|OFYGi0U&&H257Sbx>|sNOn!$E9pw@6zhnOj%08)o-(O zyu3{%%g_bW$>gp_ zDU#>mBcY*oJfbHQDR^Ncsu1`7H3vnfYMdQB)@O$E1&1q2iou=pdyBB(WPElbgSRN z#7Lu&YxS^qeI8xP2we@w6+zNd@Z2(|Y4o8#wzBpl6@n3(j-X}71KDD|3h!q+LpqBQ zXndpH_MpqG=h8l*)TwD6-71E7?Utb7B#JhBqA}dOrRb@ebhWRUxeY zrN@{wh%q~Sw3B=Cpcv6U=zQDtV}y*KpkcxvfJa=gbT^%_5Tt?G;2!4J%p^!d_b#+( zh0R{;BDxgnQP{+2;b_0hqVFa_O}cvVW?hh42{hc1HOl36?%qkGHU4`f{J%^gQ<4^| zm@<7n&%$Q1I&*KBgO5Hz`?+|x=6m)Yp7FI~7t^veBqpCnyzIP=Tyk53L*x2q-tPub z=;rqypI;?&Wzz+mlzX$KYz*ddsVD>UKJ5y%-^M2F3SdKaUg#)x`%|{zyspCn3>m3J zMWiz>XS`4HjDLb3*iBgup$%XIiHBXz5r!S%JftnExup z5VWQ-T_*1s!KZo{8_*#shmX@d*kRHl;W!AurqNzX1FH3B-ax9prMrBTm3M|7rZEea zyYe=*lG^kkZzMj*VSQ+qD%IXg*(%uPq0d>4N0P1O;14k4h!%a?mKhe1alE6YwT%v0 z8@i?=IodSP^MBug4a#VU(^Yj(oArEinE5SYw|KM_ik&l+;0Z5w)6m4qLlRa?aUX3) z(%WVuiWY6N-rCa6Sf+I~8}Xic#rL-!uXvc`PX9hnycU}~L7w541{WQ1&hp7-{l6F& z|8trDV*y(XAfkM_=!(3yj__9FUaUya?VD_9zep#F@^v^;f1R^2ZsYDm%=t65Zrt$$ zHdLQ9mFR7wcX~>fVUi$y;uh^9&m#)Uw5^r)W{2a_G^sFlM zHj9+-<9NU?z9?nuU}~_y>%LuzQu4p5D036kFK*;~db#$Yuh;RGI`vyezRi~zLGSlm zJf7h}7i8?FEqQ>_u8M0|P-)vZ7g+}n4@YGhoWVJ@9}JWQzG1(_L{pqyAd&-z+>vzqTqu3TwpFZkO- zT1qr;-@ubTnuI;Wszb^2bBvQBJ{&ahBL@9!t5}j*;~?zF?_{>ZjQ>^E!2FwwhG8Tkbg4Mx8wFqsCpbdD`5m^paSLLwi z_tjGp!@ORz*iuUJUAcFw{BsB~*UdOd+gKtu}-;kkoRk2u^J&6K!Wzw81 zO>|U~yx|STiCuxrRH&op2LVtNF2^R(CkwM^btp<5?lN&)>I;ebGwc(jd?Qm&2B|f| zn9c@$F`Tr2?0zPRwpqT|h+|Cj{DYbO*KQ&35~!61_vkk~%UMs)&2tY4+D`?sx|CoZ z%I#s_y*YW!vnk6BoD5O1za!^_ZZ>6kYE0`Ul$I30R1peD35bvv!*hI3(RHW4@ zc_u4XsOEan_;-y09?fu6tuQsyL{2F$(9@qOg%?mZX1W(gK^&rveu*}iM$<$e1rsyU zEbuf1u>LQ39!5@}cFBPz&1LoUNRi2?l% zk>f%QqDK(XQ|HLsM@8lu2Q=A5dK(^wtt*640`A>aO(*wZ8 z$PtdupVP?h`+d4y4c5`EKp#;nLwOjK`NG>ZBa&y&*GQ7G4}b810!z z-^sh4=G8=UJMut^LS>9$%u;we@k72p`PgC=N$;X2n+a_% zJ-FcnS(i;~{P!LphNNSWmK)?D{D$mi_bU)=HmpkU3dX~lBJYF$_p;nf(R5N9ij|9s z**uU$SO1_h4r}q?<`-jJj=*%5n#doKuvSbIjS73(fJg_p?8i0T9(oDaSSwtW?E~Y9 z5nfzs({si^XX3HxPAM#d7S^UVw;DbhLpxCJaVLa=>D8pIXc;0kkhxcev=*RYgZn3rp)#@YePMNuj z-H-pD&a1S!8){CO_40Xil_EOA<6 z*wkpdHYJ(4ms(2o3`3d0Sr!l$^9A*;uWRc^1tGwvLL-ih>Z-PXYM6a%7?WlpmaF8G zTq_waQA1*znJi8jZHTyd9ke#)^A_OQ;0CkXMJMrEw~N9DsD1DKw7+5Gj&c2;d8 z;YMii#G7zf+n&R!z@X_Fg}u&nma!PwE~EWWb;sxMXHs78e{mMO$^_bFi-cV)R(bl< zt%2>1#_A6@?&_all1jN?AB?%arZsq9=^$5t^5nC~Cd>yr; zQ_N#hOEY3_D?Yb4_$>d_t6!S!PtVd31KANPZ&^e^8wXYTE-dxA09*&UDX|$?7f>`6 z4e`cvJX)LFk)x5u`N*@(6=6PbsXTFU;fG6J6Ghm|Kbp<5E0z9GmFYxS7aUv{Ud(qF zxaavt`SoAP{C5a3Qb0Njnrb3HG@74bR?Jb_4V8aQT2rwK)IwV?EXx&9d?^Nw{l%Fo z6(ZWnec~><^reTMP@ZU!P@a+RX;HR{a|BClWM0#Os5aZa?F9% zN)KAyRo}z0a2UOfO^)$n6m{O}C)0J^>Ol%J9$qL@+RpXuG;r-<8^wc<8vF%!6 zOW{o!oqI*rB}hDNEy;t+1OjGTa(2j8N4i=0`mg?_cr=oD$DDcRLY*cA-^8?v8$z=_& zUf=1fXB8i5os>{XpU1JSx30JSXQ%P$LvYm-KozI`IR`wDHlSV40-8vBj<2+oBF?jXn$o%a~M!o_|Y_gLlZ;*NSL9oI!2$FUp^7F0szmFFFVp+C8_wG zOp&sMZew6|i~Q>LcgX1a8cL_QgNznA68Rm`b^nI+N#b?kZPgc5?-cgU%GrHce;@K{ zTD*p!Q0r`mW$~X1E&I;d-fn8$lZn2sw(+-rv$`PS9-pml)$jaho(MFr#rI|4?d@nw z0#_xo*AzsO^JC4W&&fMk_>fr@R+z*JKC6pt*F$18A2i7wE1eFmgofEX>G;Igs2h8X z0VYM87$=nY)*a6jO`;Cr*RL8#phE|>mRwuN2bo2bGC3SbPoN* zinVJUbAoKGxd@Sc;aywcJ>jHJ@#WP z7yo^sa5YC& z#E_TU?RI`~fV1Ip^cBHB)dz^(+>pun>>~KPR`!%jwclf8JJnqn zL6;3*N9sZ%UQ)awTcg5H9W{dj%B{IpUSM4v2)1cAW9H`n(y}}bXl*7Apbm2XcB|O2 zC*ouv%yEOxkl5mNAJf$DMm1QDv2VeuWBx4L=&W&)jJk{lqE@n{y~I3rw|3^H)-T+3 zod=iWO5x#F+!ICN{Y%B`7cO$Zi{m7xXZp925N%|)ORdDz;ii=@JHi6_6E&B(YV=AEM&2AD%=|*`CIjemp_@h_dIsAVD||X12JiL`Bd3?>-=cjvfi{ zMAiTHD5%;)=y|m}4Y5gQBGR5zt&g=`9kV}er4U(BuA(t#nK|Jgc~sSII&q4 zcF5spV6csUm{^$iVTk3u3X72JB0=*;CM@`HeB15y~? zSH2$z4r?dCd-4?F6x@dG4i`=zYOEHuLm%yq*U02ristE-+`H!UtIJfUlEQ$8e)dgS z;_p;SzCdG0wKdq|WF>=r&`X5>ZQtNkDcVT`SC_0wLv$oGRE9Cu_@Icc7r+p9RbOH? z*N;vwbSHcIQo}9o{cJTPt6Ks1bVmwt7x!4X;nb*rYKjf=g1|?T8RPRSgKs~ViXQZ% zJM>%Oa+FUdr46CB$0hdd*((6eMY&AYMMC-s(O`^hpBqPKzXf=Lrn*0goKUOuKZWOz zyEHs`K%aWk?nthe?{ci06M=h6-1AI_XqVu_;)Zbdz`nP6nEtP7B|>4C+s~h`e=nem z67`B;WXXep4ahKcBlf|MfY+rm-)r=kF8tcw1;e*Ve?0e z37#N`FzZgH_B(4A5A^^H=(asHP%Vu`|1aU2@UBQuw4o9B``~;CDz1m~ncC)XkigIK z=?nmUA!63pdFkEfbIH<%c2mj?6erJ~j0Szyw3T{|x-T*cy_THc_VNfFWI{eNsI6faJEoVs*rgl^phtg05CIeMy5VV${)J z5LT@JARKO0`eXabHZ2TIc;HDldMN#UI}Wzju1)#s)9E7u)KA|C4^H?V%f@+sVD@UW z1@5Rr0y!)8ch>fv1ZXYPB+|^#9OaKj+fiD6*`2M6@7QV-;MfN7pGm*<88L>P4DA=w z!|)+C##Yobn?aT)Bn-6q?p&{i5T}iRgK+>r!g}hVb$Sdy`Y-nOvkl_FoGF~8InFO} zrFgH-9VyDjcRQd`9>+b-H0}(GxLkFe`+k_I_sb@K2_XK`BnJ+G)LY`2sv$n*=huQ!e%vy39 z0OHq+=a|lw6nZl0iJgZ*rdD$j;|ClG-z?2iiUy2iLhf3$p@vPLg1&~lt6O2sv6F(4 z^1H+?u^D;O($ZjsrJd~s-7qAtRDsd)BTmxM+~Z$|R3<88>)6|dVtdyH+!Lt6l5OXC zFtgM8vr^V?`urgU-T-LRKO&w6W$nB1g) zT3W4GZbtYQy=+>|aSxz+^{f6=mtw=i!263FwZKK(HHz90{Bpjf*zCXU_=pJg)A*2; zOZGc*GrQR5L;xNFS|{5xI$H&xg_~MLjIFQ2a4!I|OPD|Z!wcUAo85Yz>Vgi~nlpLg zC8sVq8{D(@?D$q7G{SwWN7X>6phQ^zWv1uGZGCBYIm7s|dq)5KWjI%k*$5GYl+~zv z_SDCTp|d#iA$2da^N2J0#)5Q%nYNfK?%CIXT04pok)wTjd0P@s@EQ^Q$<0KqCvp*~a2rN1kvZHy))Z4?tuYryf#J#v~IhnXvMS4#f z#D&mzVutwj$B4&hGmeAzZl5kT$eS$n^wca)kFMtNWw>@IhKJ8_Mh=rZY5qMp`HzRM z>4AW6N{8w-kKiBFOLGV0X|YNK8?CbR5hLD#9LpOQOZHBa{$SlzXo590Tw&Rjn) zdnyN~?Eco#y%ih(d4AaGIo=$(q)Vj0Y^aNWt!e6I@02~c&j4SWv$1Cd%>}#Eo{8zj zggasu`HbM@!(YM3Tnu$#Z3i=T9HdIK6YU&R#pl29-A`loW!;f@Os12wDvO?oqhdbp z{L>dZE-&zTp8h2GZv&`$444bX4{tIk@%g}jpoo(E{56dBv713yAElj|p=5Ag#N)`Q zx#Gu6iCB}Ng*-;Q89OLYsGbxUj%_IFSCstTho)_{4Z&P+7X|Xwy!x(pkr%;>!$R3c z$pq_}F_&E&SMbrvlRUq$71SCx^>YpnXr~*;hlJs}ua#8VlsO~s%c@Em>9zmUWes#Rs zA;Gr{*D#=-v4yeSx|nQcI$9lnN^AD4ebc`^y$c<*cQK`1cG%14mKKEKr1vOXk_jNM z?L9as(A9>XO=Vdp?lXTt*x^gKzqp3d>P57qK2<0d&Y^^JAW&)`A`)>5Dj}m1e?fOU z^L-f#6qWE6VW#<65y~Z{1pE3J!1XJhcud=@_`M~G21Spyesh4tn-m^a85jv^b)}s7 zIoA9Jz*?pWc#|{N}Yp9Pkwy zYLyXkQY3Ca_P1S$$*XSZ7dawY`*f1Ar?Lvtv$3VmrEd<}}>jFZ|>x~c) z6HgwoE@L$5=lK9|~?lz!hr8(c~rp@_eaT<_o)|4ZmqNP!^GmgXt z7QFCw$^Cm4!7TYq7oG#g(lHGr```kEpr{;SUAzq#HC|$++QAy#9|WKvbHpGksGO8` z5(+;Yd@o)7D`_Bz2nF!wRId1K2MU|rV190g9$tv#BfbRloqHuv;YqSv*{;^&G}-hl z&?c=FCE&|3xp9mY^--6+?mrW>$p1LuFayXg-Wk>&fQt}G3BX6jO0p;f>Me3)XrUp? z;|{Bg=gB8_d~cW?$QFU>aqp7yP>5nvN#`X>BAUEJ#q$2`!Z40&Q#9J}2+%POndRE; z(W=Zz2qJ|MXTg1sT1Ml*IHHL&Htv1+5j2!gv;g&tx0l5l7kslU`WnRp*Jc7Pzb+=K z>VnkZ%6p;_3BSSKf9%Ld8mYtUKw;R7P`2{Rr{Ykrz_5i+y!W`7M<(7(cA{@*+_&$b zJHfKht*f1GF3Vf>RKaAS{$*Wh?fGw1V$i*=jxGbYH66r%m<=D_KrLesf0W2N6 zuNdTKBzxm{nQnHXRdnKO!*>9t!M1TbA%KplaJGVv=;rnW5s#?znwaR#ZIlbU@q&z? znLyo)SWBpiz6`y@qexlTv=N_?O?UcTr8P!*DGwcTVc}GnCPdL69`l#j8^SX8EBfrq*Uw51Ty6Auat@5tr zn=i!ej?mqh;|0`ZgcB{5E7*wFwY-hv9pXYk-Z#LcqML8d~D)n|L zU^j>45ByP5sd=bd8ST7Q4)e;k`aVNGeodlRaA8s3Ep zsH1HY#^^ry?si#rLBX!CO}bE8rF1-gT?0h*K9_nN+0+VMH48%1B({6V5_!NrPB?WB zdd4`DC@>2movstmgQKiM1hN=0Or0sYNtYz`RmEXf8QDBtI=rDZTHZRN*%k(Y#>R{Y zb+rFrlurnNT;b0#q)x*|c*5V$WpSOIcJqU>&-wW)F;RdNN5g!*&EP6H5aT9B&`{G= z_5rjg_kZIPo#dq!rb$w&DufnhJdG}(tyqenqkD|}{L5+uEqk%QqyYg+h`1nm9oROslG*7%1gbD8`Pt5d((UtmHud(loP8P`O$=d=7+$mEFOQk(G%{^5`rL| z`YU7o@oYq)nnHJp89VR-rCb+nduBiZFMs zb3t2k)EwKvto<~H*>n}+T{3B#S;54X1AU5v)nhlDiR%OmNwvQhM#a#jra0#cZ6dM1 zc?@v%w#w|_rSe*yv&~o&3M_K}Ctv*I+NQLi@^U89(mDIpkINh}Q&x0U-l)t!2ug!o zNh3yRSzE4gQ9pV2UEE1Igpz+A1= zQH+l#2a$hyWdJgG573uPaYDL@a=EZLt?Rnz{#lS}Ph%>4MAK|7#=-I3C;2rJ`B(GL zMbPKE`m<)18`nPWDQqmVVpk|X0{rtAf8SrMQEeG@XGd3QUs4mW`G+?*8!8GAWlY zr7Ael;@og|&A!=G3OHZs@)p9lLUVLSOW7wt!Cu@=BZ~FFfwEcUBBdzBJVN&*#2ZW_ zS`#(MT&qI3iwFzd8KQ>TRte}3nWEQL z$IWnG^VGGu^zM*uF^|HanLm4#>fYTWREu$EPqy$Qk<2>#ivJE`b4UQ4(Fn*WR}dSu zCT#@jtwn<~k|Cc33ot~_wO!Tk`=?SfV8@rTdzn+pV=ay;w~DX5E_1AOyo*C^nj#Hg zB(#2TzIHugz%Mu%b|6!r_Hhe`Z2eyJabDk5O+sK0&CP4xJC(gjd7rQ)n*$m`iI%*g^A z6^AJz>kdGH8Oe~+snJK2X|KjfZcVd{&d))^i(?YH{hI!6_!uW@+j1E}i*9380Uu^3 zFBToF0j*2iW$iCtJDYxf*a3H39M|~o`H$XRBRIWG8b^2`XrQr=ZmHsNRLb2J&9}41 z$7>o3fYN3OnnSYNuWSQieZ^zrpMw0O4%O8Ix}AQswD6PTX$rw%5nREdDadnf zjv>2#`k)4q#my=abbER%)Y<2BjN?Q1MT25_wTDUj-~Hs1Dh_Nt0lJf zoF|6}=E5qR57AJW^lg^KOyx7SgT!AxY+lh3-BZI>RIW!q)??KdSi>P-XABMR41?kr z`bR60%mx}kRRq%TO@_BR7aeqk@iwEk{xAbWJ;NcfK5`qoa{kLQ_{^rBJ0}~8-R*Vp zf>=spZg5G^+KR?%C;L|#J15rSgL>|P0|kmnzWGUf_$M67moyb_IXuCd8lCMjmzG3f z5;GX3V@I`+Zq?%*O_L^pMx4hEzF@Eg_e^9R`)8i#ZMjUxUvAD$YKx~OIFPXIMs9bA!i}rG(hOE>=OKrE;3eFkF(Qh2xv0*QX}7+v zPNq{P*?Mn9)3i0MXh6(3*z3eVrDZjt!iP~&+Q@0aaIrjPNgU^#27wlBY*S3ER;@Jq zz?C|)qi6?LOhnn<*{ZKobWyM)v!hWy{WQueQL*}LbGgm#UWl~l+Rb@361wIBn#2*0 z5qRdo4?Z2gH77L;Z0b*%imYy{j{a4iwjL4Se$aSPbUn|{@`L>6Z6TvIG%NA&imkJL zfOFp(!fv3@c2IndEZvazP{v{oPCg4%aBFsItb?D;6lWcqlpafR^M?`rLH9^jygy zW^VcV%N#!HOZQtB>$XgR5sB9O7?=yG>6m6fhkd9(WE1BN3u_*VheFy4jc_BizR*>lMFAOyLNF^0p}s-E zTMTMijfEAV^8$T`%54o8uFkNL6|^sq#f7zUx$)-R%1~x9&9*`I%LEf66RXabx!bjn z>NBHeiJyqWS-dPiv+jf=h^J7%++i}-M51uRpr4LbiK{26qD1XC@%a~c%l^}# z;V|)H2Mgzp#~fLm+UO^n-}@xWhi|mrub$`!7M@>DEqba`lsW%;%HmwLVB}FQjk6)4 zN<6G4kQ3l|UI-l!YgNZ47jC@sdF_j%-AX-VbIB?(xv_Nr=ERU}-=*&UTx~YvZ2w4T zA@-8W(`YeDTYROyVPked!~@1PyQwP?XgDKQ$c1cZYgrqAY4h_WoQa;7YCg{UCgjFV zKX}7h*5+zZY-D%r23ilvN~L$oSTRiWAA>g*-yphr{E_^xWi~&~u3QV94$-JjSMs%w zW{2(HI$yh=UQ8|W8QzxQe5O)%f$X~`(!dbQx87dA)LniVv#qh{u$_{UG-LL@(k#tn zv$2lyv&O*Wjo^id4#{ErpM7xhH%zN9e$u&JeWMJ46*oe%`1P0V42NBy-L+o}a#w~} zM-qiu6D{m#o6n7wuSN!M^_@GPCTh$!k=w(@+xZUetGUxCjVV6eKW6z_U?#7$@*xuM zEEHE3}G$qaF-p$5#T7SHUmgOeDT5F~kRjMiTNPjx$V-MwPgOcMz zO(irQ7EZQ`yhpR8_hk&5WiD^{7WnK{rv?(iVnNrjcQf`|Y|z2h^I~Xy&A6?@lnzGZ zLS`}toBNmhCGN-thfC$5s*9AJ`he9Ns^911QV+X22RPl0h&YzLTU1tpZKoJs-0QOm zF;?dG-()n{Bi5~Qvkz7AXOkH`h;k#g(1@nLlAaq&htO~#qiymTK z?>DR?a8i!n4Y0F{Rj?&4*E*<(Tr3WVQYBW4u8Wrk6D*Rw?5Gvco-s|a+iiBDQI_y< zDWQR%HT9d_TVy(JbYEvBuDj<>T_4Rw9zRXo7x(|rFjOUr{f1L^<^DD&8CENHx4mGR z7#ZJO*jt$mLvF5X7i_#Xp2XOyK1-EogxTFp-XwYN!Ig#srW1I}r(FVl5m}fad%N1- zD_c9V@MAIwR0HDI7#HL_(~!TK-x7IT8?Ng){tnVrLzz z2)_5g1C_mtpNr@&9CLDU0v5YWb6bDrvjPh9S%X_at}mkk2vBa~l|S zLu5Sv*VUEB!+IYsPwC;~?RwjL*9X9GZ!yx(qPnRG*L$+QL+7pxY#Zy{0FpQ|oLHNa z%h$v}#`h)h763~!8Fx>FNqm5xF-o4De#*)B$DT3cD>lD&UN_<(Llo%GU4GnCmq+vt#4MkIG=5ii_b|zy6@x zeY3M%S&pTBQUkJ~?S9IPD%L~Y+^L2$h(_-6m|5LH&QXDlOgVXrz)xlso6c19S-Ag& zYGQi{V$3?8ozHf%tO@L{|KDU{KTsb@=>ad;Nj=66fF#_+zyt;nKw!EKz5_zbG zY>*LDQsyG&UyQG^!}iR96*>o}b5xn6=90KM!$X(xjXK1&u(`yV3KPc(7U;jLv&;!9 z7^t&AJAdM70aqHmtf~zqF6->+?{t;Ib_BW1qK?fF-=#L#u)^oybrp=Gt6y!H5hl&J z@Rd6ni8V)TNw!DsP2wdFCIRaUI&)srbcD>fc^fgaWzBxJk*l7NAALFlb6-o8;g7w@ z)Uln3S2Z{LQ8167-yiu({J5xC3TvjEm`vs&%sXl}pSURF_y~v8s$-q$UTJoaF7`C) zM+8X(ym68ZtKJ0ipTS84za63O3Pzu~ZN3GMYd8wLi-~-B-;ERwRW9E~NdE}J`^532 zJ-pvQp*OMtR}M{j*<(Ck))-WQ=Tg8Q3bgO7SdoU6T$DbVRlWHOzS5;Ypg4Qv;q+k3 zpfg{AU^-A-y*I(lB)auTEg;taGH^5>S@ z8&M@c+xZB-IOye$RkRytg}sp-L@r2%APT3qcLndu%+#<+9-{4*eRiG8PpJcGf+eCB zu*T4$C2%Ytfler6M+&Q;Bb9C$*)|tu&bo4k{CAqs5YUX*Sc=b!xUXelV=>Rf^f&My z5cI_sUAozSRa=xK;22b^ZCZ~&!7m7CESBwDfVk+=zTA?arA$~DdA6Ni-Zs#(<}20G zFy(qzKiT3T7T1@83%>=9=N^%$`%c-29u_B9GFXh2!Raa148vb_^_3uCKO-k6xQ(vl zC=m5X%GB4)!CiLs{xV91(Gdr18^OO)!kpr}Pv+PbzAT=9zE`L1fK~Qm=z2L}LE37Y zwQcPzw$c8q)eP0#B+>2#VsyQ+yOPsNbl32qpR~;bD;o2~v=p$_dYuLL&HUV&@`DFn z>WWj{3KRWDD|_Nq&i-;b$9VWd4T!h)eE11Z&@<&8p(;-7EoP6`KFB_*#+GWzsPpNi zbwUCv4(d|9ISE)uG#OC?YXA-&DxH|W>(Ji-EZ2Ihin_g+r_b1c)}>a!EUV5YMmghM zx_q8Pt*aGE`MtOidd#)&Vg7`5i$2;ntS3`zu4>o&;j;_&?^e2BtORTS!JSq)O>=GS%^BiC@WpQfDG_}BzW`s(c7-i zvFq){-G591paw7(uZ-b6V-Eb8kH6-!v0Q&C;Qfo%C-Q^fnMw$98}U^aLndB#no;-Y zq|`A|DE!r66o#De_ed}4XC2zhiOTr+O0-7<#tHH=KK&E=T1ag9r#-+u>A!(UUAMrW zpkDermBFGjxP7NKfdAQ?JqOc!A1xDx`7i~Q|JEm*p{nn*)+z`!>J8FP& zQ~N8`PJxpiv7#C3B~EST`KSD0nv)DKl}k4GjelOiGR!|5hSJ*7yw#9q{S>)*;m^1H ztzt}OaLsQ|Ubq=ct1XIfKj(k?4M*6(5JjITrAutmuZfHDw4{tqt?~BRAjIR(7P2Jf z#~{zAT%z#(_Q(% zlTE!HXL8nRv1i({D=Lb(Lu_aub(FPk@IX$e~8dTdbd$tKf6tge^Te; z(vE@X!Vc$_s@v#g<9%+%zBG4DLrIevH&?}Pd(yawTpo;3);bc8yIfdEyZ0ZIDuR}^ zOW*)Pb5998IC3U<*K5%zQydvgfIQxzDV-xss&|SZW>sGW2&StFdlyT*rj2wkZwNGB z4DCd5D@hG2sW36gMNrS9-oI2D^r#O+JlHIxjSF26%na&2R;LeNc{IjBg59&;ra}3p zRfvTO?bt?7?xQ<)$MdT%Dh`z=jQDhPVo$~!W_uPKss~7F7IRWGiq$*!sK zF6i6!V&1q=gFO~lc|2EOHT9UCFzTWZJL^wvZRlrKIq2lsv`b z(_HK|D));I34F;##m8v2S@;-XUXF;l=7zxUF(#2S-*6LQTA8Uq0judf21lPgabGKz zm7?#(ce5hUTL{dwt*KvI2BBbBP@HI}S&bnl1g2GK%dhU!NOnt1Kb967x;+UC1p?3A zI8nw}dMz6@?Qx1{chTaB31)!3krklY0L)mMBbS$)(Q2*cZQ_vH(|C8>I9DEoMx&g)8zUC#Mj{`O&ZQWgPRPXCXs zw}5JE>()Ra#hv0-pcE@wpg6&yxVuBK;!@nTI4$ljE$&W`0>!Px-2z2|TLQfFKRx&U z_q{j99vR6<_Rd^uP5-+ixkidPim>93f*6Ydv<4{YD_i^&J(MNdTcXdp>w ztcNcK&bpXArz4zrI~a+#WFX{y!~Tkou+|RVNZLt_mij&N$2hXYIwHSdCD?g9+Mup1 zI2ZWIf~e7w2sEQIbXh`Cz~hrm7*dIL&0h$RPy~%LJzw~lc&0XiT85H%Wi-$7j(@hr z?F9ETc5!4^)dotN!AXV*LDuR}R4~h$fM4j@yxE`|w0LltUo+(bduaePZEz`^@Roip zkTf~ZKPM`rr2{4WVMspc{>H1cY)vpk!JQPjWb&AYde*1Iov)K}3Pt(?ZKaoyT>!l8 zz>{Y>&A7=3uHUryKFgo3%l>HSMev)!8wx*6^q`^g&C}r2$a)&~d|>a*>fJzP75|Tc z$X~$v@=zs%0eZahsIU%%{Z=%c;nB_6GZ4lOwm`R5kicV32-?1t{vjr*pDl?8j+_Pnblu zdY1~um+tAXwv3{Y0dsX)^$$UZ>CG(4W}QOL$V-|+AWSgyi_vr0(3r6zE3=(Fyk`=!hPT@s`w%DHNZ;MzFMiFnKvr=f~%YrzZHwc4w7Sb|8x528o&HCbVE z85!^wnAO}N7d;Q^Yf{D7lhqNvv;cNc0o$RuuT_(2>pZO9af;o;tg0#?6?mRd<)mRw zR)5tSl*Gl@+2j4)f*kk)yu|nuFOF47HPl*iSsS3azty(e@TEh@Tjto+uZ|c3a$k z4m#}!we#7=XrDd!L3!BW(WJt~=!B7O+PJR{^hCPAoyaQ8RC~DS?4o0x`a6lQ+^yx) zOIsCM`!YoK)d887@=fB0j$j06tXCNC%EfBF!b3!gfH>$G;DhjZR4tXKhHd|%2)E0$ zh0758d$aB&D~!rn*_S~sj_GHlLy8Gp37%$_Q?hEu4?dG9>oq0ggI=Z=H2dm22X6zu zp^?{vPK^dXYCH$2BX`adPB3M~rF|CrqMZqESnP)I(C`yC=k(oK_MOZ{)+&#<9G_5g zx2%|VK3Vxx$yq}Z5sd~`;LTTIV5kmu0z3739OMOPK(+fB;Qdy@+L@t8qSbQSgbB3! z72~7QJzAT=q*r_{SEh@~XV*FG$u+l?)A8RSpT(7F9gKw;t~}oK-kc^6pnQpA$OS5< z@qJdY|KbvRF;`wFK0uwPX=i$DY#4L1oD^%rDy%>etfz0Ee>|LUu$>F+O7{qi<@w^4 zn(IH%a2IFUst_n0P-gFXXW2P8y6|eK4OS@3oTYZRcOLUm65f`Xd4@kRp#?mDPBzLN zu%>tZ_DPj23Rz68$&D}nL}qtXBtgM%7Ce2PgDJXeAYh_XU7gu2$@Siaw?z`~7#U!5 zyTG~m(3o2!QgiLN3@^qKYT5IbO<%dFE%EQWz^@mq{^eC)GXyU&J_!xe%Qm7)KJ=tL zgYB((D(D_-*dSE02cCB`PR^f) z1{^QfmWmibA6XmA+}H%?8cIWmca<^%5B*Kf{98IXL=wu&x&x-FvFA$slX?R@TZzLy z)b;-8hFmK}UnRUte;kBudDx{L@r_T7_)l(Ehczv{3cLkpBf)s&0lh+L&Ua)~6cyQCfPxj7iqZW&i*sZKkH>ezI!}`Iz2*FC_i)Q zr_{f-07Qq+{rPP|5}kZWSv}=GmZg1}E#PTQIqPX%cfi97R4yn}Rh)KS4p%s5%$@n-wx zVee!H2D6WxO#Ll*!L#YkFN?33GAE4^4kYKooIIBH9tG|4SS~3nWc(!tF)cro8~E7g z6!&CSo05J4n%rY40+ewJisQhqDGZeRSt*xWxPI7k7SQi_`i+K0H)AdMqUx=_vt2+X zm8D3~y}pG>%2;@hpco5AQJ67Jc%t|ZbD}#Rq&65gfZ5od_N+O&yhnk*Z9UGJm(rnn zQ@^ePAJ@+{8tI>5_>u!`2tr?5CVD%t3BM3_2QaZL`&^Xu7Zrqirj@#Uv@o&mTw4g7 zat;)9l8wrv#$lS%pPvrFeA`{KXVuLx+gYy%Dg%0>NB$kQvU#0)-Y<}44 zh~*hCMQo$SGzvun4cc>{Wz`;`trRM+Aa-m2=7J2~kXpR=(Fui5E<-3P8|NVRMe{*` z3LRxPh{{UcY!LW<<_!=?vCu+Lmlg%4ER!Ic`R*c1f(7}TM|FWGHr&B^GPCH;Z7duUWSu;ER~IrAZ336B&K+ec{gndbgpCkJXA&ULOPy z@dlsQ+1!~5QlOLiQa%zd-l9tcu-}wvI=!ro@2S8>SFaNv^~{qT^@ha}I|)aVkx2n~ zN&CVfd#*-oF#hC%M*A@u43Edz9*v&d z5!ddb$6`y@j-$Vtr}6@S>VC075Z!TDfcoLc%h4KL7yfLS&V_a|hNyo~-^D}3Ul2lU zl)hC~dv)n*6?i?+!0LV~t2I6F_Uz^zc9D~?!98e(!MgM0RM1Q6S|x?!5D9=JX+|g;4PTP~?BqJK zlE9kL%0U#7iuE~8C0f_4>uZCTr_ul`2k5}7lw|zc2=XDDI{C%Z&5VcJWc43>Y0u2p z<^&$Q1b(;3-uSJiemJ`J_#UkaXMIehJ){|vclX$GHrW>_pE8)#!@1eF)42gGl@6q^ zkMA9!=U<^Neq3stS!ugqdPC{T8vB~HC;6pz9i%~|BPu=7?wJcAhV&O*DN0)@h_;)18;;C5)Ce=X>gZS; z6ni}@EZJ&~VdArn6jalchUIe(G`M*#Fr6)R)AmYRMg%dD0SQs^6@=aSN-DOr7 zSkHgS0(eRDf3H(kMD)&F`ZB20#y(Ox(&Hz!{`4`;IqvTEiz3Y!*qEZhnp5$wHK5Ki zXp^Dj!mX*K14pUHxcOG7{-iEsll+mUJgs)EeC2_Bqyuv^jBtY6)LkD*9Z=)ZH`Ce} z_!=-<-O|+7_~Tek*rpunyoCQB(%{tn&!sCXwq5x#n@}DJgFf*WW3lDisJI-1MXTbL zs?GuR1uzH3+=)7BpXrjE|^ZVJM^`_y0UFk*JZ-Ww|e~DoV>uFpT$=x)3N2`VP|Nk(4 z%HXd*tt=4ZfxS0u+zux1Tk+dMK#@Vo6OhevT`9Oi{i9Qn0l%fX5Fm{$r7BA8f%-JB zTmM7pKlJ{;UVA3d-W|ZWFXj2^69uz^HeeNfZqzeH4KXzg+0UoC;p4MKPv51U^SCy$ zK|EfuEhyheKvNXencbGXIc!He%0bYVwD)Sh@{=XK|Nl-dKSD60Y@NsQVwWp*eniTE zH$Yu*vSB&}7yneX@|D4r#cnh@_fVTWSGm!@0}kHCenvoMGcdg6BF!6Up@7;J!- zs$9Wm3vD}Ja=YyBA9EhiRqx=p0F^elEwJR$M2(!HP2e-kkHj;3$Ny2wR2g-5r1mD% z{E_F3I{9W)u5=5(;E~IZ-jfv|dVTNAsylK#gkFC3$Zt+xt0?9lVF_%1{fB5#y2NYz zfYc~1g6i7KwA)m@w%1yVNHaIuISZ@vAN7qOrA&3fMw#_DBGf}+^iFwYS-K+ zYY)^@DE0M zl0SJfUAye%jz3=qp0t2OgTqrwCLyl^wbz{enV^QZbbFrqpgXSZBQJ%#0UjI+(~n)6 zpieFeUKJd^+OyC)C)>Si7o4n;$Ol8OQ75#VRIcng=nM-n*wD}5-0ommgt(=|ZYXsQ z{;di5ntWnz|HJ0ONv&!>hr|XnM)=p6@3<4Ux4ylkS6IK5x8e;%68FYol|p|gv9M$a z2Ap1_@rU22^CR$`g^$S2UH5VG+?H7eYhNTH(O==NMA`!qZQ6CyaIy;5dEq44~Vv{K#(=Pg7>-600ysHspaLR}A&Amn*y3xt={ujTlI<^GJBm z@0^5{o-IA3mQqbV-rvINAe0h|U7twEsw_xHTE2iu=9L(N^Re=hv4@D$j9T10?B`w9 zP7;QHZ0kemx)Ez)m`vvM9)`#9=A>u3%jcdD)W*;rU{i~9`Hk(KH zJV2qxL5}mmNKE>j-o$Ualged73n~ft3?j|`gT%NIZeBVeK#ZG`b*nIyS&9>~^CpK$ z^L`^*-t6AIft-`F16u(13y{Ysl|dd53ii$ninpFVnUD7Rv$9V@w&xTOREFJ zBvbHcUhDWY(oT_kPeAy+jYMRpUVs}|^Wpl0*u5f*hFr9}JyVF4%__kZ0 zYjvGK3^MpTb@K7_WK%$eLqDfOE5OYlvtxdr%bHX$WgJGH~V5 zfZQW+WT~2L-7o;0*Q&})EX)1~b%Ts@%#82Ok3`y4X5GSsF(!MwJnj&7db0bG zqd-9m%{yie3%0GYmRS*b+nm@pFO#wuOygGYGdIoJglAJ7Mf8ZE9drSBKMYl zwt8Qzhi3c;BaQO*;=qedrH@e;yvKxn=S@G0ZGIHZW9l%Cw5Wz95`b*

M*L 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 WLxG;+_w1Z~{AFo&`C=*DBl1tTZv|Zd literal 0 HcmV?d00001 diff --git a/src/core/arm/nce/arm_nce.cpp b/src/core/arm/nce/arm_nce.cpp index 877e8ac3c7..0e0d72fc8a 100644 --- a/src/core/arm/nce/arm_nce.cpp +++ b/src/core/arm/nce/arm_nce.cpp @@ -227,7 +227,7 @@ HaltReason ArmNce::RunThread(Kernel::KThread* thread) { if (auto it = post_handlers.find(m_guest_ctx.pc); it != post_handlers.end()) { hr = ReturnToRunCodeByTrampoline(thread_params, &m_guest_ctx, it->second); } else { - hr = ReturnToRunCodeByExceptionLevelChange(m_thread_id, thread_params); + hr = ReturnToRunCodeByExceptionLevelChange(m_thread_id, thread_params); // Android: Use "process handle SIGUSR2 -n true -p true -s false" (and SIGURG) in LLDB when debugging } // Critical section for thread cleanup diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 6f6e0c23a8..5223afe937 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -26,7 +26,9 @@ BufferCache

::BufferCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, R void(slot_buffers.insert(runtime, NullBufferParams{})); gpu_modified_ranges.Clear(); inline_buffer_id = NULL_BUFFER_ID; - +#ifdef YUZU_LEGACY + immediately_free = (Settings::values.vram_usage_mode.GetValue() == Settings::VramUsageMode::Aggressive); +#endif if (!runtime.CanReportMemoryUsage()) { minimum_memory = DEFAULT_EXPECTED_MEMORY; critical_memory = DEFAULT_CRITICAL_MEMORY; @@ -1378,6 +1380,10 @@ void BufferCache

::JoinOverlap(BufferId new_buffer_id, BufferId overlap_id, }); new_buffer.MarkUsage(copies[0].dst_offset, copies[0].size); runtime.CopyBuffer(new_buffer, overlap, copies, true); +#ifdef YUZU_LEGACY + if (immediately_free) + runtime.Finish(); +#endif DeleteBuffer(overlap_id, true); } @@ -1668,7 +1674,12 @@ void BufferCache

::DeleteBuffer(BufferId buffer_id, bool do_not_mark) { } Unregister(buffer_id); - delayed_destruction_ring.Push(std::move(slot_buffers[buffer_id])); + +#ifdef YUZU_LEGACY + if (!do_not_mark || !immediately_free) +#endif + delayed_destruction_ring.Push(std::move(slot_buffers[buffer_id])); + slot_buffers.erase(buffer_id); if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h index a45e9b35f1..486d19fb79 100644 --- a/src/video_core/buffer_cache/buffer_cache_base.h +++ b/src/video_core/buffer_cache/buffer_cache_base.h @@ -154,7 +154,11 @@ template class BufferCache : public VideoCommon::ChannelSetupCaches { // Page size for caching purposes. // This is unrelated to the CPU page size and it can be changed as it seems optimal. +#ifdef YUZU_LEGACY + static constexpr u32 CACHING_PAGEBITS = 12; +#else static constexpr u32 CACHING_PAGEBITS = 16; +#endif static constexpr u64 CACHING_PAGESIZE = u64{1} << CACHING_PAGEBITS; static constexpr bool IS_OPENGL = P::IS_OPENGL; @@ -168,9 +172,14 @@ class BufferCache : public VideoCommon::ChannelSetupCaches slot_buffers; - DelayedDestructionRing delayed_destruction_ring; +#ifdef YUZU_LEGACY + static constexpr size_t TICKS_TO_DESTROY = 6; +#else + static constexpr size_t TICKS_TO_DESTROY = 8; +#endif + DelayedDestructionRing delayed_destruction_ring; const Tegra::Engines::DrawManager::IndirectParams* current_draw_indirect{}; @@ -478,6 +492,9 @@ private: u64 minimum_memory = 0; u64 critical_memory = 0; BufferId inline_buffer_id; +#ifdef YUZU_LEGACY + bool immediately_free = false; +#endif std::array> CACHING_PAGEBITS)> page_table; Common::ScratchBuffer tmp_buffer; diff --git a/src/video_core/host1x/host1x.cpp b/src/video_core/host1x/host1x.cpp index 293bca6d79..cec5104144 100644 --- a/src/video_core/host1x/host1x.cpp +++ b/src/video_core/host1x/host1x.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -18,9 +21,15 @@ Host1x::~Host1x() = default; void Host1x::StartDevice(s32 fd, ChannelType type, u32 syncpt) { switch (type) { case ChannelType::NvDec: +#ifdef YUZU_LEGACY + std::call_once(nvdec_first_init, []() {std::this_thread::sleep_for(std::chrono::milliseconds{500});}); // HACK: For Astroneer +#endif devices[fd] = std::make_unique(*this, fd, syncpt, frame_queue); break; case ChannelType::VIC: +#ifdef YUZU_LEGACY + std::call_once(vic_first_init, []() {std::this_thread::sleep_for(std::chrono::milliseconds{500});}); // HACK: For Astroneer +#endif devices[fd] = std::make_unique(*this, fd, syncpt, frame_queue); break; default: diff --git a/src/video_core/host1x/host1x.h b/src/video_core/host1x/host1x.h index 8debac93dd..4eea214ec6 100644 --- a/src/video_core/host1x/host1x.h +++ b/src/video_core/host1x/host1x.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -201,6 +204,10 @@ private: std::unique_ptr> allocator; FrameQueue frame_queue; std::unordered_map> devices; +#ifdef YUZU_LEGACY + std::once_flag nvdec_first_init; + std::once_flag vic_first_init; +#endif }; } // namespace Tegra::Host1x diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index f7d22afde2..01a9a6a3f1 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h @@ -110,7 +110,12 @@ class TextureCache : public VideoCommon::ChannelSetupCaches::max)()}; +#ifdef YUZU_LEGACY + static constexpr s64 TARGET_THRESHOLD = 3_GiB; +#else static constexpr s64 TARGET_THRESHOLD = 4_GiB; +#endif + static constexpr s64 DEFAULT_EXPECTED_MEMORY = 1_GiB + 125_MiB; static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB + 625_MiB; static constexpr size_t GC_EMERGENCY_COUNTS = 2; @@ -479,7 +484,11 @@ private: }; Common::LeastRecentlyUsedCache lru_cache; + #ifdef YUZU_LEGACY + static constexpr size_t TICKS_TO_DESTROY = 6; + #else static constexpr size_t TICKS_TO_DESTROY = 8; +#endif DelayedDestructionRing sentenced_images; DelayedDestructionRing sentenced_image_view; DelayedDestructionRing sentenced_framebuffers; diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index f0309117bf..4cd3442d97 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -325,4 +325,6 @@ namespace Vulkan { return MemoryCommit(allocator, a, info); } + + } // namespace Vulkan From a52ddf78a6147e3fefd15be2fe60178d7dc07138 Mon Sep 17 00:00:00 2001 From: lizzie Date: Sun, 5 Oct 2025 05:42:59 +0200 Subject: [PATCH 05/24] [docs] add packaging status to README (#2658) Very surprising we are on repology already. Anyways this may help power users track which packages are outdated and whatnot wrt to others. Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2658 Reviewed-by: MaranBr Reviewed-by: crueter Co-authored-by: lizzie Co-committed-by: lizzie --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c78490e6d4..c5aa17ad1e 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,8 @@ A list of supported games will be available in future. Please be patient. Check out our [website](https://eden-emu.dev) for the latest news on exciting features, monthly progress reports, and more! +[![Packaging status](https://repology.org/badge/vertical-allrepos/eden-emulator.svg)](https://repology.org/project/eden-emulator/versions) + ## Development Most of the development happens on our Git server. It is also where [our central repository](https://git.eden-emu.dev/eden-emu/eden) is hosted. For development discussions, please join us on [Discord](https://discord.gg/kXAmGCXBGD) or [Revolt](https://rvlt.gg/qKgFEAbH). From f6d99e5032e8aeb55833c0b8edce01dc12297269 Mon Sep 17 00:00:00 2001 From: lizzie Date: Sun, 5 Oct 2025 20:44:48 +0200 Subject: [PATCH 06/24] [docs] initial user handbook draft (#2629) This is the initial draft of a "User Handbook", or FAQ. Currently contains useful info on the basics, graphics, and architecture/platform info. Archive.org OR archive.is should be used for linking external websites, especially since their content should not change. And most often than not, in a few years these could change. Signed-off-by: lizzie Co-authored-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2629 Reviewed-by: crueter Reviewed-by: CamilleLaVey Co-authored-by: lizzie Co-committed-by: lizzie --- docs/README.md | 2 +- docs/SIGNUP.md | 1 + docs/User.md | 15 ++--- docs/user/Architectures.md | 130 +++++++++++++++++++++++++++++++++++++ docs/user/Audio.md | 3 + docs/user/Basics.md | 57 ++++++++++++++++ docs/user/Graphics.md | 62 ++++++++++++++++++ 7 files changed, 261 insertions(+), 9 deletions(-) create mode 100644 docs/user/Architectures.md create mode 100644 docs/user/Audio.md create mode 100644 docs/user/Basics.md create mode 100644 docs/user/Graphics.md diff --git a/docs/README.md b/docs/README.md index 49617fa43a..686cfe8ea0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,4 +7,4 @@ This contains documentation created by developers. This contains build instructi - **[Dependencies](Deps.md)** - **[CPM - CMake Package Manager](CPMUtil.md)** - **[Platform-Specific Caveats](Caveats.md)** -- **[User Directory Handling](User.md)** \ No newline at end of file +- **[User Handbook](User.md)** \ No newline at end of file diff --git a/docs/SIGNUP.md b/docs/SIGNUP.md index f8cc315830..6995db6d9a 100644 --- a/docs/SIGNUP.md +++ b/docs/SIGNUP.md @@ -27,6 +27,7 @@ The following are not valid reasons to sign up: * To download and use Eden, see our [Releases page](https://github.com/eden-emulator/Releases/releases)! - I want to see the source code. * To see Eden's source code, go [here](https://git.eden-emu.dev/eden-emu/eden). + ## Other Information Requests that appear suspicious, automated, OR blank will generally be automatically filtered. In cases of suspicion, or any of the invalid reasons listed above, you may receive an email back asking for clarification. diff --git a/docs/User.md b/docs/User.md index cfc81063f8..ba5d1b3eb0 100644 --- a/docs/User.md +++ b/docs/User.md @@ -1,11 +1,10 @@ -# User configuration +# User Handbook -## Configuration directories +The "FAQ". -Eden will store configuration in the following directories: +This handbook is primarily aimed at the end-user - baking useful knowledge for enhancing their emulation experience. -- **Windows**: `%AppData%\Roaming`. -- **Android**: Data is stored internally. -- **Linux, macOS, FreeBSD, Solaris, OpenBSD**: `$XDG_DATA_HOME`, `$XDG_CACHE_HOME`, `$XDG_CONFIG_HOME`. - -If a `user` directory is present in the current working directory, that will override all global configuration directories and the emulator will use that instead. +- **[The Basics](user/Basics.md)** +- **[Audio](user/Audio.md)** +- **[Graphics](user/Graphics.md)** +- **[Platforms and Architectures](user/Architectures.md)** \ No newline at end of file diff --git a/docs/user/Architectures.md b/docs/user/Architectures.md new file mode 100644 index 0000000000..6d60716684 --- /dev/null +++ b/docs/user/Architectures.md @@ -0,0 +1,130 @@ +# User Handbook - Architectures and Platforms + +Notes and caveats for different architectures and platforms. + +# Architectures + +Eden is primarily designed to run on amd64 (x86_64--Intel/AMD 64-bit) and aarch64 (arm64--ARM 64-bit) CPUs. Each architecture tends to have their own quirks and fun stuff; this page serves as a reference for these quirks. + +## amd64 + +AMD64, aka x86_64, is the most tested and supported architecture for desktop targets. Android is entirely unsupported. + +### Caveats + +AMD64 systems are almost always limited by the CPU. For example, a Zen 5/RX 6600 system will often hit max CPU usage before the GPU ever reaches 70% usage, with minimal exceptions (that tend to pop up only at >200fps). JIT is slow! + +Computers on Linux will almost always run Eden strictly better than an equivalent machine on Windows. This is largely due to the way the Linux kernel handles memory management (and the lack of Microsoft spyware). + +Intel Macs are believed to be supported, but no CI is provided for them. Performance will likely be awful on all but the highest-end iMacs and Pro-level Macs, and the MoltenVK requirement generally means Vulkan compatibility will suffer. + +## aarch64 + +ARM64, aka aarch64, is the only supported architecture for Android, with limited experimental support available on Linux, Windows, and macOS. + +### Caveats + +NCE (Native Code Execution) is currently only available on Android and (experimentally) Linux. Support for macOS is in the works, but Windows is extremely unlikely to ever happen (if you want it--submit patches!). Generally, if NCE is available, you should pretty much always use it due to the massive performance hit JIT has. + +When NCE is enabled, do note that the GPU will almost always be the limiting factor. This is especially the case for Android, as well as desktops that lack dedicated GPUs; Adreno, Mali, PowerVR, etc. GPUs are generally significantly weaker relative to their respective CPUs. + +Windows/arm64 is *very* experimental and is unlikely to work at all. Support and testing is in the works. + +## riscv64 + +RISC-V, aka riscv64, is sparsely tested, but preliminary tests from developers have reported at least partial support on Milk-V's Fedora/riscv64 Linux distribution. Performance, Vulkan support, compatibility, and build system caveats are largely unknown for the time being. + +### Caveats + +Windows/riscv64 doesn't exist, and may never (until corporate greed no longer consumes Microsoft). + +Android/riscv64 is interesting. While support for it may be added if and when RISC-V phones/handhelds ever go mainstream, arm64 devices will always be preferred due to NCE. + +Only Fedora/riscv64 has been tested, but in theory, every riscv64 distribution that has *at least* the standard build tools, Qt, FFmpeg, and SDL2 should work. + +## Other + +Other architectures, such as SPARC, MIPS, PowerPC, Loong, and all 32-bit architectures are completely unsupported, as there is no JIT backend or emitter thereof. If you want support for it--submit patches! + +IA-64 (Itanium) support is completely unknown. Existing amd64 packages will not run on IA-64 (assuming you can even find a supported Windows/Linux distribution) + +# Platforms + +The vast majority of Eden's testing is done on Windows, Linux, and Android. However, first-class support is also provided for: + +- FreeBSD +- OpenBSD +- OpenIndiana (Solaris) +- macOS + +## Linux + +While all modern Linux distributions are supported (Fedora >40, Ubuntu >24.04, Debian >12, Arch, Gentoo, etc.), the vast majority of testing and development for Linux is on Arch and Gentoo. Most major build system changes are tested on Gentoo first and foremost, so if builds fail on any modern distribution no matter what you do, it's likely a bug and should be reported. + +Intel and Nvidia GPU support is limited. AMD (RADV) drivers receive first-class testing and are known to provide the most stable Eden experience possible. + +## Windows + +Windows 10 and 11 are supported. Support for Windows 8.x is unknown, and Windows 7 support is unlikely to ever be added. + +In order to run Eden, you will probably need to install the [Visual C++ Redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170). + +Neither AMD nor Nvidia drivers work nearly as well as Linux's RADV drivers. Compatibility is still largely the same, but performance and some hard-to-run games may suffer compared to Linux. + +## Android + +A cooler is always recommended. Phone SoCs tend to get very hot, especially those manufactured with the Samsung process or those lacking in power. + +Adreno 6xx and 7xx GPUs with Turnip drivers will always have the best compatibility. "Stock" (system) drivers will have better performance on Adreno, but compatibility will suffer. Better support for stock drivers (including Adreno 8xx) is in the works. + +Android 16 is always recommended, as it brought major improvements to Vulkan requirements and compatibility, *plus* significant performance gains. Some users reported an over 50% performance gain on some Pixel phones after updating. + +Mali, PowerVR, Xclipse, and other GPU vendors generally lack in performance and compatibility. Notably: +- No PowerVR GPUs *except* the DXT-48-1536 are known to work with Eden at all. +- No Xclipse GPUs *except* the very latest (e.g. Xclipse 950) are known to work with Eden at all. +- Mali has especially bad performance, though the Mali-G715 (Tensor G4) and Immortalis-G925 are known to generally run surprisingly well, especially on Android 16. +- The status of all other GPU vendors is unknown. As long as they support Vulkan, they theoretically can run Eden. +- Note that these GPUs generally don't play well with driver injection. If you choose to inject custom drivers via a rooted system (Panfrost, RADV, etc), you may see good results. + +Qualcomm Snapdragon SoCs are generally the most well supported. +- Google Tensor chips have pretty terrible performance, but even the G1 has been proven to be able to run some games well on the Pixel 6 Pro. + * The Tensor G4 is the best-supported at the time. How the G5 currently fares is unknown, but on paper, it should do about as well as a Snapdragon 8 Gen 2 with stock drivers. +- Samsung Exynos chips made before 2022 are not supported. +- MediaTek Dimensity chips are extremely weak and most before mid-2023 don't work at all. + * This means that most budget phones won't work, as they tend to use old MediaTek SoCs. + * Generally, if your phone doesn't cost *at least* as much as a Switch itself, it will not *emulate* the Switch very well. +- Snapdragon 865 and other old-ish SoCs may benefit from the Legacy build. These will reduce performance but *should* drastically improve compatibility. +- If you're not sure how powerful your SoC is, check [NanoReview](https://nanoreview.net/en/soc-compare) - e.g. [Tensor G5](https://archive.is/ylC4Z). + * A good base to compare to is the Snapdragon 865--e.g. [Tensor vs SD865](https://archive.is/M1P58) + * Some benchmarks may be misleading due to thermal throttling OR RAM requirements. + - For example, a Pixel 6a (Tensor G1) performs about 1/3 as well as an 865 due to its lack of RAM and poor thermals. + * Remember--always use a cooler if you can, and you MUST have *at least* 8GB of RAM! +- If you're not sure what SoC you have, check [GSMArena](https://www.gsmarena.com) - e.g. [Pixel 9 Pro](https://archive.ph/91VhA) + +Custom ROMs are recommended, *as long as* you know what you're doing. +- For most devices, [LineageOS](https://lineageos.org/) is preferred. +- [CalyxOS](https://calyxos.org/) is available as well. +- For Google Pixel devices ONLY... and [soon another OEM](https://archive.ph/cPpMd)... [GrapheneOS](https://grapheneos.org/) is highly recommended. + * As of October 5, 2025, the Pixel 10 line is unsupported, however, [it will be](https://archive.is/viAUl) in the very near future! + * Keep checking the [FAQ page](https://grapheneos.org/faq#supported-devices) for news. +- Custom ROMs will likely be exclusively recommended in the future due to Google's upcoming [draconian](https://archive.is/hGIjZ), [anti-privacy, anti-user](https://archive.is/mc1CJ) verification requirements. + +Eden is currently unavailable on F-Droid or the Play Store. Check back occasionally. + +## macOS + +macOS is relatively stable, with only the occasional crash and bug. Compatibility may suffer due to the MoltenVK layer, however. + +Do note that building the GUI version with Qt versions higher than 6.7.3 will cause mysterious bugs, Vulkan errors, and crashes, alongside the cool feature of freezing the entire system UI randomly; we recommend you build with 6.7.3 (via aqtinstall) or earlier as the CI does. + +## *BSD, Solaris + +BSD and Solaris distributions tend to lag behind Linux in terms of Vulkan and other library compatibility. For example, OpenIndiana (Solaris) does not properly package Qt, meaning the recommended method of usage is to use `eden-cli` only for now. Solaris also generally works better with OpenGL. + +AMD GPU support on these platforms is limited or nonexistent. + +## VMs + +Eden "can" run in a VM, but only with the software renderer, *unless* you create a hardware-accelerated KVM with GPU passthrough. If you *really* want to do this and don't have a spare GPU lying around, RX 570 and 580 GPUs are extremely cheap on the black market and are powerful enough to run most commercial games at 60fps. + +Some users and developers have had success using a pure OpenGL-accelerated KVM on Linux with a Windows VM, but this is ridiculously tedious to set up. You're probably better off dual-booting. \ No newline at end of file diff --git a/docs/user/Audio.md b/docs/user/Audio.md new file mode 100644 index 0000000000..38a4ead433 --- /dev/null +++ b/docs/user/Audio.md @@ -0,0 +1,3 @@ +# User Handbook - Audio + +`PULSE_SERVER=none` forces cubeb to use ALSA. diff --git a/docs/user/Basics.md b/docs/user/Basics.md new file mode 100644 index 0000000000..5751c6a6a3 --- /dev/null +++ b/docs/user/Basics.md @@ -0,0 +1,57 @@ +# User Handbook - The Basics + +## Introduction + +Eden is a very complicated piece of software, and as such there are many knobs and toggles that can be configured. Most of these are invisible to normal users, however power users may be able to leverage them to their advantage. + +This handbook primarily describes such knobs and toggles. Normal configuration options are described within the emulator itself and will not be covered in detail. + +## Requirements + +The emulator is very demanding on hardware, and as such requires a decent mid-range computer/cellphone. + +See [the requirements page](https://archive.is/sv83h) for recommended and minimum specs. + +The CPU must support FMA for an optimal gameplay experience. The GPU needs to support OpenGL 4.6 ([compatibility list](https://opengl.gpuinfo.org/)), or Vulkan 1.1 ([compatibility list](https://vulkan.gpuinfo.org/)). + +If your GPU doesn't support or is just behind by a minor version, see Mesa environment variables below (*nix only). + +## User configuration + +### Configuration directories + +Eden will store configuration files in the following directories: + +- **Windows**: `%AppData%\Roaming`. +- **Android**: Data is stored internally. +- **Linux, macOS, FreeBSD, Solaris, OpenBSD**: `$XDG_DATA_HOME`, `$XDG_CACHE_HOME`, `$XDG_CONFIG_HOME`. + +If a `user` directory is present in the current working directory, that will override all global configuration directories and the emulator will use that instead. + +### Environment variables + +Throughout the handbook, environment variables are mentioned. These are often either global (system wide) or local (set in a script, bound only to the current session). It's heavily recommended to use them in a local context only, as this allows you to rollback changes easily (if for example, there are regressions setting them). + +The recommended way is to create a `.bat` file alongside the emulator `.exe`; contents of which could resemble something like: + +```bat +set "__GL_THREADED_OPTIMIZATIONS=1" +set "SOME_OTHER_VAR=1" +eden.exe +``` + +Android doesn't have a convenient way to set environment variables. + +For other platforms, the recommended method is using a shell script: + +```sh +export __GL_THREADED_OPTIMIZATIONS=1 +export SOME_OTHER_VAR=1 +./eden +``` + +Then just running `chmod +x script.sh && source script.sh`. + +## Compatibility list + +Eden doesn't mantain a compatibility list. However, [EmuReady](https://www.emuready.com/) has a more fine-grained compatibility information for multiple emulators/forks as well. diff --git a/docs/user/Graphics.md b/docs/user/Graphics.md new file mode 100644 index 0000000000..1b4c0dc4c3 --- /dev/null +++ b/docs/user/Graphics.md @@ -0,0 +1,62 @@ +# User Handbook - Graphics + +## Visual Enhancements + +### Anti-aliasing + +Enhancements aimed at removing jagged lines/sharp edges and/or masking artifacts. + +- **No AA**: Default, provides no anti-aliasing. +- **FXAA**: Fast Anti-Aliasing, an implementation as described on [this blog post](https://web.archive.org/web/20110831051323/http://timothylottes.blogspot.com/2011/03/nvidia-fxaa.html). Generally fast but with some innocuos artifacts. +- **SMAA**: Subpixel Morphological Anti-Aliasing, an implementation as described on [this article](https://web.archive.org/web/20250000000000*/https://www.iryoku.com/smaa/). + +### Filters + +Various graphical filters exist - each of them aimed at a specific target/image quality preset. + +- **Nearest**: Provides no filtering - useful for debugging. + - **Pros**: Fast, works in any hardware. + - **Cons**: Less image quality. +- **Bilinear**: Provides the hardware default filtering of the Tegra X1. + - **Pros**: Fast with acceptable image quality. +- **Bicubic**: Provides a bicubic interpolation using a Catmull-Rom (or hardware-accelerated) implementation. + - **Pros**: Better image quality with more rounded edges. +- **Zero-Tangent, B-Spline, Mitchell**: Provides bicubic interpolation using the respective matrix weights. They're normally not hardware accelerated unless the device supports the `VK_QCOM_filter_cubic_weights` extension. The matrix weights are those matching [the specification itself](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#VkSamplerCubicWeightsCreateInfoQCOM). + - **Pros/Cons**: Each of them is a variation of the Bicubic interpolation model with different weights, they offer different methods to fix some artifacts present in Catmull-Rom. +- **Spline-1**: Bicubic interpolation (similar to Mitchell) but with a faster texel fetch method. Generally less blurry than bicubic. + - **Pros**: Faster than bicubic even without hardware accelerated bicubic. +- **Gaussian**: Whole-area blur, an applied gaussian blur is done to the entire frame. + - **Pros**: Less edge artifacts. + - **Cons**: Slow and sometimes blurry. +- **Lanczos**: An implementation using `a = 3` (49 texel fetches). Provides sharper edges but blurrier artifacts. + - **Pros**: Less edge artifacts and less blurry than gaussian. + - **Cons**: Slow. +- **ScaleForce**: Experimental texture upscale method, see [ScaleFish](https://github.com/BreadFish64/ScaleFish). + - **Pros**: Relatively fast. +- **FSR**: Uses AMD FidelityFX Super Resolution to enhance image quality. + - **Pros**: Great for upscaling, and offers sharper visual quality. + - **Cons**: Somewhat slow, and may be offputtingly sharp. +- **Area**: Area interpolation (high kernel count). + - **Pros**: Best for downscaling (internal resolution > display resolution). + - **Cons**: Costly and slow. +- **MMPX**: Nearest-neighbour filter aimed at providing higher pixel-art quality. + - **Pros**: Offers decent pixel-art upscaling. + - **Cons**: Only works for pixel-art. + +### External + +While stock shaders offer a basic subset of options for most users, programs such as [ReShade](https://github.com/crosire/reshade) offer a more flexible experience. In addition to that users can also seek out modifications (mods) for enhancing visual experience (60 FPS mods, HDR, etc). + +## Driver specifics + +### Mesa environment variable hacks + +The software requires a certain version of Vulkan and a certain version of OpenGL to work - otherwise it will refuse to load, this can be easily bypassed by setting an environment variable: `MESA_GL_VERSION_OVERRIDE=4.6 MESA_GLSL_VERSION_OVERRIDE=460` (OpenGL) and `MESA_VK_VERSION_OVERRIDE=1.3` (Vulkan), for more information see [Environment variables for Mesa](https://web.archive.org/web/20250000000000*/https://docs.mesa3d.org/envvars.html). + +### NVIDIA OpenGL environment variables + +Unstable multithreaded optimisations are offered by the stock proprietary NVIDIA driver on X11 platforms. Setting `__GL_THREADED_OPTIMIZATIONS` to `1` would enable such optimisations. This mainly benefits the OpenGL backend. For more information see [Environment Variables for X11 NVIDIA](https://web.archive.org/web/20250115162518/https://download.nvidia.com/XFree86/Linux-x86_64/435.17/README/openglenvvariables.html). + +### swrast/LLVMpipe crashes under high load + +The OpenGL backend would invoke behaviour that would result in swarst/LLVMpipe writing an invalid SSA IR (on old versions of Mesa), and then proceeding to crash. The solution is using a script found in [tools/llvmpipe-run.sh](../../tools/llvmpipe-run.sh). From bc1d093fe9e5ee4ddee02e3beb43480f5ee2ead9 Mon Sep 17 00:00:00 2001 From: Aleksandr Popovich Date: Mon, 6 Oct 2025 03:08:00 +0200 Subject: [PATCH 07/24] [frontend] add 1.25x resolution option (#2566) It sits at 900p or 1350p. Signed-off-by: Aleksandr Popovich Co-authored-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2566 Reviewed-by: MaranBr Reviewed-by: crueter Co-authored-by: Aleksandr Popovich Co-committed-by: Aleksandr Popovich --- src/android/app/src/main/res/values/arrays.xml | 2 ++ src/android/app/src/main/res/values/strings.xml | 1 + src/common/settings.cpp | 4 ++++ src/common/settings_enums.h | 2 +- src/qt_common/shared_translation.cpp | 1 + 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index 1b66c191d3..ec94730348 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -180,6 +180,7 @@ @string/resolution_half @string/resolution_three_quarter @string/resolution_one + @string/resolution_five_quarter @string/resolution_three_half @string/resolution_two @string/resolution_three @@ -202,6 +203,7 @@ 5 6 7 + 8 diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 2a5cc48bb1..2f6587d136 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -996,6 +996,7 @@ 0.5X (360p/540p) 0.75X (540p/810p) 1X (720p/1080p) + 1.25X (900p/1350p) 1.5X (1080p/1620p) 2X (1440p/2160p) (Slow) 3X (2160p/3240p) (Slow) diff --git a/src/common/settings.cpp b/src/common/settings.cpp index b41f4c75f5..b849d7cb6a 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -301,6 +301,10 @@ void TranslateResolutionInfo(ResolutionSetup setup, ResolutionScalingInfo& info) info.up_scale = 3; info.down_shift = 1; break; + case ResolutionSetup::Res5_4X: + info.up_scale = 5; + info.down_shift = 2; + break; case ResolutionSetup::Res2X: info.up_scale = 2; info.down_shift = 0; diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index 0e5a08d845..6644bc01cc 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -142,7 +142,7 @@ ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb) ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never); ENUM(FullscreenMode, Borderless, Exclusive); ENUM(NvdecEmulation, Off, Cpu, Gpu); -ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, Res8X); +ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res5_4X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, Res8X); ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, MaxEnum); ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum); ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch); diff --git a/src/qt_common/shared_translation.cpp b/src/qt_common/shared_translation.cpp index 8f5d929b74..5b8622e00a 100644 --- a/src/qt_common/shared_translation.cpp +++ b/src/qt_common/shared_translation.cpp @@ -540,6 +540,7 @@ std::unique_ptr ComboboxEnumeration(QObject* parent) PAIR(ResolutionSetup, Res1_2X, tr("0.5X (360p/540p) [EXPERIMENTAL]")), PAIR(ResolutionSetup, Res3_4X, tr("0.75X (540p/810p) [EXPERIMENTAL]")), PAIR(ResolutionSetup, Res1X, tr("1X (720p/1080p)")), + PAIR(ResolutionSetup, Res5_4X, tr("1.25X (900p/1350p) [EXPERIMENTAL]")), PAIR(ResolutionSetup, Res3_2X, tr("1.5X (1080p/1620p) [EXPERIMENTAL]")), PAIR(ResolutionSetup, Res2X, tr("2X (1440p/2160p)")), PAIR(ResolutionSetup, Res3X, tr("3X (2160p/3240p)")), From 5d4cfe195b9d221a0b7c7195dd0fd0f8d38b1838 Mon Sep 17 00:00:00 2001 From: Ribbit Date: Mon, 6 Oct 2025 17:39:32 +0200 Subject: [PATCH 08/24] [vk] Fix Vulkan Upload & Present Barriers for Spec Compliance (#2681) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The barrier before the CPU-upload copy was using VK_PIPELINE_STAGE_HOST_BIT. Validation rules only allow HOST as the source stage if you’re also specifying host-side access flags; inside a command buffer the GPU isn’t executing “host work,” so pairing that stage with the usual image layout transition is technically invalid. Switching the source stage to VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT keeps the ordering guarantee we need and satisfies the spec, while the actual host visibility is still handled correctly by the preceding vmaFlushAllocation. Co-authored-by: Ribbit Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2681 Reviewed-by: MaranBr Reviewed-by: Shinmegumi Co-authored-by: Ribbit Co-committed-by: Ribbit --- src/video_core/renderer_vulkan/present/layer.cpp | 2 +- src/video_core/renderer_vulkan/vk_present_manager.cpp | 4 ++-- src/video_core/renderer_vulkan/vk_texture_cache.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video_core/renderer_vulkan/present/layer.cpp b/src/video_core/renderer_vulkan/present/layer.cpp index 5676dfe62a..fee19a69c2 100644 --- a/src/video_core/renderer_vulkan/present/layer.cpp +++ b/src/video_core/renderer_vulkan/present/layer.cpp @@ -332,7 +332,7 @@ void Layer::UpdateRawImage(const Tegra::FramebufferConfig& framebuffer, size_t i write_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; write_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, read_barrier); cmdbuf.CopyBufferToImage(*buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, copy); cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp index 0b29ad1389..161f6c8b9f 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp @@ -412,7 +412,7 @@ void PresentManager::CopyToSwapchainImpl(Frame* frame) { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .pNext = nullptr, .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT, + .dstAccessMask = 0, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, @@ -460,7 +460,7 @@ void PresentManager::CopyToSwapchainImpl(Frame* frame) { MakeImageCopy(frame->width, frame->height, extent.width, extent.height)); } - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, {}, + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, {}, {}, {}, post_barriers); cmdbuf.End(); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 575651905e..50a73ea76d 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1068,7 +1068,7 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src, cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, READ_BARRIER, {}, middle_out_barrier); - cmdbuf.CopyBufferToImage(copy_buffer, dst_image, VK_IMAGE_LAYOUT_GENERAL, vk_out_copies); + cmdbuf.CopyBufferToImage(copy_buffer, dst_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk_out_copies); cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, {}, {}, post_barriers); }); From 6a4fa11ac3ad837caac5f6c305641f57fe4ecf73 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 7 Oct 2025 01:31:36 +0200 Subject: [PATCH 09/24] [externals] only build spirv-tools as static (#2680) Upstream forcefully builds the shared lib and also builds shared and static separately for... some reason. I made a PR that fixes that, so for now let's use it here should speed up build on Android and Windows Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2680 Reviewed-by: CamilleLaVey Reviewed-by: MaranBr --- .ci/android/build.sh | 4 ++-- externals/cpmfile.json | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.ci/android/build.sh b/.ci/android/build.sh index 4b4c9c0834..836faa38d5 100755 --- a/.ci/android/build.sh +++ b/.ci/android/build.sh @@ -13,8 +13,8 @@ fi cd src/android chmod +x ./gradlew -./gradlew assembleRelease -./gradlew bundleRelease +./gradlew assembleMainlineRelease +./gradlew bundleMainlineRelease if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then rm "${ANDROID_KEYSTORE_FILE}" diff --git a/externals/cpmfile.json b/externals/cpmfile.json index aa3a97c128..dde8c22d5f 100644 --- a/externals/cpmfile.json +++ b/externals/cpmfile.json @@ -117,9 +117,9 @@ }, "spirv-tools": { "package": "SPIRV-Tools", - "repo": "KhronosGroup/SPIRV-Tools", - "tag": "v%VERSION%", - "hash": "b17940433ced72e004c5eeffd7dd411b6afcc6a52ee31de6427d88edceb8172369be8ec8bf5b65708a78bf41fdae264d554aa7750b2209831679ab36bc867567", + "repo": "crueter/SPIRV-Tools", + "sha": "2fa2d44485", + "hash": "45b198be1d09974ccb2438e8bfa5683f23a0421b058297c28eacfd77e454ec2cf87e77850eddd202efff34b004d8d6b4d12e9615e59bd72be904c196f5eb2169", "git_version": "2025.4", "options": [ "SPIRV_SKIP_EXECUTABLES ON" From badd913bee87bde630e1e4d4c6182b027ed0830f Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 7 Oct 2025 01:32:09 +0200 Subject: [PATCH 10/24] [desktop] fix save data location, orphaned profiles finder (#2678) Previously, if the user had their NAND in a nonstandard location, profiles.dat would be read from the standard Eden path and thus return effectively garbage data. What this would result in is: - The Qt profile manager would be completely nonfunctional - "Open Save Data Location" would put you into the completely wrong place - Games would read from incorrect locations for their saves To solve this, I made it so that profiles.dat is re-read *after* QtConfig initializes. It's not the perfect solution, but it works. Additionally, this adds an orphaned profiles finder: - walks through the save folders in nand/user/save/000.../ - for each subdirectory, checks to see if profiles.dat contains a corresponding UUID - If not, the profile is "orphaned". It may contain legit save data, so let the user decide how to handle it (famous last words) - Empty profiles are just removed. If they really matter, they're instantly recreated anyways. The orphaned profiles check runs right *after* the decryption keys check, but before the game list ever gets populated Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2678 Reviewed-by: CamilleLaVey Reviewed-by: MaranBr --- docs/user/Architectures.md | 2 + src/common/fs/fs_types.h | 4 + src/core/file_sys/savedata_factory.cpp | 5 -- src/core/hle/service/acc/profile_manager.cpp | 92 +++++++++++++++++++- src/core/hle/service/acc/profile_manager.h | 5 ++ src/qt_common/qt_content_util.cpp | 38 ++++++++ src/qt_common/qt_content_util.h | 3 + src/qt_common/qt_game_util.cpp | 15 ++-- src/qt_common/qt_game_util.h | 3 +- src/yuzu/main.cpp | 5 +- src/yuzu/migration_worker.cpp | 1 - 11 files changed, 156 insertions(+), 17 deletions(-) diff --git a/docs/user/Architectures.md b/docs/user/Architectures.md index 6d60716684..240feb666d 100644 --- a/docs/user/Architectures.md +++ b/docs/user/Architectures.md @@ -63,6 +63,8 @@ While all modern Linux distributions are supported (Fedora >40, Ubuntu >24.04, D Intel and Nvidia GPU support is limited. AMD (RADV) drivers receive first-class testing and are known to provide the most stable Eden experience possible. +Wayland is not recommended. Testing has shown significantly worse performance on most Wayland compositors compared to X11, alongside mysterious bugs and compatibility errors. For now, set `QT_QPA_PLATFORM=xcb` when running Eden, or pass `-platform xcb` to the launch arguments. + ## Windows Windows 10 and 11 are supported. Support for Windows 8.x is unknown, and Windows 7 support is unlikely to ever be added. diff --git a/src/common/fs/fs_types.h b/src/common/fs/fs_types.h index 900f85d24e..7b7359fa6f 100644 --- a/src/common/fs/fs_types.h +++ b/src/common/fs/fs_types.h @@ -1,8 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once +#include #include #include "common/common_funcs.h" diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index edf51e74de..dda8d526d3 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -4,7 +4,6 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include #include "common/assert.h" #include "common/common_types.h" #include "common/logging/log.h" @@ -129,10 +128,6 @@ std::string SaveDataFactory::GetFullPath(ProgramId program_id, VirtualDir dir, std::string out = GetSaveDataSpaceIdPath(space); - LOG_INFO(Common_Filesystem, "Save ID: {:016X}", save_id); - LOG_INFO(Common_Filesystem, "User ID[1]: {:016X}", user_id[1]); - LOG_INFO(Common_Filesystem, "User ID[0]: {:016X}", user_id[0]); - switch (type) { case SaveDataType::System: return fmt::format("{}save/{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]); diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index a4394046fa..4a892f7c65 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -4,13 +4,17 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include #include +#include +#include #include #include #include "common/fs/file.h" #include "common/fs/fs.h" +#include "common/fs/fs_types.h" #include "common/fs/path_util.h" #include #include "common/settings.h" @@ -90,6 +94,11 @@ bool ProfileManager::RemoveProfileAtIndex(std::size_t index) { return true; } +void ProfileManager::RemoveAllProfiles() +{ + profiles = {}; +} + /// Helper function to register a user to the system Result ProfileManager::AddUser(const ProfileInfo& user) { if (!AddToProfiles(user)) { @@ -259,8 +268,9 @@ void ProfileManager::CloseUser(UUID uuid) { /// Gets all valid user ids on the system UserIDArray ProfileManager::GetAllUsers() const { UserIDArray output{}; - std::ranges::transform(profiles, output.begin(), - [](const ProfileInfo& p) { return p.user_uuid; }); + std::ranges::transform(profiles, output.begin(), [](const ProfileInfo& p) { + return p.user_uuid; + }); return output; } @@ -387,18 +397,19 @@ bool ProfileManager::SetProfileBaseAndData(Common::UUID uuid, const ProfileBase& void ProfileManager::ParseUserSaveFile() { const auto save_path(FS::GetEdenPath(FS::EdenPath::NANDDir) / ACC_SAVE_AVATORS_BASE_PATH / "profiles.dat"); + const FS::IOFile save(save_path, FS::FileAccessMode::Read, FS::FileType::BinaryFile); if (!save.IsOpen()) { LOG_WARNING(Service_ACC, "Failed to load profile data from save data... Generating new " - "user 'eden' with random UUID."); + "user 'Eden' with random UUID."); return; } ProfileDataRaw data; if (!save.ReadObject(data)) { LOG_WARNING(Service_ACC, "profiles.dat is smaller than expected... Generating new user " - "'eden' with random UUID."); + "'Eden' with random UUID."); return; } @@ -471,6 +482,79 @@ void ProfileManager::WriteUserSaveFile() { is_save_needed = false; } +void ProfileManager::ResetUserSaveFile() +{ + RemoveAllProfiles(); + ParseUserSaveFile(); +} + +std::vector ProfileManager::FindOrphanedProfiles() +{ + std::vector good_uuids; + + for (const ProfileInfo& p : profiles) { + std::string uuid_string = [p]() -> std::string { + auto uuid = p.user_uuid; + + // "ignore" invalid uuids + if (uuid.IsInvalid()) { + return "0"; + } + + auto user_id = uuid.AsU128(); + + return fmt::format("{:016X}{:016X}", user_id[1], user_id[0]); + }(); + + good_uuids.emplace_back(uuid_string); + } + + // TODO: fetch save_id programmatically + const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) + / "user/save/0000000000000000"; + + std::vector orphaned_profiles; + + Common::FS::IterateDirEntries( + path, + [&good_uuids, &orphaned_profiles](const std::filesystem::directory_entry& entry) -> bool { + const std::string uuid = entry.path().stem().string(); + + // first off, we should always clear empty profiles + // 99% of the time these are useless. If not, they are recreated anyways... + namespace fs = std::filesystem; + + const auto is_empty = [&entry]() -> bool { + try { + for (const auto& file : fs::recursive_directory_iterator(entry.path())) { + if (file.is_regular_file()) { + return true; + } + } + } catch (const fs::filesystem_error& e) { + // if we get an error--no worries, just pretend it's not empty + return false; + } + return false; + }(); + + if (!is_empty) { + fs::remove_all(entry); + return true; + } + + // if profiles.dat contains the UUID--all good + // if not--it's an orphaned profile and should be resolved by the user + if (std::find(good_uuids.begin(), good_uuids.end(), uuid) == good_uuids.end()) { + orphaned_profiles.emplace_back(uuid); + } + return true; + }, + Common::FS::DirEntryFilter::Directory); + + return orphaned_profiles; +} + void ProfileManager::SetUserPosition(u64 position, Common::UUID uuid) { auto idxOpt = GetUserIndex(uuid); if (!idxOpt) diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index d64e42715c..b164ed011a 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -103,10 +103,15 @@ public: void WriteUserSaveFile(); + void ResetUserSaveFile(); + + std::vector FindOrphanedProfiles(); + private: void ParseUserSaveFile(); std::optional AddToProfiles(const ProfileInfo& profile); bool RemoveProfileAtIndex(std::size_t index); + void RemoveAllProfiles(); bool is_save_needed{}; std::array profiles{}; diff --git a/src/qt_common/qt_content_util.cpp b/src/qt_common/qt_content_util.cpp index e4625aa423..2f659cf1b2 100644 --- a/src/qt_common/qt_content_util.cpp +++ b/src/qt_common/qt_content_util.cpp @@ -1,8 +1,10 @@ // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +#include "qt_common/qt_game_util.h" #include "qt_content_util.h" #include "common/fs/fs.h" +#include "core/hle/service/acc/profile_manager.h" #include "frontend_common/content_manager.h" #include "frontend_common/firmware_manager.h" #include "qt_common/qt_common.h" @@ -310,4 +312,40 @@ void VerifyInstalledContents() { } } +void FixProfiles() +{ + // Reset user save files after config is initialized and migration is done. + // Doing it at init time causes profiles to read from the wrong place entirely if NAND dir is not default + // TODO: better solution + system->GetProfileManager().ResetUserSaveFile(); + std::vector orphaned = system->GetProfileManager().FindOrphanedProfiles(); + + // no orphaned dirs--all good :) + if (orphaned.empty()) + return; + + // otherwise, let the user know + QString qorphaned; + + // max. of 8 orphaned profiles is fair, I think + // 33 = 32 (UUID) + 1 (\n) + qorphaned.reserve(8 * 33); + + for (const std::string& s : orphaned) { + qorphaned += "\n" + QString::fromStdString(s); + } + + QtCommon::Frontend::Critical( + tr("Orphaned Profiles Detected!"), + tr("UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!\n" + "Eden has detected the following save directories with no attached profile:\n" + "%1\n\n" + "Click \"OK\" to open your save folder and fix up your profiles.\n" + "Hint: copy the contents of the largest or last-modified folder elsewhere, " + "delete all orphaned profiles, and move your copied contents to the good profile.") + .arg(qorphaned)); + + QtCommon::Game::OpenSaveFolder(); +} + } // namespace QtCommon::Content diff --git a/src/qt_common/qt_content_util.h b/src/qt_common/qt_content_util.h index b572c1c4a3..b95e78c0a0 100644 --- a/src/qt_common/qt_content_util.h +++ b/src/qt_common/qt_content_util.h @@ -45,5 +45,8 @@ void InstallKeys(); // Content // void VerifyGameContents(const std::string &game_path); void VerifyInstalledContents(); + +// Profiles // +void FixProfiles(); } #endif // QT_CONTENT_UTIL_H diff --git a/src/qt_common/qt_game_util.cpp b/src/qt_common/qt_game_util.cpp index 5d0b4d8ae7..ac922ea967 100644 --- a/src/qt_common/qt_game_util.cpp +++ b/src/qt_common/qt_game_util.cpp @@ -178,6 +178,12 @@ void OpenNANDFolder() OpenEdenFolder(Common::FS::EdenPath::NANDDir); } +void OpenSaveFolder() +{ + const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "user/save/0000000000000000"; + QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(path.string()))); +} + void OpenSDMCFolder() { OpenEdenFolder(Common::FS::EdenPath::SDMCDir); @@ -379,21 +385,21 @@ void RemoveCacheStorage(u64 program_id) } // Metadata // -void ResetMetadata() +void ResetMetadata(bool show_message) { const QString title = tr("Reset Metadata Cache"); if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list/")) { - QtCommon::Frontend::Warning(rootObject, title, tr("The metadata cache is already empty.")); + if (show_message) QtCommon::Frontend::Warning(rootObject, title, tr("The metadata cache is already empty.")); } else if (Common::FS::RemoveDirRecursively( Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) { - QtCommon::Frontend::Information(rootObject, + if (show_message) QtCommon::Frontend::Information(rootObject, title, tr("The operation completed successfully.")); UISettings::values.is_game_list_reload_pending.exchange(true); } else { - QtCommon::Frontend::Warning( + if (show_message) QtCommon::Frontend::Warning( rootObject, title, tr("The metadata cache couldn't be deleted. It might be in use or non-existent.")); @@ -573,5 +579,4 @@ void CreateHomeMenuShortcut(ShortcutTarget target) { CreateShortcut(game_path, QLaunchId, "Switch Home Menu", target, "-qlaunch", false); } - } // namespace QtCommon::Game diff --git a/src/qt_common/qt_game_util.h b/src/qt_common/qt_game_util.h index 0a21208659..5c6bb24910 100644 --- a/src/qt_common/qt_game_util.h +++ b/src/qt_common/qt_game_util.h @@ -52,6 +52,7 @@ bool MakeShortcutIcoPath(const u64 program_id, void OpenEdenFolder(const Common::FS::EdenPath &path); void OpenRootDataFolder(); void OpenNANDFolder(); +void OpenSaveFolder(); void OpenSDMCFolder(); void OpenModFolder(); void OpenLogFolder(); @@ -67,7 +68,7 @@ void RemoveCustomConfiguration(u64 program_id, const std::string& game_path); void RemoveCacheStorage(u64 program_id); // Metadata // -void ResetMetadata(); +void ResetMetadata(bool show_message = true); // Shortcuts // void CreateShortcut(const std::string& game_path, diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 901a39cc9f..44ed29f141 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -545,6 +545,9 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) // Gen keys if necessary OnCheckFirmwareDecryption(); + // Check for orphaned profiles and reset profile data if necessary + QtCommon::Content::FixProfiles(); + game_list->LoadCompatibilityList(); // force reload on first load to ensure add-ons get updated game_list->PopulateAsync(UISettings::values.game_dirs); @@ -3947,7 +3950,7 @@ void GMainWindow::OnToggleStatusBar() { void GMainWindow::OnGameListRefresh() { // Resets metadata cache and reloads - QtCommon::Game::ResetMetadata(); + QtCommon::Game::ResetMetadata(false); game_list->RefreshGameDirectory(); SetFirmwareVersion(); } diff --git a/src/yuzu/migration_worker.cpp b/src/yuzu/migration_worker.cpp index 42ec006026..95f205ec0c 100644 --- a/src/yuzu/migration_worker.cpp +++ b/src/yuzu/migration_worker.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include "common/fs/path_util.h" From 62369aa2d5cfd55da00a4174d5bffdf367f31eea Mon Sep 17 00:00:00 2001 From: Ribbit Date: Tue, 7 Oct 2025 03:26:54 +0200 Subject: [PATCH 11/24] [vk] StreamBuffer Changes (#2684) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tighter ring allocation + sync tracking with correct wrap/no-wrap, alignment, and per-range sync_ticks; update head/tail only when needed (wrap to 0 if tail won’t fit). Adds safer sizing under debug tools by preferring device-local host-visible heaps with fallback. Expected result: fewer stalls, steadier reuse, higher upload throughput. Co-authored-by: Ribbit Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2684 Reviewed-by: MaranBr Reviewed-by: Lizzie Reviewed-by: CamilleLaVey Co-authored-by: Ribbit Co-committed-by: Ribbit --- .../vk_staging_buffer_pool.cpp | 60 ++++++++++++++----- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp index 08513d1534..ecc4f77dc7 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp @@ -33,19 +33,29 @@ constexpr VkDeviceSize MAX_STREAM_BUFFER_SIZE = 128_MiB; size_t GetStreamBufferSize(const Device& device) { VkDeviceSize size{0}; if (device.HasDebuggingToolAttached()) { - ForEachDeviceLocalHostVisibleHeap(device, [&size](size_t index, VkMemoryHeap& heap) { + bool found_heap = false; + ForEachDeviceLocalHostVisibleHeap(device, [&size, &found_heap](size_t /*index*/, VkMemoryHeap& heap) { size = (std::max)(size, heap.size); + found_heap = true; }); - // If rebar is not supported, cut the max heap size to 40%. This will allow 2 captures to be - // loaded at the same time in RenderDoc. If rebar is supported, this shouldn't be an issue - // as the heap will be much larger. - if (size <= 256_MiB) { + // If no suitable heap was found fall back to the default cap to avoid creating a zero-sized stream buffer. + if (!found_heap) { + size = MAX_STREAM_BUFFER_SIZE; + } else if (size <= 256_MiB) { + // If rebar is not supported, cut the max heap size to 40%. This will allow 2 captures to be + // loaded at the same time in RenderDoc. If rebar is supported, this shouldn't be an issue + // as the heap will be much larger. size = size * 40 / 100; } } else { size = MAX_STREAM_BUFFER_SIZE; } - return (std::min)(Common::AlignUp(size, MAX_ALIGNMENT), MAX_STREAM_BUFFER_SIZE); + + // Clamp to the configured maximum, align up for safety, and ensure a sane minimum so + // region_size (stream_buffer_size / NUM_SYNCS) never becomes zero. + const VkDeviceSize aligned = (std::min)(Common::AlignUp(size, MAX_ALIGNMENT), MAX_STREAM_BUFFER_SIZE); + const VkDeviceSize min_size = MAX_ALIGNMENT * StagingBufferPool::NUM_SYNCS; + return static_cast((std::max)(aligned, min_size)); } } // Anonymous namespace @@ -106,31 +116,53 @@ void StagingBufferPool::TickFrame() { } StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) { - if (AreRegionsActive(Region(free_iterator) + 1, - (std::min)(Region(iterator + size) + 1, NUM_SYNCS))) { + const size_t aligned_size = Common::AlignUp(size, MAX_ALIGNMENT); + const bool wraps = iterator + size >= stream_buffer_size; + const size_t new_iterator = + wraps ? aligned_size : Common::AlignUp(iterator + size, MAX_ALIGNMENT); + const size_t begin_region = wraps ? 0 : Region(iterator); + const size_t last_byte = new_iterator == 0 ? 0 : new_iterator - 1; + const size_t end_region = (std::min)(Region(last_byte) + 1, NUM_SYNCS); + const size_t guard_begin = (std::min)(Region(free_iterator) + 1, NUM_SYNCS); + + if (!wraps) { + if (guard_begin < end_region && AreRegionsActive(guard_begin, end_region)) { + // Avoid waiting for the previous usages to be free + return GetStagingBuffer(size, MemoryUsage::Upload); + } + } else if (guard_begin < NUM_SYNCS && AreRegionsActive(guard_begin, NUM_SYNCS)) { // Avoid waiting for the previous usages to be free return GetStagingBuffer(size, MemoryUsage::Upload); } + const u64 current_tick = scheduler.CurrentTick(); std::fill(sync_ticks.begin() + Region(used_iterator), sync_ticks.begin() + Region(iterator), current_tick); used_iterator = iterator; - free_iterator = (std::max)(free_iterator, iterator + size); - if (iterator + size >= stream_buffer_size) { + if (wraps) { std::fill(sync_ticks.begin() + Region(used_iterator), sync_ticks.begin() + NUM_SYNCS, current_tick); used_iterator = 0; iterator = 0; free_iterator = size; - - if (AreRegionsActive(0, Region(size) + 1)) { + const size_t head_last_byte = aligned_size == 0 ? 0 : aligned_size - 1; + const size_t head_end_region = (std::min)(Region(head_last_byte) + 1, NUM_SYNCS); + if (AreRegionsActive(0, head_end_region)) { // Avoid waiting for the previous usages to be free return GetStagingBuffer(size, MemoryUsage::Upload); } } - const size_t offset = iterator; - iterator = Common::AlignUp(iterator + size, MAX_ALIGNMENT); + + std::fill(sync_ticks.begin() + begin_region, sync_ticks.begin() + end_region, current_tick); + + const size_t offset = wraps ? 0 : iterator; + iterator = new_iterator; + + if (!wraps) { + free_iterator = (std::max)(free_iterator, offset + size); + } + return StagingBufferRef{ .buffer = *stream_buffer, .offset = static_cast(offset), From dbeae7add0bbc0242be84664641d8d20edbecdac Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 7 Oct 2025 06:35:57 +0200 Subject: [PATCH 12/24] [vk, ogl] Add VK_QCOM ZTC, Bspline, Mitchell filter weights, add MMPX filter (#2577) Adds native support for QCOM cubic filter weights, and for devices whom do not support said weights, just implement them in shaders TODO: ZTC filter is wrong!? Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2577 Reviewed-by: crueter Reviewed-by: MaranBr Reviewed-by: CamilleLaVey Co-authored-by: lizzie Co-committed-by: lizzie --- docs/User.md | 2 +- .../app/src/main/res/values/arrays.xml | 8 ++ .../app/src/main/res/values/strings.xml | 4 + src/common/settings_enums.h | 2 +- src/qt_common/shared_translation.cpp | 4 + src/qt_common/shared_translation.h | 4 + src/video_core/host_shaders/CMakeLists.txt | 4 + .../host_shaders/present_bicubic.frag | 71 ++++------ .../host_shaders/present_bspline.frag | 35 +++++ .../host_shaders/present_mitchell.frag | 35 +++++ src/video_core/host_shaders/present_mmpx.frag | 131 ++++++++++++++++++ .../host_shaders/present_zero_tangent.frag | 35 +++++ .../renderer_opengl/gl_blit_screen.cpp | 13 ++ .../renderer_opengl/present/filters.cpp | 24 ++++ .../renderer_opengl/present/filters.h | 4 + .../renderer_vulkan/present/filters.cpp | 38 ++++- .../renderer_vulkan/present/filters.h | 3 +- .../renderer_vulkan/present/util.cpp | 13 +- src/video_core/renderer_vulkan/present/util.h | 2 +- .../renderer_vulkan/vk_blit_screen.cpp | 15 +- src/video_core/vulkan_common/vulkan_device.h | 8 +- 21 files changed, 395 insertions(+), 60 deletions(-) create mode 100644 src/video_core/host_shaders/present_bspline.frag create mode 100644 src/video_core/host_shaders/present_mitchell.frag create mode 100644 src/video_core/host_shaders/present_mmpx.frag create mode 100644 src/video_core/host_shaders/present_zero_tangent.frag diff --git a/docs/User.md b/docs/User.md index ba5d1b3eb0..67f81eadb6 100644 --- a/docs/User.md +++ b/docs/User.md @@ -7,4 +7,4 @@ This handbook is primarily aimed at the end-user - baking useful knowledge for e - **[The Basics](user/Basics.md)** - **[Audio](user/Audio.md)** - **[Graphics](user/Graphics.md)** -- **[Platforms and Architectures](user/Architectures.md)** \ No newline at end of file +- **[Platforms and Architectures](user/Architectures.md)** diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index ec94730348..7e44750909 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -253,12 +253,16 @@ @string/scaling_filter_nearest_neighbor @string/scaling_filter_bilinear @string/scaling_filter_bicubic + @string/scaling_filter_zero_tangent + @string/scaling_filter_bspline + @string/scaling_filter_mitchell @string/scaling_filter_spline1 @string/scaling_filter_gaussian @string/scaling_filter_lanczos @string/scaling_filter_scale_force @string/scaling_filter_fsr @string/scaling_filter_area + @string/scaling_filter_mmpx @@ -271,6 +275,10 @@ 6 7 8 + 9 + 10 + 11 + 12 diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 2f6587d136..cff0bab2b5 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -1018,6 +1018,10 @@ ScaleForce AMD FidelityFX™ Super Resolution Area + Zero-Tangent + B-Spline + Mitchell + MMPX None diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index 6644bc01cc..3fcdf08256 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -143,7 +143,7 @@ ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never); ENUM(FullscreenMode, Borderless, Exclusive); ENUM(NvdecEmulation, Off, Cpu, Gpu); ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res5_4X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, Res8X); -ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, MaxEnum); +ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, ZeroTangent, BSpline, Mitchell, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, Mmpx, MaxEnum); ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum); ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch); ENUM(ConsoleMode, Handheld, Docked); diff --git a/src/qt_common/shared_translation.cpp b/src/qt_common/shared_translation.cpp index 5b8622e00a..f926f506e7 100644 --- a/src/qt_common/shared_translation.cpp +++ b/src/qt_common/shared_translation.cpp @@ -555,12 +555,16 @@ std::unique_ptr ComboboxEnumeration(QObject* parent) PAIR(ScalingFilter, NearestNeighbor, tr("Nearest Neighbor")), PAIR(ScalingFilter, Bilinear, tr("Bilinear")), PAIR(ScalingFilter, Bicubic, tr("Bicubic")), + PAIR(ScalingFilter, ZeroTangent, tr("Zero-Tangent")), + PAIR(ScalingFilter, BSpline, tr("B-Spline")), + PAIR(ScalingFilter, Mitchell, tr("Mitchell")), PAIR(ScalingFilter, Spline1, tr("Spline-1")), PAIR(ScalingFilter, Gaussian, tr("Gaussian")), PAIR(ScalingFilter, Lanczos, tr("Lanczos")), PAIR(ScalingFilter, ScaleForce, tr("ScaleForce")), PAIR(ScalingFilter, Fsr, tr("AMD FidelityFX™️ Super Resolution")), PAIR(ScalingFilter, Area, tr("Area")), + PAIR(ScalingFilter, Mmpx, tr("MMPX")), }}); translations->insert({Settings::EnumMetadata::Index(), { diff --git a/src/qt_common/shared_translation.h b/src/qt_common/shared_translation.h index c9216c2daa..a25887bb87 100644 --- a/src/qt_common/shared_translation.h +++ b/src/qt_common/shared_translation.h @@ -38,6 +38,9 @@ static const std::map scaling_filter_texts_map {Settings::ScalingFilter::Bilinear, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bilinear"))}, {Settings::ScalingFilter::Bicubic, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bicubic"))}, + {Settings::ScalingFilter::ZeroTangent, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Zero-Tangent"))}, + {Settings::ScalingFilter::BSpline, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "B-Spline"))}, + {Settings::ScalingFilter::Mitchell, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Mitchell"))}, {Settings::ScalingFilter::Spline1, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Spline-1"))}, {Settings::ScalingFilter::Gaussian, @@ -48,6 +51,7 @@ static const std::map scaling_filter_texts_map QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "ScaleForce"))}, {Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))}, {Settings::ScalingFilter::Area, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Area"))}, + {Settings::ScalingFilter::Mmpx, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "MMPX"))}, }; static const std::map use_docked_mode_texts_map = { diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index c14b44a45a..9f7b9edd5a 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt @@ -44,9 +44,13 @@ set(SHADER_FILES pitch_unswizzle.comp present_area.frag present_bicubic.frag + present_zero_tangent.frag + present_bspline.frag + present_mitchell.frag present_gaussian.frag present_lanczos.frag present_spline1.frag + present_mmpx.frag queries_prefix_scan_sum.comp queries_prefix_scan_sum_nosubgroups.comp resolve_conditional_render.comp diff --git a/src/video_core/host_shaders/present_bicubic.frag b/src/video_core/host_shaders/present_bicubic.frag index a9d9d40a38..5347fd2ef7 100644 --- a/src/video_core/host_shaders/present_bicubic.frag +++ b/src/video_core/host_shaders/present_bicubic.frag @@ -1,56 +1,37 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later - #version 460 core - - layout (location = 0) in vec2 frag_tex_coord; - layout (location = 0) out vec4 color; - layout (binding = 0) uniform sampler2D color_texture; - -vec4 cubic(float v) { - vec4 n = vec4(1.0, 2.0, 3.0, 4.0) - v; - vec4 s = n * n * n; - float x = s.x; - float y = s.y - 4.0 * s.x; - float z = s.z - 4.0 * s.y + 6.0 * s.x; - float w = 6.0 - x - y - z; - return vec4(x, y, z, w) * (1.0 / 6.0); +vec4 cubic(float x) { + float x2 = x * x; + float x3 = x2 * x; + return vec4(1.0, x, x2, x3) * transpose(mat4x4( + 0.0, 2.0, 0.0, 0.0, + -1.0, 0.0, 1.0, 0.0, + 2.0, -5.0, 4.0, -1.0, + -1.0, 3.0, -3.0, 1.0 + ) * (1.0 / 2.0)); } - -vec4 textureBicubic( sampler2D textureSampler, vec2 texCoords ) { - - vec2 texSize = textureSize(textureSampler, 0); - vec2 invTexSize = 1.0 / texSize; - - texCoords = texCoords * texSize - 0.5; - - vec2 fxy = fract(texCoords); - texCoords -= fxy; - - vec4 xcubic = cubic(fxy.x); - vec4 ycubic = cubic(fxy.y); - - vec4 c = texCoords.xxyy + vec2(-0.5, +1.5).xyxy; - - vec4 s = vec4(xcubic.xz + xcubic.yw, ycubic.xz + ycubic.yw); - vec4 offset = c + vec4(xcubic.yw, ycubic.yw) / s; - - offset *= invTexSize.xxyy; - - vec4 sample0 = texture(textureSampler, offset.xz); - vec4 sample1 = texture(textureSampler, offset.yz); - vec4 sample2 = texture(textureSampler, offset.xw); - vec4 sample3 = texture(textureSampler, offset.yw); - - float sx = s.x / (s.x + s.y); - float sy = s.z / (s.z + s.w); - - return mix(mix(sample3, sample2, sx), mix(sample1, sample0, sx), sy); +vec4 textureBicubic(sampler2D samp, vec2 uv) { + vec2 tex_size = vec2(textureSize(samp, 0)); + vec2 cc_tex = uv * tex_size - 0.5f; + vec2 fex = cc_tex - floor(cc_tex); + vec4 xcubic = cubic(fex.x); + vec4 ycubic = cubic(fex.y); + vec4 c = floor(cc_tex).xxyy + vec2(-0.5f, 1.5f).xyxy; + vec4 z = vec4(xcubic.yw, ycubic.yw); + vec4 s = vec4(xcubic.xz, ycubic.xz) + z; + vec4 offset = (c + z / s) * (1.0f / tex_size).xxyy; + vec2 n = vec2(s.x / (s.x + s.y), s.z / (s.z + s.w)); + return mix( + mix(texture(samp, offset.yw), texture(samp, offset.xw), n.x), + mix(texture(samp, offset.yz), texture(samp, offset.xz), n.x), + n.y); } - void main() { color = textureBicubic(color_texture, frag_tex_coord); } diff --git a/src/video_core/host_shaders/present_bspline.frag b/src/video_core/host_shaders/present_bspline.frag new file mode 100644 index 0000000000..f229de6030 --- /dev/null +++ b/src/video_core/host_shaders/present_bspline.frag @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later +#version 460 core +layout (location = 0) in vec2 frag_tex_coord; +layout (location = 0) out vec4 color; +layout (binding = 0) uniform sampler2D color_texture; +vec4 cubic(float x) { + float x2 = x * x; + float x3 = x2 * x; + return vec4(1.0, x, x2, x3) * transpose(mat4x4( + 1.0, 4.0, 1.0, 0.0, + -3.0, 0.0, 3.0, 0.0, + 3.0, -6.0, 3.0, 0.0, + -1.0, 3.0, -3.0, 1.0 + ) * (1.0 / 6.0)); +} +vec4 textureBicubic(sampler2D samp, vec2 uv) { + vec2 tex_size = vec2(textureSize(samp, 0)); + vec2 cc_tex = uv * tex_size - 0.5f; + vec2 fex = cc_tex - floor(cc_tex); + vec4 xcubic = cubic(fex.x); + vec4 ycubic = cubic(fex.y); + vec4 c = floor(cc_tex).xxyy + vec2(-0.5f, 1.5f).xyxy; + vec4 z = vec4(xcubic.yw, ycubic.yw); + vec4 s = vec4(xcubic.xz, ycubic.xz) + z; + vec4 offset = (c + z / s) * (1.0f / tex_size).xxyy; + vec2 n = vec2(s.x / (s.x + s.y), s.z / (s.z + s.w)); + return mix( + mix(texture(samp, offset.yw), texture(samp, offset.xw), n.x), + mix(texture(samp, offset.yz), texture(samp, offset.xz), n.x), + n.y); +} +void main() { + color = textureBicubic(color_texture, frag_tex_coord); +} diff --git a/src/video_core/host_shaders/present_mitchell.frag b/src/video_core/host_shaders/present_mitchell.frag new file mode 100644 index 0000000000..4ca65cd6f0 --- /dev/null +++ b/src/video_core/host_shaders/present_mitchell.frag @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later +#version 460 core +layout (location = 0) in vec2 frag_tex_coord; +layout (location = 0) out vec4 color; +layout (binding = 0) uniform sampler2D color_texture; +vec4 cubic(float x) { + float x2 = x * x; + float x3 = x2 * x; + return vec4(1.0, x, x2, x3) * transpose(mat4x4( + 1.0, 16.0, 1.0, 0.0, + -9.0, 0.0, 9.0, 0.0, + 15.0, -36.0, 27.0, -6.0, + -7.0, 21.0, -21.0, 7.0 + ) * (1.0 / 18.0)); +} +vec4 textureBicubic(sampler2D samp, vec2 uv) { + vec2 tex_size = vec2(textureSize(samp, 0)); + vec2 cc_tex = uv * tex_size - 0.5f; + vec2 fex = cc_tex - floor(cc_tex); + vec4 xcubic = cubic(fex.x); + vec4 ycubic = cubic(fex.y); + vec4 c = floor(cc_tex).xxyy + vec2(-0.5f, 1.5f).xyxy; + vec4 z = vec4(xcubic.yw, ycubic.yw); + vec4 s = vec4(xcubic.xz, ycubic.xz) + z; + vec4 offset = (c + z / s) * (1.0f / tex_size).xxyy; + vec2 n = vec2(s.x / (s.x + s.y), s.z / (s.z + s.w)); + return mix( + mix(texture(samp, offset.yw), texture(samp, offset.xw), n.x), + mix(texture(samp, offset.yz), texture(samp, offset.xz), n.x), + n.y); +} +void main() { + color = textureBicubic(color_texture, frag_tex_coord); +} diff --git a/src/video_core/host_shaders/present_mmpx.frag b/src/video_core/host_shaders/present_mmpx.frag new file mode 100644 index 0000000000..6c2c05a63a --- /dev/null +++ b/src/video_core/host_shaders/present_mmpx.frag @@ -0,0 +1,131 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright 2023 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#version 460 core +layout(location = 0) in vec2 tex_coord; +layout(location = 0) out vec4 frag_color; +layout(binding = 0) uniform sampler2D tex; + +#define src(x, y) texture(tex, coord + vec2(x, y) * 1.0 / source_size) + +float luma(vec4 col) { + return dot(col.rgb, vec3(0.2126, 0.7152, 0.0722)) * (1.0 - col.a); +} + +bool same(vec4 B, vec4 A0) { + return all(equal(B, A0)); +} + +bool notsame(vec4 B, vec4 A0) { + return any(notEqual(B, A0)); +} + +bool all_eq2(vec4 B, vec4 A0, vec4 A1) { + return (same(B,A0) && same(B,A1)); +} + +bool all_eq3(vec4 B, vec4 A0, vec4 A1, vec4 A2) { + return (same(B,A0) && same(B,A1) && same(B,A2)); +} + +bool all_eq4(vec4 B, vec4 A0, vec4 A1, vec4 A2, vec4 A3) { + return (same(B,A0) && same(B,A1) && same(B,A2) && same(B,A3)); +} + +bool any_eq3(vec4 B, vec4 A0, vec4 A1, vec4 A2) { + return (same(B,A0) || same(B,A1) || same(B,A2)); +} + +bool none_eq2(vec4 B, vec4 A0, vec4 A1) { + return (notsame(B,A0) && notsame(B,A1)); +} + +bool none_eq4(vec4 B, vec4 A0, vec4 A1, vec4 A2, vec4 A3) { + return (notsame(B,A0) && notsame(B,A1) && notsame(B,A2) && notsame(B,A3)); +} + +void main() +{ + vec2 source_size = vec2(textureSize(tex, 0)); + vec2 pos = fract(tex_coord * source_size) - vec2(0.5, 0.5); + vec2 coord = tex_coord - pos / source_size; + + vec4 E = src(0.0,0.0); + + vec4 A = src(-1.0,-1.0); + vec4 B = src(0.0,-1.0); + vec4 C = src(1.0,-1.0); + + vec4 D = src(-1.0,0.0); + vec4 F = src(1.0,0.0); + + vec4 G = src(-1.0,1.0); + vec4 H = src(0.0,1.0); + vec4 I = src(1.0,1.0); + + vec4 J = E; + vec4 K = E; + vec4 L = E; + vec4 M = E; + + frag_color = E; + + if(same(E,A) && same(E,B) && same(E,C) && same(E,D) && same(E,F) && same(E,G) && same(E,H) && same(E,I)) return; + + vec4 P = src(0.0,2.0); + vec4 Q = src(-2.0,0.0); + vec4 R = src(2.0,0.0); + vec4 S = src(0.0,2.0); + + float Bl = luma(B); + float Dl = luma(D); + float El = luma(E); + float Fl = luma(F); + float Hl = luma(H); + + if (((same(D,B) && notsame(D,H) && notsame(D,F))) && ((El>=Dl) || same(E,A)) && any_eq3(E,A,C,G) && ((El=Bl) || same(E,C)) && any_eq3(E,A,C,I) && ((El=Hl) || same(E,G)) && any_eq3(E,A,G,I) && ((El=Fl) || same(E,I)) && any_eq3(E,C,G,I) && ((El MakeBicubic(const Device& device) { HostShaders::PRESENT_BICUBIC_FRAG); } +std::unique_ptr MakeMitchell(const Device& device) { + return std::make_unique(device, CreateBilinearSampler(), + HostShaders::PRESENT_MITCHELL_FRAG); +} + +std::unique_ptr MakeZeroTangent(const Device& device) { + return std::make_unique(device, CreateBilinearSampler(), + HostShaders::PRESENT_ZERO_TANGENT_FRAG); +} + +std::unique_ptr MakeBSpline(const Device& device) { + return std::make_unique(device, CreateBilinearSampler(), + HostShaders::PRESENT_BSPLINE_FRAG); +} + std::unique_ptr MakeGaussian(const Device& device) { return std::make_unique(device, CreateBilinearSampler(), HostShaders::PRESENT_GAUSSIAN_FRAG); @@ -60,4 +79,9 @@ std::unique_ptr MakeArea(const Device& device) { HostShaders::PRESENT_AREA_FRAG); } +std::unique_ptr MakeMmpx(const Device& device) { + return std::make_unique(device, CreateNearestNeighborSampler(), + HostShaders::PRESENT_MMPX_FRAG); +} + } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/present/filters.h b/src/video_core/renderer_opengl/present/filters.h index 7b38ac56bc..187d0f1298 100644 --- a/src/video_core/renderer_opengl/present/filters.h +++ b/src/video_core/renderer_opengl/present/filters.h @@ -17,10 +17,14 @@ namespace OpenGL { std::unique_ptr MakeNearestNeighbor(const Device& device); std::unique_ptr MakeBilinear(const Device& device); std::unique_ptr MakeBicubic(const Device& device); +std::unique_ptr MakeZeroTangent(const Device& device); +std::unique_ptr MakeMitchell(const Device& device); +std::unique_ptr MakeBSpline(const Device& device); std::unique_ptr MakeGaussian(const Device& device); std::unique_ptr MakeSpline1(const Device& device); std::unique_ptr MakeLanczos(const Device& device); std::unique_ptr MakeScaleForce(const Device& device); std::unique_ptr MakeArea(const Device& device); +std::unique_ptr MakeMmpx(const Device& device); } // namespace OpenGL diff --git a/src/video_core/renderer_vulkan/present/filters.cpp b/src/video_core/renderer_vulkan/present/filters.cpp index e0f2b26f84..0a28ea6349 100644 --- a/src/video_core/renderer_vulkan/present/filters.cpp +++ b/src/video_core/renderer_vulkan/present/filters.cpp @@ -7,6 +7,8 @@ // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include +#include "common/assert.h" #include "common/common_types.h" #include "video_core/host_shaders/present_area_frag_spv.h" @@ -14,6 +16,10 @@ #include "video_core/host_shaders/present_gaussian_frag_spv.h" #include "video_core/host_shaders/present_lanczos_frag_spv.h" #include "video_core/host_shaders/present_spline1_frag_spv.h" +#include "video_core/host_shaders/present_mitchell_frag_spv.h" +#include "video_core/host_shaders/present_bspline_frag_spv.h" +#include "video_core/host_shaders/present_zero_tangent_frag_spv.h" +#include "video_core/host_shaders/present_mmpx_frag_spv.h" #include "video_core/host_shaders/vulkan_present_frag_spv.h" #include "video_core/host_shaders/vulkan_present_scaleforce_fp16_frag_spv.h" #include "video_core/host_shaders/vulkan_present_scaleforce_fp32_frag_spv.h" @@ -52,13 +58,28 @@ std::unique_ptr MakeSpline1(const Device& device, VkFormat fram BuildShader(device, PRESENT_SPLINE1_FRAG_SPV)); } -std::unique_ptr MakeBicubic(const Device& device, VkFormat frame_format) { +std::unique_ptr MakeBicubic(const Device& device, VkFormat frame_format, VkCubicFilterWeightsQCOM qcom_weights) { // No need for handrolled shader -- if the VK impl can do it for us ;) - if (device.IsExtFilterCubicSupported()) - return std::make_unique(device, frame_format, CreateCubicSampler(device), - BuildShader(device, VULKAN_PRESENT_FRAG_SPV)); - return std::make_unique(device, frame_format, CreateBilinearSampler(device), - BuildShader(device, PRESENT_BICUBIC_FRAG_SPV)); + // Catmull-Rom is default bicubic for all implementations... + if (device.IsExtFilterCubicSupported() && (device.IsQcomFilterCubicWeightsSupported() || qcom_weights == VK_CUBIC_FILTER_WEIGHTS_CATMULL_ROM_QCOM)) { + return std::make_unique(device, frame_format, CreateCubicSampler(device, + qcom_weights), BuildShader(device, VULKAN_PRESENT_FRAG_SPV)); + } else { + return std::make_unique(device, frame_format, CreateBilinearSampler(device), [&](){ + switch (qcom_weights) { + case VK_CUBIC_FILTER_WEIGHTS_CATMULL_ROM_QCOM: + return BuildShader(device, PRESENT_BICUBIC_FRAG_SPV); + case VK_CUBIC_FILTER_WEIGHTS_ZERO_TANGENT_CARDINAL_QCOM: + return BuildShader(device, PRESENT_ZERO_TANGENT_FRAG_SPV); + case VK_CUBIC_FILTER_WEIGHTS_B_SPLINE_QCOM: + return BuildShader(device, PRESENT_BSPLINE_FRAG_SPV); + case VK_CUBIC_FILTER_WEIGHTS_MITCHELL_NETRAVALI_QCOM: + return BuildShader(device, PRESENT_MITCHELL_FRAG_SPV); + default: + UNREACHABLE(); + } + }()); + } } std::unique_ptr MakeGaussian(const Device& device, VkFormat frame_format) { @@ -81,4 +102,9 @@ std::unique_ptr MakeArea(const Device& device, VkFormat frame_f BuildShader(device, PRESENT_AREA_FRAG_SPV)); } +std::unique_ptr MakeMmpx(const Device& device, VkFormat frame_format) { + return std::make_unique(device, frame_format, CreateNearestNeighborSampler(device), + BuildShader(device, PRESENT_MMPX_FRAG_SPV)); +} + } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/filters.h b/src/video_core/renderer_vulkan/present/filters.h index 015bffc8a5..afc3ba29a0 100644 --- a/src/video_core/renderer_vulkan/present/filters.h +++ b/src/video_core/renderer_vulkan/present/filters.h @@ -17,11 +17,12 @@ class MemoryAllocator; std::unique_ptr MakeNearestNeighbor(const Device& device, VkFormat frame_format); std::unique_ptr MakeBilinear(const Device& device, VkFormat frame_format); -std::unique_ptr MakeBicubic(const Device& device, VkFormat frame_format); +std::unique_ptr MakeBicubic(const Device& device, VkFormat frame_format, VkCubicFilterWeightsQCOM qcom_weights); std::unique_ptr MakeSpline1(const Device& device, VkFormat frame_format); std::unique_ptr MakeGaussian(const Device& device, VkFormat frame_format); std::unique_ptr MakeLanczos(const Device& device, VkFormat frame_format); std::unique_ptr MakeScaleForce(const Device& device, VkFormat frame_format); std::unique_ptr MakeArea(const Device& device, VkFormat frame_format); +std::unique_ptr MakeMmpx(const Device& device, VkFormat frame_format); } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/util.cpp b/src/video_core/renderer_vulkan/present/util.cpp index 0b1a89eec0..29a1c34976 100644 --- a/src/video_core/renderer_vulkan/present/util.cpp +++ b/src/video_core/renderer_vulkan/present/util.cpp @@ -624,8 +624,8 @@ vk::Sampler CreateNearestNeighborSampler(const Device& device) { return device.GetLogical().CreateSampler(ci_nn); } -vk::Sampler CreateCubicSampler(const Device& device) { - const VkSamplerCreateInfo ci_nn{ +vk::Sampler CreateCubicSampler(const Device& device, VkCubicFilterWeightsQCOM qcom_weights) { + VkSamplerCreateInfo ci_nn{ .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, .pNext = nullptr, .flags = 0, @@ -645,7 +645,14 @@ vk::Sampler CreateCubicSampler(const Device& device) { .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, .unnormalizedCoordinates = VK_FALSE, }; - + const VkSamplerCubicWeightsCreateInfoQCOM ci_qcom_nn{ + .sType = VK_STRUCTURE_TYPE_SAMPLER_CUBIC_WEIGHTS_CREATE_INFO_QCOM, + .pNext = nullptr, + .cubicWeights = qcom_weights + }; + // If not specified, assume Catmull-Rom + if (qcom_weights != VK_CUBIC_FILTER_WEIGHTS_CATMULL_ROM_QCOM) + ci_nn.pNext = &ci_qcom_nn; return device.GetLogical().CreateSampler(ci_nn); } diff --git a/src/video_core/renderer_vulkan/present/util.h b/src/video_core/renderer_vulkan/present/util.h index 11810352df..38cc6203c5 100644 --- a/src/video_core/renderer_vulkan/present/util.h +++ b/src/video_core/renderer_vulkan/present/util.h @@ -57,7 +57,7 @@ VkWriteDescriptorSet CreateWriteDescriptorSet(std::vector VkDescriptorSet set, u32 binding); vk::Sampler CreateBilinearSampler(const Device& device); vk::Sampler CreateNearestNeighborSampler(const Device& device); -vk::Sampler CreateCubicSampler(const Device& device); +vk::Sampler CreateCubicSampler(const Device& device, VkCubicFilterWeightsQCOM qcom_weights); void BeginRenderPass(vk::CommandBuffer& cmdbuf, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent); diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index b720bcded3..0f54dd5ade 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp @@ -7,6 +7,7 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include #include "video_core/framebuffer_config.h" #include "video_core/present.h" #include "video_core/renderer_vulkan/present/filters.h" @@ -41,7 +42,16 @@ void BlitScreen::SetWindowAdaptPass() { window_adapt = MakeNearestNeighbor(device, swapchain_view_format); break; case Settings::ScalingFilter::Bicubic: - window_adapt = MakeBicubic(device, swapchain_view_format); + window_adapt = MakeBicubic(device, swapchain_view_format, VK_CUBIC_FILTER_WEIGHTS_CATMULL_ROM_QCOM); + break; + case Settings::ScalingFilter::ZeroTangent: + window_adapt = MakeBicubic(device, swapchain_view_format, VK_CUBIC_FILTER_WEIGHTS_ZERO_TANGENT_CARDINAL_QCOM); + break; + case Settings::ScalingFilter::BSpline: + window_adapt = MakeBicubic(device, swapchain_view_format, VK_CUBIC_FILTER_WEIGHTS_B_SPLINE_QCOM); + break; + case Settings::ScalingFilter::Mitchell: + window_adapt = MakeBicubic(device, swapchain_view_format, VK_CUBIC_FILTER_WEIGHTS_MITCHELL_NETRAVALI_QCOM); break; case Settings::ScalingFilter::Spline1: window_adapt = MakeSpline1(device, swapchain_view_format); @@ -58,6 +68,9 @@ void BlitScreen::SetWindowAdaptPass() { case Settings::ScalingFilter::Area: window_adapt = MakeArea(device, swapchain_view_format); break; + case Settings::ScalingFilter::Mmpx: + window_adapt = MakeMmpx(device, swapchain_view_format); + break; case Settings::ScalingFilter::Fsr: case Settings::ScalingFilter::Bilinear: default: diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index bd54144480..cb13f28523 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -89,7 +89,8 @@ VK_DEFINE_HANDLE(VmaAllocator) EXTENSION(NV, VIEWPORT_ARRAY2, viewport_array2) \ EXTENSION(NV, VIEWPORT_SWIZZLE, viewport_swizzle) \ EXTENSION(EXT, DESCRIPTOR_INDEXING, descriptor_indexing) \ - EXTENSION(EXT, FILTER_CUBIC, filter_cubic) + EXTENSION(EXT, FILTER_CUBIC, filter_cubic) \ + EXTENSION(QCOM, FILTER_CUBIC_WEIGHTS, filter_cubic_weights) // Define extensions which must be supported. #define FOR_EACH_VK_MANDATORY_EXTENSION(EXTENSION_NAME) \ @@ -558,6 +559,11 @@ public: return extensions.filter_cubic; } + /// Returns true if the device supports VK_QCOM_filter_cubic_weights + bool IsQcomFilterCubicWeightsSupported() const { + return extensions.filter_cubic_weights; + } + /// Returns true if the device supports VK_EXT_line_rasterization. bool IsExtLineRasterizationSupported() const { return extensions.line_rasterization; From cf0628af466f1297c87e73b2bfe973a97f12dd04 Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 7 Oct 2025 06:38:22 +0200 Subject: [PATCH 13/24] [compat] improve thread naming logic (#271) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/271 Reviewed-by: MaranBr Reviewed-by: CamilleLaVey Co-authored-by: lizzie Co-committed-by: lizzie --- src/common/thread.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/common/thread.cpp b/src/common/thread.cpp index da1fa9b6c5..2de7465a22 100644 --- a/src/common/thread.cpp +++ b/src/common/thread.cpp @@ -1,6 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later - // SPDX-FileCopyrightText: 2013 Dolphin Emulator Project // SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -18,9 +17,8 @@ #else #if defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) #include -#else -#include #endif +#include #include #endif #ifndef _WIN32 @@ -93,33 +91,35 @@ void SetCurrentThreadName(const char* name) { #else // !MSVC_VER, so must be POSIX threads // MinGW with the POSIX threading model does not support pthread_setname_np -#if !defined(_WIN32) || defined(_MSC_VER) void SetCurrentThreadName(const char* name) { + // See for reference + // https://gitlab.freedesktop.org/mesa/mesa/-/blame/main/src/util/u_thread.c?ref_type=heads#L75 #ifdef __APPLE__ pthread_setname_np(name); +#elif defined(__HAIKU__) + rename_thread(find_thread(NULL), name); #elif defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) pthread_set_name_np(pthread_self(), name); #elif defined(__NetBSD__) pthread_setname_np(pthread_self(), "%s", (void*)name); -#elif defined(__linux__) - // Linux limits thread names to 15 characters and will outright reject any - // attempt to set a longer name with ERANGE. - std::string truncated(name, (std::min)(strlen(name), static_cast(15))); - if (int e = pthread_setname_np(pthread_self(), truncated.c_str())) { - errno = e; - LOG_ERROR(Common, "Failed to set thread name to '{}': {}", truncated, GetLastErrorMsg()); +#elif defined(__linux__) || defined(__CYGWIN__) || defined(__sun__) || defined(__glibc__) || defined(__managarm__) + int ret = pthread_setname_np(pthread_self(), name); + if (ret == ERANGE) { + // Linux limits thread names to 15 characters and will outright reject any + // attempt to set a longer name with ERANGE. + char buf[16]; + size_t const len = std::min(std::strlen(name), sizeof(buf) - 1); + std::memcpy(buf, name, len); + buf[len] = '\0'; + pthread_setname_np(pthread_self(), buf); } +#elif !defined(_WIN32) || defined(_MSC_VER) + // mingw stub + (void)name; #else pthread_setname_np(pthread_self(), name); #endif } -#endif - -#if defined(_WIN32) -void SetCurrentThreadName(const char* name) { - // Do Nothing on MingW -} -#endif #endif From 9acb6006b8586303304102deb42b4f7dc462fe53 Mon Sep 17 00:00:00 2001 From: Caio Oliveira Date: Wed, 8 Oct 2025 01:04:18 +0200 Subject: [PATCH 14/24] [ci] improve ccache and add support on Android (#2673) * disable PCH * fix missing headers after disabling PCH * add support to extra cmake flags on Android building * remove debug symbols on Release building (also fixing ccache on windows) Signed-off-by: Caio Oliveira Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2673 Reviewed-by: crueter Co-authored-by: Caio Oliveira Co-committed-by: Caio Oliveira --- CMakeLists.txt | 7 +++++++ docs/build/Android.md | 1 + externals/CMakeLists.txt | 14 ++++++++------ src/CMakeLists.txt | 12 +++--------- src/android/app/build.gradle.kts | 5 ++++- src/dynarmic/CMakeLists.txt | 12 ++++++------ src/dynarmic/src/dynarmic/backend/arm64/abi.h | 1 + src/dynarmic/src/dynarmic/common/assert.h | 6 ++++++ src/dynarmic/src/dynarmic/common/memory_pool.h | 4 ++++ src/dynarmic/src/dynarmic/ir/opt_passes.cpp | 1 + 10 files changed, 41 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f436c0a183..1b69782a23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -287,6 +287,13 @@ if (ANDROID) set(CMAKE_POLICY_VERSION_MINIMUM 3.5) # Workaround for Oboe endif() +# We need to downgrade debug info (/Zi -> /Z7) to use an older but more cacheable format +# See https://github.com/nanoant/CMakePCHCompiler/issues/21 +if(WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) + string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") +endif() + # Default to a Release build get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if (NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE) diff --git a/docs/build/Android.md b/docs/build/Android.md index c8ff3a3b1e..f511f71370 100644 --- a/docs/build/Android.md +++ b/docs/build/Android.md @@ -33,6 +33,7 @@ Eden by default will be cloned into - 4. Navigate to `eden/src/android`. 5. Then Build with `./gradlew assembleRelWithDebInfo`. 6. To build the optimised build use `./gradlew assembleGenshinSpoofRelWithDebInfo`. +7. You can pass extra variables to cmake via `-PYUZU_ANDROID_ARGS="-D..."` ### Script A convenience script for building is provided in `.ci/android/build.sh`. The built APK can be put into an `artifacts` directory via `.ci/android/package.sh`. On Windows, these must be done in the Git Bash or MinGW terminal. diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 434e6fb100..2da461fd5c 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -155,12 +155,14 @@ if (YUZU_USE_BUNDLED_SIRIT) AddJsonPackage(sirit-ci) else() AddJsonPackage(sirit) - if(MSVC AND USE_CCACHE AND sirit_ADDED) - get_target_property(_opts sirit COMPILE_OPTIONS) - list(FILTER _opts EXCLUDE REGEX "/Zi") - list(APPEND _opts "/Z7") - set_target_properties(siritobj PROPERTIES COMPILE_OPTIONS "${_opts}") - elseif(MSVC AND CXX_CLANG) + # Change to old-but-more-cacheable debug info on Windows + if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) + get_target_property(sirit_opts sirit COMPILE_OPTIONS) + list(FILTER sirit_opts EXCLUDE REGEX "/Zi") + list(APPEND sirit_opts "/Z7") + set_target_properties(sirit PROPERTIES COMPILE_OPTIONS "${sirit_opts}") + endif() + if(MSVC AND CXX_CLANG) target_compile_options(siritobj PRIVATE -Wno-error=unused-command-line-argument) endif() endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 88470c4c42..0f3c5cfd4b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -101,15 +101,9 @@ if (MSVC AND NOT CXX_CLANG) ) endif() - if (USE_CCACHE OR YUZU_USE_PRECOMPILED_HEADERS) - # when caching, we need to use /Z7 to downgrade debug info to use an older but more cacheable format - # Precompiled headers are deleted if not using /Z7. See https://github.com/nanoant/CMakePCHCompiler/issues/21 - add_compile_options(/Z7) - # Avoid D9025 warning - string(REPLACE "/Zi" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") - string(REPLACE "/Zi" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") - else() - add_compile_options(/Zi) + if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) + string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") endif() if (ARCHITECTURE_x86_64) diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts index c85da039cb..31db36199a 100644 --- a/src/android/app/build.gradle.kts +++ b/src/android/app/build.gradle.kts @@ -75,6 +75,8 @@ android { externalNativeBuild { cmake { + val extraCMakeArgs = (project.findProperty("YUZU_ANDROID_ARGS") as String?)?.split("\\s+".toRegex()) ?: emptyList() + arguments.addAll(listOf( "-DENABLE_QT=0", // Don't use QT "-DENABLE_SDL2=0", // Don't use SDL @@ -87,7 +89,8 @@ android { "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", "-DBUILD_TESTING=OFF", "-DYUZU_TESTS=OFF", - "-DDYNARMIC_TESTS=OFF" + "-DDYNARMIC_TESTS=OFF", + *extraCMakeArgs.toTypedArray() )) abiFilters("arm64-v8a") diff --git a/src/dynarmic/CMakeLists.txt b/src/dynarmic/CMakeLists.txt index 6b3308fb54..e5345ef458 100644 --- a/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/CMakeLists.txt @@ -25,11 +25,7 @@ option(DYNARMIC_IGNORE_ASSERTS "Ignore asserts" OFF) option(DYNARMIC_TESTS_USE_UNICORN "Enable fuzzing tests against unicorn" OFF) CMAKE_DEPENDENT_OPTION(DYNARMIC_USE_LLVM "Support disassembly of jitted x86_64 code using LLVM" OFF "NOT YUZU_DISABLE_LLVM" OFF) -if (PLATFORM_OPENBSD) - option(DYNARMIC_USE_PRECOMPILED_HEADERS "Use precompiled headers" OFF) -else() - option(DYNARMIC_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON) -endif() +option(DYNARMIC_USE_PRECOMPILED_HEADERS "Use precompiled headers" OFF) option(DYNARMIC_INSTALL "Install dynarmic headers and CMake files" OFF) option(DYNARMIC_USE_BUNDLED_EXTERNALS "Use all bundled externals (useful when e.g. cross-compiling)" OFF) @@ -81,7 +77,6 @@ if (MSVC) /wd4592 # Symbol will be dynamically initialized (implementation limitation) /permissive- # Stricter C++ standards conformance /MP - /Zi /Zo /EHsc /Zc:externConstexpr # Allows external linkage for variables declared "extern constexpr", as the standard permits. @@ -91,6 +86,11 @@ if (MSVC) /bigobj # Increase number of sections in .obj files /DNOMINMAX) + if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) + string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + endif() + if (DYNARMIC_WARNINGS_AS_ERRORS) list(APPEND DYNARMIC_CXX_FLAGS /WX) diff --git a/src/dynarmic/src/dynarmic/backend/arm64/abi.h b/src/dynarmic/src/dynarmic/backend/arm64/abi.h index ca7c9187db..635d64f062 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/abi.h +++ b/src/dynarmic/src/dynarmic/backend/arm64/abi.h @@ -14,6 +14,7 @@ #include #include "dynarmic/common/common_types.h" +#include "dynarmic/common/assert.h" #include #include "dynarmic/common/always_false.h" diff --git a/src/dynarmic/src/dynarmic/common/assert.h b/src/dynarmic/src/dynarmic/common/assert.h index 9973b8948d..0a3cb5331d 100644 --- a/src/dynarmic/src/dynarmic/common/assert.h +++ b/src/dynarmic/src/dynarmic/common/assert.h @@ -23,6 +23,12 @@ template } \ }()) #endif +#ifndef ASSERT_FALSE +#define ASSERT_FALSE(...) \ + ([&]() { \ + assert_terminate("false", __VA_ARGS__); \ + }()) +#endif #ifndef ASSERT #define ASSERT(_a_) ASSERT_MSG(_a_, "") diff --git a/src/dynarmic/src/dynarmic/common/memory_pool.h b/src/dynarmic/src/dynarmic/common/memory_pool.h index c99316e107..d0a5223db3 100644 --- a/src/dynarmic/src/dynarmic/common/memory_pool.h +++ b/src/dynarmic/src/dynarmic/common/memory_pool.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2016 MerryMage * SPDX-License-Identifier: 0BSD @@ -6,6 +9,7 @@ #pragma once #include +#include #include namespace Dynarmic::Common { diff --git a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp index e9175f0e6b..25afde9b5d 100644 --- a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp +++ b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: 0BSD */ +#include #include #include From acd7d792a34a809cf4e7f9270b3cee605fb6c35e Mon Sep 17 00:00:00 2001 From: Gamer64 Date: Wed, 8 Oct 2025 02:08:13 +0200 Subject: [PATCH 15/24] [hle] Stubbed QueryLastPlayTime (#389) Ported from Torzu, made by Jarrod Norwell. Co-authored-by: Jarrod Norwell Co-authored-by: Gamer64 <76565986+Gamer64ytb@users.noreply.github.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/389 Reviewed-by: crueter Reviewed-by: MaranBr Co-authored-by: Gamer64 Co-committed-by: Gamer64 --- src/core/hle/service/ns/query_service.cpp | 14 +++++++++++++- src/core/hle/service/ns/query_service.h | 8 ++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/core/hle/service/ns/query_service.cpp b/src/core/hle/service/ns/query_service.cpp index 1384005415..a4632cb6c8 100644 --- a/src/core/hle/service/ns/query_service.cpp +++ b/src/core/hle/service/ns/query_service.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -29,7 +32,7 @@ IQueryService::IQueryService(Core::System& system_) : ServiceFramework{system_, {14, nullptr, "QueryRecentlyPlayedApplication"}, {15, nullptr, "GetRecentlyPlayedApplicationUpdateEvent"}, {16, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystemV0"}, - {17, nullptr, "QueryLastPlayTime"}, + {17, D<&IQueryService::QueryLastPlayTime>, "QueryLastPlayTime"}, {18, nullptr, "QueryApplicationPlayStatisticsForSystem"}, {19, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystem"}, }; @@ -53,4 +56,13 @@ Result IQueryService::QueryPlayStatisticsByApplicationIdAndUserAccountId( R_SUCCEED(); } +Result IQueryService::QueryLastPlayTime( + Out out_entries, u8 unknown, + OutArray out_last_play_times, + InArray application_ids) { + *out_entries = 1; + *out_last_play_times = {}; + R_SUCCEED(); +} + } // namespace Service::NS diff --git a/src/core/hle/service/ns/query_service.h b/src/core/hle/service/ns/query_service.h index c4c82b752e..ba1cddd4ca 100644 --- a/src/core/hle/service/ns/query_service.h +++ b/src/core/hle/service/ns/query_service.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -23,6 +26,8 @@ struct PlayStatistics { }; static_assert(sizeof(PlayStatistics) == 0x28, "PlayStatistics is an invalid size"); +struct LastPlayTime {}; + class IQueryService final : public ServiceFramework { public: explicit IQueryService(Core::System& system_); @@ -31,6 +36,9 @@ public: private: Result QueryPlayStatisticsByApplicationIdAndUserAccountId( Out out_play_statistics, bool unknown, u64 application_id, Uid account_id); + Result QueryLastPlayTime(Out out_entries, u8 unknown, + OutArray out_last_play_times, + InArray application_ids); }; } // namespace Service::NS From db65f107689f853141fd2cf4cb7b6b55b24aff3e Mon Sep 17 00:00:00 2001 From: Ribbit Date: Wed, 8 Oct 2025 04:01:24 +0200 Subject: [PATCH 16/24] [vk] Unify RAII in Vulkan (#2679) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR consolidates Vulkan RAII on video_core/vulkan_common/vulkan_wrapper.h’s vk::Handle and remove the unused duplicate src/video_core/vulkan_common/vulkan_raii.h, reducing confusion and maintenance. Swapchain now uses RAII‑managed per‑image semaphores and clears them in Destroy(), providing correct present synchronization and automatic cleanup. Expected result: simpler lifetimes, fewer leak risks, and more stable presentation with negligible overhead. Co-authored-by: Ribbit Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2679 Reviewed-by: MaranBr Reviewed-by: CamilleLaVey Co-authored-by: Ribbit Co-committed-by: Ribbit --- .../features/settings/model/BooleanSetting.kt | 2 - .../settings/model/view/SettingsItem.kt | 8 +- .../settings/ui/SettingsFragmentPresenter.kt | 1 - .../app/src/main/res/values-ar/strings.xml | 2 - .../app/src/main/res/values-ckb/strings.xml | 2 - .../app/src/main/res/values-cs/strings.xml | 2 - .../app/src/main/res/values-de/strings.xml | 2 - .../app/src/main/res/values-es/strings.xml | 2 - .../app/src/main/res/values-fa/strings.xml | 2 - .../app/src/main/res/values-fr/strings.xml | 2 - .../app/src/main/res/values-he/strings.xml | 2 - .../app/src/main/res/values-hu/strings.xml | 2 - .../app/src/main/res/values-id/strings.xml | 2 - .../app/src/main/res/values-it/strings.xml | 2 - .../app/src/main/res/values-ja/strings.xml | 2 - .../app/src/main/res/values-ko/strings.xml | 2 - .../app/src/main/res/values-nb/strings.xml | 2 - .../app/src/main/res/values-pl/strings.xml | 2 - .../src/main/res/values-pt-rBR/strings.xml | 2 - .../src/main/res/values-pt-rPT/strings.xml | 2 - .../app/src/main/res/values-ru/strings.xml | 2 - .../app/src/main/res/values-sr/strings.xml | 2 - .../app/src/main/res/values-uk/strings.xml | 2 - .../app/src/main/res/values-vi/strings.xml | 2 - .../src/main/res/values-zh-rCN/strings.xml | 2 - .../src/main/res/values-zh-rTW/strings.xml | 2 - .../app/src/main/res/values/strings.xml | 2 - src/common/settings.h | 1 - src/qt_common/shared_translation.cpp | 7 +- .../renderer_vulkan/renderer_vulkan.cpp | 9 - .../renderer_vulkan/renderer_vulkan.h | 10 +- .../renderer_vulkan/vk_swapchain.cpp | 1 + src/video_core/vulkan_common/vulkan_raii.h | 231 ------------------ .../vulkan_common/vulkan_wrapper.cpp | 11 +- src/video_core/vulkan_common/vulkan_wrapper.h | 66 ++--- 35 files changed, 42 insertions(+), 353 deletions(-) delete mode 100644 src/video_core/vulkan_common/vulkan_raii.h diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index 638e1101db..b26fb1dec5 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt @@ -51,7 +51,6 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { SOC_OVERLAY_BACKGROUND("soc_overlay_background"), - ENABLE_RAII("enable_raii"), FRAME_INTERPOLATION("frame_interpolation"), // FRAME_SKIPPING("frame_skipping"), @@ -71,7 +70,6 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { DEBUG_FLUSH_BY_LINE("flush_line"), USE_LRU_CACHE("use_lru_cache"); - external fun isRaiiEnabled(): Boolean // external fun isFrameSkippingEnabled(): Boolean external fun isFrameInterpolationEnabled(): Boolean diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index 5f7f7a43f9..ebc726225a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -229,13 +229,6 @@ abstract class SettingsItem( override fun reset() = BooleanSetting.USE_DOCKED_MODE.reset() } - put( - SwitchSetting( - BooleanSetting.ENABLE_RAII, - titleId = R.string.enable_raii, - descriptionId = R.string.enable_raii_description - ) - ) put( SwitchSetting( BooleanSetting.FRAME_INTERPOLATION, @@ -833,3 +826,4 @@ abstract class SettingsItem( } } } + diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index 715baec72f..0d882a7f01 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -462,7 +462,6 @@ class SettingsFragmentPresenter( add(IntSetting.RENDERER_SAMPLE_SHADING_FRACTION.key) add(HeaderSetting(R.string.veil_renderer)) - add(BooleanSetting.ENABLE_RAII.key) add(BooleanSetting.RENDERER_EARLY_RELEASE_FENCES.key) add(IntSetting.DMA_ACCURACY.key) add(BooleanSetting.BUFFER_REORDER_DISABLE.key) diff --git a/src/android/app/src/main/res/values-ar/strings.xml b/src/android/app/src/main/res/values-ar/strings.xml index 4b58d5f851..388afd88cd 100644 --- a/src/android/app/src/main/res/values-ar/strings.xml +++ b/src/android/app/src/main/res/values-ar/strings.xml @@ -64,8 +64,6 @@ امتدادات GPU العارض - RAII - طريقة لإدارة الموارد تلقائيًا في فولكان تضمن الإفراج الصحيح عن الموارد عندما لا تكون هناك حاجة إليها، ولكن قد تسبب تعطل الألعاب المجمعة. وحدة المعالجة المركزية والذاكرة حجاب عدن إعدادات تجريبية لتحسين الأداء والقدرة. قد تسبب هذه الإعدادات شاشات سوداء أو مشاكل أخرى في اللعبة. diff --git a/src/android/app/src/main/res/values-ckb/strings.xml b/src/android/app/src/main/res/values-ckb/strings.xml index 25fcf6acef..2ab4af16ad 100644 --- a/src/android/app/src/main/res/values-ckb/strings.xml +++ b/src/android/app/src/main/res/values-ckb/strings.xml @@ -65,8 +65,6 @@ پاشکۆکانی GPU رێندرەر - RAII - ڕێگایەکی بەڕێوەبردنی سەرچاوەکان بە خۆکار لە ڤولکان کە دڵنیای دەکاتەوە لە ئازادکردنی گونجاوی سەرچاوەکان کاتێک کە چیتر پێویستیان نییە، بەڵام لەوانەیە ببێتە هۆی کەوتنی یارییە کۆکراوەکان. CPU و بیرگە حجاب عدن ڕێکخستنە تاقیکارییەکان بۆ باشترکردنی کارایی و توانا. ئەم ڕێکخستنانە لەوانەیە ببێتە هۆی شاشە ڕەشەکان یان کێشەیتری یاری. diff --git a/src/android/app/src/main/res/values-cs/strings.xml b/src/android/app/src/main/res/values-cs/strings.xml index 8d7e274464..ad8f89ffc5 100644 --- a/src/android/app/src/main/res/values-cs/strings.xml +++ b/src/android/app/src/main/res/values-cs/strings.xml @@ -64,8 +64,6 @@ Rozšíření GPU Renderer - RAII - Metoda automatické správy prostředků ve Vulkanu, která zajišťuje správné uvolnění prostředků, když již nejsou potřeba, ale může způsobit pády v balených hrách. CPU a paměť Edenův závoj Experimentální nastavení pro zlepšení výkonu a schopností. Tato nastavení mohou způsobit černé obrazovky nebo další herní problémy. diff --git a/src/android/app/src/main/res/values-de/strings.xml b/src/android/app/src/main/res/values-de/strings.xml index 146fa60fed..cf12a2244f 100644 --- a/src/android/app/src/main/res/values-de/strings.xml +++ b/src/android/app/src/main/res/values-de/strings.xml @@ -65,8 +65,6 @@ GPU-Erweiterungen Renderer - RAII - Eine Methode zur automatischen Ressourcenverwaltung in Vulkan, die eine ordnungsgemäße Freigabe von Ressourcen gewährleistet, wenn sie nicht mehr benötigt werden, aber bei gebündelten Spielen Abstürze verursachen kann. CPU und Speicher Edens Schleier Experimentelle Einstellungen zur Verbesserung der Leistung und Funktionalität. Diese Einstellungen können schwarze Bildschirme oder andere Spielprobleme verursachen. diff --git a/src/android/app/src/main/res/values-es/strings.xml b/src/android/app/src/main/res/values-es/strings.xml index 28a93f005b..eff563b7ea 100644 --- a/src/android/app/src/main/res/values-es/strings.xml +++ b/src/android/app/src/main/res/values-es/strings.xml @@ -65,8 +65,6 @@ Extensiones de GPU Renderizador - RAII - Un método de gestión automática de recursos en Vulkan que garantiza la liberación adecuada de recursos cuando ya no son necesarios, pero puede causar fallos en juegos empaquetados. CPU y memoria Velo de Edén Configuraciones experimentales para mejorar el rendimiento y la capacidad. Estas configuraciones pueden causar pantallas negras u otros problemas en el juego. diff --git a/src/android/app/src/main/res/values-fa/strings.xml b/src/android/app/src/main/res/values-fa/strings.xml index b30f67292a..205662b182 100644 --- a/src/android/app/src/main/res/values-fa/strings.xml +++ b/src/android/app/src/main/res/values-fa/strings.xml @@ -65,8 +65,6 @@ افزونه‌های GPU رندرر - RAII - روشی برای مدیریت خودکار منابع در ولکان که تضمین می‌کند منابع به درستی آزاد شوند وقتی دیگر مورد نیاز نیستند، اما ممکن است باعث کرش شدن بازی‌های بسته‌بندی شده شود. پردازنده و حافظه پرده عدن تنظیمات آزمایشی برای بهبود عملکرد و قابلیت. این تنظیمات ممکن است باعث نمایش صفحه سیاه یا سایر مشکلات بازی شود. diff --git a/src/android/app/src/main/res/values-fr/strings.xml b/src/android/app/src/main/res/values-fr/strings.xml index f4c741aecc..12c93fd76c 100644 --- a/src/android/app/src/main/res/values-fr/strings.xml +++ b/src/android/app/src/main/res/values-fr/strings.xml @@ -65,8 +65,6 @@ Extensions GPU Rendu - RAII - Une méthode de gestion automatique des ressources dans Vulkan qui assure la libération correcte des ressources lorsqu\'elles ne sont plus nécessaires, mais peut provoquer des plantages dans les jeux regroupés. CPU et mémoire Voile d\'Eden Paramètres expérimentaux pour améliorer les performances et les capacités. Ces paramètres peuvent causer des écrans noirs ou d\'autres problèmes de jeu. diff --git a/src/android/app/src/main/res/values-he/strings.xml b/src/android/app/src/main/res/values-he/strings.xml index 6c5a877a66..9efaf05085 100644 --- a/src/android/app/src/main/res/values-he/strings.xml +++ b/src/android/app/src/main/res/values-he/strings.xml @@ -65,8 +65,6 @@ הרחבות GPU רנדרר - RAII - שיטה לניהול אוטומטי של משאבים ב-Vulkan המבטיחה שחרור נכון של משאבים כאשר הם כבר לא נחוצים, אך עלולה לגרום לקריסות במשחקים מאוגדים. מעבד וזיכרון עדן וייל הגדרות ניסיוניות לשיפור ביצועים ויכולות. הגדרות אלו עלולות לגרום למסכים שחורים או לבעיות אחרות במשחק. diff --git a/src/android/app/src/main/res/values-hu/strings.xml b/src/android/app/src/main/res/values-hu/strings.xml index 6c4f428086..20b222818f 100644 --- a/src/android/app/src/main/res/values-hu/strings.xml +++ b/src/android/app/src/main/res/values-hu/strings.xml @@ -65,8 +65,6 @@ GPU kiterjesztések Megjelenítő - RAII - A Vulkan erőforrás-kezelési módszere, amely biztosítja az erőforrások megfelelő felszabadítását, ha már nincs rájuk szükség, de csomagolt játékok összeomlását okozhatja. CPU és memória Eden Fátyla Kísérleti beállítások a teljesítmény és képesség javításához. Ezek a beállítások fekete képernyőket vagy más játékproblémákat okozhatnak. diff --git a/src/android/app/src/main/res/values-id/strings.xml b/src/android/app/src/main/res/values-id/strings.xml index 8e89132815..83db153bec 100644 --- a/src/android/app/src/main/res/values-id/strings.xml +++ b/src/android/app/src/main/res/values-id/strings.xml @@ -65,8 +65,6 @@ Ekstensi GPU Renderer - RAII - Metode manajemen sumber daya otomatis di Vulkan yang memastikan pelepasan sumber daya yang tepat ketika tidak lagi diperlukan, tetapi dapat menyebabkan crash pada game yang dibundel. CPU dan Memori Eden\'s Veil Pengaturan eksperimental untuk meningkatkan kinerja dan kemampuan. Pengaturan ini dapat menyebabkan layar hitam atau masalah game lainnya. diff --git a/src/android/app/src/main/res/values-it/strings.xml b/src/android/app/src/main/res/values-it/strings.xml index 339bae8883..7d5c118441 100644 --- a/src/android/app/src/main/res/values-it/strings.xml +++ b/src/android/app/src/main/res/values-it/strings.xml @@ -65,8 +65,6 @@ Estensioni GPU Renderer - RAII - Un metodo di gestione automatica delle risorse in Vulkan che garantisce il corretto rilascio delle risorse quando non sono più necessarie, ma può causare crash nei giochi in bundle. CPU e Memoria Velo di Eden Impostazioni sperimentali per migliorare prestazioni e capacità. Queste impostazioni possono causare schermate nere o altri problemi di gioco. diff --git a/src/android/app/src/main/res/values-ja/strings.xml b/src/android/app/src/main/res/values-ja/strings.xml index 4fc9f135e4..0d0c37c78f 100644 --- a/src/android/app/src/main/res/values-ja/strings.xml +++ b/src/android/app/src/main/res/values-ja/strings.xml @@ -65,8 +65,6 @@ GPU拡張機能 レンダラー - RAII - Vulkanにおける自動リソース管理の方法で、不要になったリソースを適切に解放しますが、バンドルされたゲームでクラッシュを引き起こす可能性があります。 CPUとメモリ エデンのベール パフォーマンスと機能を向上させる実験的な設定。これらの設定は黒画面やその他のゲームの問題を引き起こす可能性があります。 diff --git a/src/android/app/src/main/res/values-ko/strings.xml b/src/android/app/src/main/res/values-ko/strings.xml index ebad3409d7..ff0af4fc43 100644 --- a/src/android/app/src/main/res/values-ko/strings.xml +++ b/src/android/app/src/main/res/values-ko/strings.xml @@ -65,8 +65,6 @@ GPU 확장 기능 렌더러 - RAII - Vulkan에서 자동 리소스 관리를 위한 방법으로, 더 이상 필요하지 않은 리소스를 적절히 해제하지만 번들된 게임에서 충돌을 일으킬 수 있습니다. CPU 및 메모리 에덴의 베일 성능 및 기능을 향상시키기 위한 실험적 설정. 이 설정은 검은 화면 또는 기타 게임 문제를 일으킬 수 있습니다. diff --git a/src/android/app/src/main/res/values-nb/strings.xml b/src/android/app/src/main/res/values-nb/strings.xml index 4a5f6f2efb..313d8797c3 100644 --- a/src/android/app/src/main/res/values-nb/strings.xml +++ b/src/android/app/src/main/res/values-nb/strings.xml @@ -65,8 +65,6 @@ GPU-utvidelser Renderer - RAII - En metode for automatisk ressurshåndtering i Vulkan som sikrer riktig frigjøring av ressurser når de ikke lenger trengs, men kan føre til krasj i bundlede spill. CPU og minne Edens slør Eksperimentelle innstillinger for å forbedre ytelse og funksjonalitet. Disse innstillingene kan forårsake svarte skjermer eller andre spillproblemer. diff --git a/src/android/app/src/main/res/values-pl/strings.xml b/src/android/app/src/main/res/values-pl/strings.xml index d1bc789aa9..4ebe24e1c9 100644 --- a/src/android/app/src/main/res/values-pl/strings.xml +++ b/src/android/app/src/main/res/values-pl/strings.xml @@ -65,8 +65,6 @@ Rozszerzenia GPU Renderer - RAII - Metoda automatycznego zarządzania zasobami w Vulkanie, która zapewnia prawidłowe zwalnianie zasobów, gdy nie są już potrzebne, ale może powodować awarie w pakietowych grach. Procesor i pamięć Zasłona Edenu Eksperymentalne ustawienia poprawiające wydajność i możliwości. Te ustawienia mogą powodować czarne ekrany lub inne problemy z grą. diff --git a/src/android/app/src/main/res/values-pt-rBR/strings.xml b/src/android/app/src/main/res/values-pt-rBR/strings.xml index bad95a18e5..2f5f4c4b5b 100644 --- a/src/android/app/src/main/res/values-pt-rBR/strings.xml +++ b/src/android/app/src/main/res/values-pt-rBR/strings.xml @@ -65,8 +65,6 @@ Extensões da GPU Renderizador - RAII - Um método de gerenciamento automático de recursos no Vulkan que garante a liberação adequada de recursos quando não são mais necessários, mas pode causar falhas em jogos empacotados. CPU e Memória Véu do Éden Configurações experimentais para melhorar desempenho e capacidade. Essas configurações podem causar telas pretas ou outros problemas no jogo. diff --git a/src/android/app/src/main/res/values-pt-rPT/strings.xml b/src/android/app/src/main/res/values-pt-rPT/strings.xml index 0b57eebab6..084fe1c82d 100644 --- a/src/android/app/src/main/res/values-pt-rPT/strings.xml +++ b/src/android/app/src/main/res/values-pt-rPT/strings.xml @@ -65,8 +65,6 @@ Extensões da GPU Renderizador - RAII - Um método de gestão automática de recursos no Vulkan que garante a libertação adequada de recursos quando já não são necessários, mas pode causar falhas em jogos empacotados. CPU e Memória Véu do Éden Definições experimentais para melhorar o desempenho e capacidade. Estas definições podem causar ecrãs pretos ou outros problemas no jogo. diff --git a/src/android/app/src/main/res/values-ru/strings.xml b/src/android/app/src/main/res/values-ru/strings.xml index 53f49b91cb..0938b9c18f 100644 --- a/src/android/app/src/main/res/values-ru/strings.xml +++ b/src/android/app/src/main/res/values-ru/strings.xml @@ -72,8 +72,6 @@ Настройки в Покров Эдема являются экспериментальными и могут вызывать проблемы. Если ваша игра не запускается, отключите все расширения. В разработке: Пропуск кадров Включите или отключите пропуск кадров для повышения производительности за счет уменьшения количества отображаемых кадров. Эта функция находится в разработке и будет включена в будущих версиях. - RAII - Метод автоматического управления ресурсами в Vulkan, который обеспечивает правильное освобождение ресурсов при их ненадобности, но может вызывать сбои в бандл-играх. Улучшенная синхронизация кадров Обеспечивает плавную и стабильную подачу кадров за счет синхронизации их времени, уменьшая подтормаживания и неравномерную анимацию. Идеально для игр с нестабильным временем кадров или микро-подтормаживаниями во время игры. Ранний релиз ограждений diff --git a/src/android/app/src/main/res/values-sr/strings.xml b/src/android/app/src/main/res/values-sr/strings.xml index 3f2de72f8b..35ef07f3a6 100644 --- a/src/android/app/src/main/res/values-sr/strings.xml +++ b/src/android/app/src/main/res/values-sr/strings.xml @@ -81,8 +81,6 @@ Побољшава текстуру и руковање међуспремника, као и преводилачки слој Маквелл. Подржани од стране неких Вулкана 1.1 ГПУ-а и сви Вулкан 1.2+ ГПУ. Рендерер - RAII - Метод аутоматског управљања ресурсима у Vulkan-у који осигурава правилно ослобађање ресурса када више нису потребни, али може изазвати падове у пакованим играма. Побољшани оквирни пејсинг Осигурава глатку и доследан испоруку оквира синхронизацијом времена између оквира, смањење муцања и неуједначене анимације. Идеално за игре које доживљавају временски оквир нестабилност или микро-штитнике током играња. Ranije oslobađanje ograda diff --git a/src/android/app/src/main/res/values-uk/strings.xml b/src/android/app/src/main/res/values-uk/strings.xml index b5eee4992c..b22c30999b 100644 --- a/src/android/app/src/main/res/values-uk/strings.xml +++ b/src/android/app/src/main/res/values-uk/strings.xml @@ -70,8 +70,6 @@ Експериментальні налаштування для покращення продуктивності та сумісності. Ці налаштування можуть викликати збої, зокрема чорний екран. Експериментальні налаштування Налаштування Завіси Eden є експериментальними та можуть спричинити проблеми. Якщо ваша гра не запускається — вимкніть усі розширення. - RAII - Метод автоматичного керування ресурсами у Vulkan, який забезпечує правильне звільнення ресурсів після завершення їх використання, проте він може спричинити збої в ігрових збірниках. В розробці: Пропуск кадрів Увімкніть або вимкніть пропуск кадрів для покращення продуктивності за рахунок зменшення кількості візуалізованих кадрів. Ця функція ще розробляється та буде доступна у майбутніх версіях. Покращена синхронізація кадрів diff --git a/src/android/app/src/main/res/values-vi/strings.xml b/src/android/app/src/main/res/values-vi/strings.xml index 1a34509f5c..171b4ea116 100644 --- a/src/android/app/src/main/res/values-vi/strings.xml +++ b/src/android/app/src/main/res/values-vi/strings.xml @@ -65,8 +65,6 @@ Tiện ích mở rộng GPU Trình kết xuất - RAII - Phương pháp quản lý tài nguyên tự động trong Vulkan đảm bảo giải phóng tài nguyên đúng cách khi không còn cần thiết, nhưng có thể gây ra sự cố trong các trò chơi được đóng gói. CPU và Bộ nhớ Mành che của Eden Cài đặt thử nghiệm để cải thiện hiệu suất và khả năng. Những cài đặt này có thể gây ra màn hình đen hoặc các vấn đề khác trong trò chơi. diff --git a/src/android/app/src/main/res/values-zh-rCN/strings.xml b/src/android/app/src/main/res/values-zh-rCN/strings.xml index 6fa40b8727..daa2143beb 100644 --- a/src/android/app/src/main/res/values-zh-rCN/strings.xml +++ b/src/android/app/src/main/res/values-zh-rCN/strings.xml @@ -65,8 +65,6 @@ GPU扩展 渲染器 - RAII - Vulkan中的一种自动资源管理方法,确保在不再需要时正确释放资源,但可能导致捆绑游戏崩溃。 CPU和内存 伊甸之幕 实验性设置以提高性能和能力。这些设置可能会导致黑屏或其他游戏问题。 diff --git a/src/android/app/src/main/res/values-zh-rTW/strings.xml b/src/android/app/src/main/res/values-zh-rTW/strings.xml index b73ec8ccaa..67f3f268a8 100644 --- a/src/android/app/src/main/res/values-zh-rTW/strings.xml +++ b/src/android/app/src/main/res/values-zh-rTW/strings.xml @@ -65,8 +65,6 @@ GPU擴充功能 渲染器 - RAII - Vulkan中的一種自動資源管理方法,確保在不再需要時正確釋放資源,但可能導致捆綁遊戲崩潰。 CPU與記憶體 伊甸之幕 實驗性設定以提高效能和能力。這些設定可能會導致黑屏或其他遊戲問題。 diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index cff0bab2b5..00206a5df5 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -109,8 +109,6 @@ The intensity of the sample shading pass. Higher values improve quality more but also reduce performance to a greater extent. Renderer - RAII - A method of automatic resource management in Vulkan that ensures proper release of resources when they are no longer needed, but may cause crashes in bundled games. Enhanced Frame Pacing Ensures smooth and consistent frame delivery by synchronizing the timing between frames, reducing stuttering and uneven animation. Ideal for games that experience frame timing instability or micro-stutters during gameplay. Release Fences Early diff --git a/src/common/settings.h b/src/common/settings.h index 59e75d3ee0..c6b52f7ba3 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -336,7 +336,6 @@ struct Values { "shader_backend", Category::Renderer, Specialization::RuntimeList}; SwitchableSetting vulkan_device{linkage, 0, "vulkan_device", Category::Renderer, Specialization::RuntimeList}; - SwitchableSetting enable_raii{linkage, false, "enable_raii", Category::Renderer}; #ifdef __ANDROID__ SwitchableSetting frame_interpolation{linkage, true, "frame_interpolation", Category::Renderer, Specialization::RuntimeList}; diff --git a/src/qt_common/shared_translation.cpp b/src/qt_common/shared_translation.cpp index f926f506e7..0b40ca9904 100644 --- a/src/qt_common/shared_translation.cpp +++ b/src/qt_common/shared_translation.cpp @@ -320,12 +320,6 @@ std::unique_ptr InitializeTranslations(QObject* parent) tr("Improves rendering of transparency effects in specific games.")); // Renderer (Extensions) - INSERT(Settings, - enable_raii, - tr("RAII"), - tr("A method of automatic resource management in Vulkan " - "that ensures proper release of resources " - "when they are no longer needed, but may cause crashes in bundled games.")); INSERT(Settings, dyna_state, tr("Extended Dynamic State"), @@ -721,3 +715,4 @@ std::unique_ptr ComboboxEnumeration(QObject* parent) return translations; } } // namespace ConfigurationShared + diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 6f3a0e4cd1..e6e72cdca7 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -164,15 +164,6 @@ try PresentFiltersForAppletCapture) , rasterizer(render_window, gpu, device_memory, device, memory_allocator, state_tracker, scheduler) { - // Initialize RAII wrappers after creating the main objects - if (Settings::values.enable_raii.GetValue()) { - managed_instance = MakeManagedInstance(instance, dld); - if (Settings::values.renderer_debug) { - managed_debug_messenger = MakeManagedDebugUtilsMessenger(debug_messenger, instance, dld); - } - managed_surface = MakeManagedSurface(surface, instance, dld); - } - if (Settings::values.renderer_force_max_clock.GetValue() && device.ShouldBoostClocks()) { turbo_mode.emplace(instance, dld); scheduler.RegisterOnSubmit([this] { turbo_mode->QueueSubmitted(); }); diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index c1e6d5db7f..4fb88b29de 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -20,7 +23,6 @@ #include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_memory_allocator.h" #include "video_core/vulkan_common/vulkan_wrapper.h" -#include "video_core/vulkan_common/vulkan_raii.h" namespace Core::Memory { class Memory; @@ -78,16 +80,10 @@ private: // Keep original handles for compatibility with existing code vk::Instance instance; - // RAII wrapper for instance - ManagedInstance managed_instance; vk::DebugUtilsMessenger debug_messenger; - // RAII wrapper for debug messenger - ManagedDebugUtilsMessenger managed_debug_messenger; vk::SurfaceKHR surface; - // RAII wrapper for surface - ManagedSurface managed_surface; Device device; MemoryAllocator memory_allocator; diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 3b35e28c05..fdd2de2379 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -351,6 +351,7 @@ void Swapchain::CreateSemaphores() { void Swapchain::Destroy() { frame_index = 0; present_semaphores.clear(); + render_semaphores.clear(); swapchain.reset(); } diff --git a/src/video_core/vulkan_common/vulkan_raii.h b/src/video_core/vulkan_common/vulkan_raii.h deleted file mode 100644 index cf5e268b68..0000000000 --- a/src/video_core/vulkan_common/vulkan_raii.h +++ /dev/null @@ -1,231 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2025 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include -#include - -#include "common/logging/log.h" - -#include "video_core/vulkan_common/vulkan_wrapper.h" - -namespace Vulkan { - -/** - * RAII wrapper for Vulkan resources. - * Automatically manages the lifetime of Vulkan objects using RAII principles. - */ -template -class VulkanRaii { -public: - using DeleterFunc = std::function; - - // Default constructor - creates a null handle - VulkanRaii() : handle{}, deleter{}, dispatch{} {} - - // Constructor with handle and deleter - VulkanRaii(T handle_, DeleterFunc deleter_, const Dispatch& dispatch_, const char* resource_name = "Vulkan resource") - : handle{handle_}, deleter{std::move(deleter_)}, dispatch{dispatch_} { - LOG_DEBUG(Render_Vulkan, "RAII wrapper created for {}", resource_name); - } - - // Move constructor - VulkanRaii(VulkanRaii&& other) noexcept - : handle{std::exchange(other.handle, VK_NULL_HANDLE)}, - deleter{std::move(other.deleter)}, - dispatch{other.dispatch} { - } - - // Move assignment - VulkanRaii& operator=(VulkanRaii&& other) noexcept { - if (this != &other) { - cleanup(); - handle = std::exchange(other.handle, VK_NULL_HANDLE); - deleter = std::move(other.deleter); - dispatch = other.dispatch; - } - return *this; - } - - // Destructor - automatically cleans up the resource - ~VulkanRaii() { - cleanup(); - } - - // Disallow copying - VulkanRaii(const VulkanRaii&) = delete; - VulkanRaii& operator=(const VulkanRaii&) = delete; - - // Get the underlying handle - T get() const noexcept { - return handle; - } - - // Check if the handle is valid - bool valid() const noexcept { - return handle != VK_NULL_HANDLE; - } - - // Release ownership of the handle without destroying it - T release() noexcept { - return std::exchange(handle, VK_NULL_HANDLE); - } - - // Reset the handle (destroying the current one if it exists) - void reset(T new_handle = VK_NULL_HANDLE, DeleterFunc new_deleter = {}) { - cleanup(); - handle = new_handle; - deleter = std::move(new_deleter); - } - - // Implicit conversion to handle type - operator T() const noexcept { - return handle; - } - - // Dereference operator for pointer-like access - T operator->() const noexcept { - return handle; - } - -private: - // Optimized cleanup function - void cleanup() noexcept { - if (handle != VK_NULL_HANDLE && deleter) { - deleter(handle, dispatch); - handle = VK_NULL_HANDLE; - } - } - - T handle; - DeleterFunc deleter; - Dispatch dispatch; -}; - -// Common type aliases for Vulkan RAII wrappers with clearer names -using ManagedInstance = VulkanRaii; -using ManagedDevice = VulkanRaii; -using ManagedSurface = VulkanRaii; -using ManagedSwapchain = VulkanRaii; -using ManagedCommandPool = VulkanRaii; -using ManagedBuffer = VulkanRaii; -using ManagedImage = VulkanRaii; -using ManagedImageView = VulkanRaii; -using ManagedSampler = VulkanRaii; -using ManagedShaderModule = VulkanRaii; -using ManagedPipeline = VulkanRaii; -using ManagedPipelineLayout = VulkanRaii; -using ManagedDescriptorSetLayout = VulkanRaii; -using ManagedDescriptorPool = VulkanRaii; -using ManagedSemaphore = VulkanRaii; -using ManagedFence = VulkanRaii; -using ManagedDebugUtilsMessenger = VulkanRaii; - -// Helper functions to create RAII wrappers - -/** - * Creates an RAII wrapper for a Vulkan instance - */ -inline ManagedInstance MakeManagedInstance(const vk::Instance& instance, const vk::InstanceDispatch& dispatch) { - auto deleter = [](VkInstance handle, const vk::InstanceDispatch& dld) { - dld.vkDestroyInstance(handle, nullptr); - }; - return ManagedInstance(*instance, deleter, dispatch, "VkInstance"); -} - -/** - * Creates an RAII wrapper for a Vulkan device - */ -inline ManagedDevice MakeManagedDevice(const vk::Device& device, const vk::DeviceDispatch& dispatch) { - auto deleter = [](VkDevice handle, const vk::DeviceDispatch& dld) { - dld.vkDestroyDevice(handle, nullptr); - }; - return ManagedDevice(*device, deleter, dispatch, "VkDevice"); -} - -/** - * Creates an RAII wrapper for a Vulkan surface - */ -inline ManagedSurface MakeManagedSurface(const vk::SurfaceKHR& surface, const vk::Instance& instance, const vk::InstanceDispatch& dispatch) { - auto deleter = [instance_ptr = *instance](VkSurfaceKHR handle, const vk::InstanceDispatch& dld) { - dld.vkDestroySurfaceKHR(instance_ptr, handle, nullptr); - }; - return ManagedSurface(*surface, deleter, dispatch, "VkSurfaceKHR"); -} - -/** - * Creates an RAII wrapper for a Vulkan debug messenger - */ -inline ManagedDebugUtilsMessenger MakeManagedDebugUtilsMessenger(const vk::DebugUtilsMessenger& messenger, - const vk::Instance& instance, - const vk::InstanceDispatch& dispatch) { - auto deleter = [instance_ptr = *instance](VkDebugUtilsMessengerEXT handle, const vk::InstanceDispatch& dld) { - dld.vkDestroyDebugUtilsMessengerEXT(instance_ptr, handle, nullptr); - }; - return ManagedDebugUtilsMessenger(*messenger, deleter, dispatch, "VkDebugUtilsMessengerEXT"); -} - -/** - * Creates an RAII wrapper for a Vulkan swapchain - */ -inline ManagedSwapchain MakeManagedSwapchain(VkSwapchainKHR swapchain_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) { - auto deleter = [device_handle](VkSwapchainKHR handle, const vk::DeviceDispatch& dld) { - dld.vkDestroySwapchainKHR(device_handle, handle, nullptr); - }; - return ManagedSwapchain(swapchain_handle, deleter, dispatch, "VkSwapchainKHR"); -} - -/** - * Creates an RAII wrapper for a Vulkan buffer - */ -inline ManagedBuffer MakeManagedBuffer(VkBuffer buffer_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) { - auto deleter = [device_handle](VkBuffer handle, const vk::DeviceDispatch& dld) { - dld.vkDestroyBuffer(device_handle, handle, nullptr); - }; - return ManagedBuffer(buffer_handle, deleter, dispatch, "VkBuffer"); -} - -/** - * Creates an RAII wrapper for a Vulkan image - */ -inline ManagedImage MakeManagedImage(VkImage image_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) { - auto deleter = [device_handle](VkImage handle, const vk::DeviceDispatch& dld) { - dld.vkDestroyImage(device_handle, handle, nullptr); - }; - return ManagedImage(image_handle, deleter, dispatch, "VkImage"); -} - -/** - * Creates an RAII wrapper for a Vulkan image view - */ -inline ManagedImageView MakeManagedImageView(VkImageView view_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) { - auto deleter = [device_handle](VkImageView handle, const vk::DeviceDispatch& dld) { - dld.vkDestroyImageView(device_handle, handle, nullptr); - }; - return ManagedImageView(view_handle, deleter, dispatch, "VkImageView"); -} - -/** - * Creates an RAII wrapper for a Vulkan semaphore - */ -inline ManagedSemaphore MakeManagedSemaphore(VkSemaphore semaphore_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) { - auto deleter = [device_handle](VkSemaphore handle, const vk::DeviceDispatch& dld) { - dld.vkDestroySemaphore(device_handle, handle, nullptr); - }; - return ManagedSemaphore(semaphore_handle, deleter, dispatch, "VkSemaphore"); -} - -/** - * Creates an RAII wrapper for a Vulkan fence - */ -inline ManagedFence MakeManagedFence(VkFence fence_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) { - auto deleter = [device_handle](VkFence handle, const vk::DeviceDispatch& dld) { - dld.vkDestroyFence(device_handle, handle, nullptr); - }; - return ManagedFence(fence_handle, deleter, dispatch, "VkFence"); -} - -} // namespace Vulkan \ No newline at end of file diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 949b91499d..b77d01711a 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp @@ -12,7 +12,6 @@ #include "common/common_types.h" #include "common/logging/log.h" -#include "common/settings.h" #include "video_core/vulkan_common/vk_enum_string_helper.h" #include "video_core/vulkan_common/vma.h" #include "video_core/vulkan_common/vulkan_wrapper.h" @@ -311,10 +310,7 @@ const char* Exception::what() const noexcept { } void Destroy(VkInstance instance, const InstanceDispatch& dld) noexcept { - // FIXME: A double free occurs here if RAII is enabled. - if (!Settings::values.enable_raii.GetValue()) { - dld.vkDestroyInstance(instance, nullptr); - } + dld.vkDestroyInstance(instance, nullptr); } void Destroy(VkDevice device, const InstanceDispatch& dld) noexcept { @@ -417,10 +413,7 @@ void Destroy(VkInstance instance, VkDebugReportCallbackEXT handle, } void Destroy(VkInstance instance, VkSurfaceKHR handle, const InstanceDispatch& dld) noexcept { - // FIXME: A double free occurs here if RAII is enabled. - if (!Settings::values.enable_raii.GetValue()) { - dld.vkDestroySurfaceKHR(instance, handle, nullptr); - } + dld.vkDestroySurfaceKHR(instance, handle, nullptr); } VkResult Free(VkDevice device, VkDescriptorPool handle, Span sets, diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index 6501094f05..39396b3279 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h @@ -516,7 +516,7 @@ public: } /// Returns true when there's a held object. - operator bool() const noexcept { + explicit operator bool() const noexcept { return handle != nullptr; } @@ -627,7 +627,7 @@ class Instance : public Handle { public: /// Creates a Vulkan instance. /// @throw Exception on initialization error. - static Instance Create(u32 version, Span layers, Span extensions, + [[nodiscard]] static Instance Create(u32 version, Span layers, Span extensions, InstanceDispatch& dispatch); /// Enumerates physical devices. @@ -637,12 +637,12 @@ public: /// Creates a debug callback messenger. /// @throw Exception on creation failure. - DebugUtilsMessenger CreateDebugUtilsMessenger( + [[nodiscard]] DebugUtilsMessenger CreateDebugUtilsMessenger( const VkDebugUtilsMessengerCreateInfoEXT& create_info) const; /// Creates a debug report callback. /// @throw Exception on creation failure. - DebugReportCallback CreateDebugReportCallback( + [[nodiscard]] DebugReportCallback CreateDebugReportCallback( const VkDebugReportCallbackCreateInfoEXT& create_info) const; /// Returns dispatch table. @@ -986,58 +986,60 @@ class Device : public Handle { using Handle::Handle; public: - static Device Create(VkPhysicalDevice physical_device, Span queues_ci, - Span enabled_extensions, const void* next, - DeviceDispatch& dispatch); + [[nodiscard]] static Device Create(VkPhysicalDevice physical_device, + Span queues_ci, + Span enabled_extensions, const void* next, + DeviceDispatch& dispatch); - Queue GetQueue(u32 family_index) const noexcept; + [[nodiscard]] Queue GetQueue(u32 family_index) const noexcept; - BufferView CreateBufferView(const VkBufferViewCreateInfo& ci) const; + [[nodiscard]] BufferView CreateBufferView(const VkBufferViewCreateInfo& ci) const; - ImageView CreateImageView(const VkImageViewCreateInfo& ci) const; + [[nodiscard]] ImageView CreateImageView(const VkImageViewCreateInfo& ci) const; - Semaphore CreateSemaphore() const; + [[nodiscard]] Semaphore CreateSemaphore() const; - Semaphore CreateSemaphore(const VkSemaphoreCreateInfo& ci) const; + [[nodiscard]] Semaphore CreateSemaphore(const VkSemaphoreCreateInfo& ci) const; - Fence CreateFence(const VkFenceCreateInfo& ci) const; + [[nodiscard]] Fence CreateFence(const VkFenceCreateInfo& ci) const; - DescriptorPool CreateDescriptorPool(const VkDescriptorPoolCreateInfo& ci) const; + [[nodiscard]] DescriptorPool CreateDescriptorPool(const VkDescriptorPoolCreateInfo& ci) const; - RenderPass CreateRenderPass(const VkRenderPassCreateInfo& ci) const; + [[nodiscard]] RenderPass CreateRenderPass(const VkRenderPassCreateInfo& ci) const; - DescriptorSetLayout CreateDescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo& ci) const; + [[nodiscard]] DescriptorSetLayout CreateDescriptorSetLayout( + const VkDescriptorSetLayoutCreateInfo& ci) const; - PipelineCache CreatePipelineCache(const VkPipelineCacheCreateInfo& ci) const; + [[nodiscard]] PipelineCache CreatePipelineCache(const VkPipelineCacheCreateInfo& ci) const; - PipelineLayout CreatePipelineLayout(const VkPipelineLayoutCreateInfo& ci) const; + [[nodiscard]] PipelineLayout CreatePipelineLayout(const VkPipelineLayoutCreateInfo& ci) const; - Pipeline CreateGraphicsPipeline(const VkGraphicsPipelineCreateInfo& ci, - VkPipelineCache cache = nullptr) const; + [[nodiscard]] Pipeline CreateGraphicsPipeline(const VkGraphicsPipelineCreateInfo& ci, + VkPipelineCache cache = nullptr) const; - Pipeline CreateComputePipeline(const VkComputePipelineCreateInfo& ci, - VkPipelineCache cache = nullptr) const; + [[nodiscard]] Pipeline CreateComputePipeline(const VkComputePipelineCreateInfo& ci, + VkPipelineCache cache = nullptr) const; - Sampler CreateSampler(const VkSamplerCreateInfo& ci) const; + [[nodiscard]] Sampler CreateSampler(const VkSamplerCreateInfo& ci) const; - Framebuffer CreateFramebuffer(const VkFramebufferCreateInfo& ci) const; + [[nodiscard]] Framebuffer CreateFramebuffer(const VkFramebufferCreateInfo& ci) const; - CommandPool CreateCommandPool(const VkCommandPoolCreateInfo& ci) const; + [[nodiscard]] CommandPool CreateCommandPool(const VkCommandPoolCreateInfo& ci) const; - DescriptorUpdateTemplate CreateDescriptorUpdateTemplate( + [[nodiscard]] DescriptorUpdateTemplate CreateDescriptorUpdateTemplate( const VkDescriptorUpdateTemplateCreateInfo& ci) const; - QueryPool CreateQueryPool(const VkQueryPoolCreateInfo& ci) const; + [[nodiscard]] QueryPool CreateQueryPool(const VkQueryPoolCreateInfo& ci) const; - ShaderModule CreateShaderModule(const VkShaderModuleCreateInfo& ci) const; + [[nodiscard]] ShaderModule CreateShaderModule(const VkShaderModuleCreateInfo& ci) const; - Event CreateEvent() const; + [[nodiscard]] Event CreateEvent() const; - SwapchainKHR CreateSwapchainKHR(const VkSwapchainCreateInfoKHR& ci) const; + [[nodiscard]] SwapchainKHR CreateSwapchainKHR(const VkSwapchainCreateInfoKHR& ci) const; - DeviceMemory TryAllocateMemory(const VkMemoryAllocateInfo& ai) const noexcept; + [[nodiscard]] DeviceMemory TryAllocateMemory(const VkMemoryAllocateInfo& ai) const noexcept; - DeviceMemory AllocateMemory(const VkMemoryAllocateInfo& ai) const; + [[nodiscard]] DeviceMemory AllocateMemory(const VkMemoryAllocateInfo& ai) const; VkMemoryRequirements GetBufferMemoryRequirements(VkBuffer buffer, void* pnext = nullptr) const noexcept; From 8078990b9b95c5bb2c432abc9012c2738f8a451a Mon Sep 17 00:00:00 2001 From: Ribbit Date: Wed, 8 Oct 2025 05:39:08 +0200 Subject: [PATCH 17/24] [vk] Fast UBO: fix tracking, resize heuristics, add debug guard (#2695) Co-authored-by: Ribbit Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2695 Reviewed-by: CamilleLaVey Co-authored-by: Ribbit Co-committed-by: Ribbit --- src/core/device_memory_manager.h | 6 +++ src/core/device_memory_manager.inc | 26 ++++++++++++ src/video_core/buffer_cache/buffer_cache.h | 42 ++++++++++--------- .../buffer_cache/buffer_cache_base.h | 5 ++- .../vk_staging_buffer_pool.cpp | 26 +++++++----- .../renderer_vulkan/vk_staging_buffer_pool.h | 4 ++ 6 files changed, 76 insertions(+), 33 deletions(-) diff --git a/src/core/device_memory_manager.h b/src/core/device_memory_manager.h index 6dcf7bb228..192c6e5c01 100644 --- a/src/core/device_memory_manager.h +++ b/src/core/device_memory_manager.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -109,6 +112,9 @@ public: void ReadBlock(DAddr address, void* dest_pointer, size_t size); void ReadBlockUnsafe(DAddr address, void* dest_pointer, size_t size); +#ifdef YUZU_DEBUG + bool ReadBlockFastChecked(DAddr address, void* dest_pointer, size_t size); +#endif void WriteBlock(DAddr address, const void* src_pointer, size_t size); void WriteBlockUnsafe(DAddr address, const void* src_pointer, size_t size); diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc index 52dff5df9a..3629579c09 100644 --- a/src/core/device_memory_manager.inc +++ b/src/core/device_memory_manager.inc @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -467,6 +470,29 @@ void DeviceMemoryManager::ReadBlockUnsafe(DAddr address, void* dest_poin }); } +#ifdef YUZU_DEBUG +template +bool DeviceMemoryManager::ReadBlockFastChecked(DAddr address, void* dest_pointer, + size_t size) { + bool success = true; + WalkBlock( + address, size, + [&](size_t copy_amount, DAddr current_vaddr) { + LOG_CRITICAL(Render, "DeviceMemory OOB/unmapped: addr=0x{:x} size={}", current_vaddr, + size); + std::memset(dest_pointer, 0, copy_amount); + success = false; + }, + [&](size_t copy_amount, const u8* const src_ptr) { + std::memcpy(dest_pointer, src_ptr, copy_amount); + }, + [&](const std::size_t copy_amount) { + dest_pointer = static_cast(dest_pointer) + copy_amount; + }); + return success; +} +#endif + template void DeviceMemoryManager::WriteBlockUnsafe(DAddr address, const void* src_pointer, size_t size) { diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 5223afe937..388c8034c5 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -386,11 +386,10 @@ void BufferCache

::BindHostComputeBuffers() { template void BufferCache

::SetUniformBuffersState(const std::array& mask, const UniformBufferSizes* sizes) { - if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { - if (channel_state->enabled_uniform_buffer_masks != mask) { - if constexpr (IS_OPENGL) { - channel_state->fast_bound_uniform_buffers.fill(0); - } + const bool mask_changed = channel_state->enabled_uniform_buffer_masks != mask; + if (mask_changed) { + channel_state->fast_bound_uniform_buffers.fill(0); + if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { channel_state->dirty_uniform_buffers.fill(~u32{0}); channel_state->uniform_buffer_binding_sizes.fill({}); } @@ -806,7 +805,7 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 channel_state->uniform_buffer_binding_sizes[stage][binding_index] != size; if (should_fast_bind) { // We only have to bind when the currently bound buffer is not the fast version - channel_state->fast_bound_uniform_buffers[stage] |= 1U << binding_index; + channel_state->fast_bound_uniform_buffers[stage] |= 1u << binding_index; channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size; runtime.BindFastUniformBuffer(stage, binding_index, size); } @@ -815,13 +814,22 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 return; } } - if constexpr (IS_OPENGL) { - channel_state->fast_bound_uniform_buffers[stage] |= 1U << binding_index; - channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size; - } + channel_state->fast_bound_uniform_buffers[stage] |= 1u << binding_index; + channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size; // Stream buffer path to avoid stalling on non-Nvidia drivers or Vulkan const std::span span = runtime.BindMappedUniformBuffer(stage, binding_index, size); +#ifdef YUZU_DEBUG + ASSERT(binding_index < NUM_GRAPHICS_UNIFORM_BUFFERS); + ASSERT(span.size() >= size && "UBO stream span too small"); + if (!device_memory.ReadBlockFastChecked(device_addr, span.data(), size)) { + LOG_CRITICAL(Render, "DeviceMemory OOB/unmapped: addr=0x{:x} size={}", device_addr, size); + channel_state->fast_bound_uniform_buffers[stage] &= ~(1u << binding_index); + ASSERT(false); + return; + } +#else device_memory.ReadBlockUnsafe(device_addr, span.data(), size); +#endif return; } // Classic cached path @@ -830,7 +838,8 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 } // Skip binding if it's not needed and if the bound buffer is not the fast version // This exists to avoid instances where the fast buffer is bound and a GPU write happens - needs_bind |= HasFastUniformBufferBound(stage, binding_index); + const bool was_fast_bound = HasFastUniformBufferBound(stage, binding_index); + needs_bind |= was_fast_bound; if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { needs_bind |= channel_state->uniform_buffer_binding_sizes[stage][binding_index] != size; } @@ -839,9 +848,6 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 } const u32 offset = buffer.Offset(device_addr); if constexpr (IS_OPENGL) { - // Fast buffer will be unbound - channel_state->fast_bound_uniform_buffers[stage] &= ~(1U << binding_index); - // Mark the index as dirty if offset doesn't match const bool is_copy_bind = offset != 0 && !runtime.SupportsNonZeroUniformOffset(); channel_state->dirty_uniform_buffers[stage] |= (is_copy_bind ? 1U : 0U) << index; @@ -855,6 +861,7 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 } else { runtime.BindUniformBuffer(buffer, offset, size); } + channel_state->fast_bound_uniform_buffers[stage] &= ~(1u << binding_index); } template @@ -1789,12 +1796,7 @@ std::span BufferCache

::ImmediateBuffer(size_t wanted_capacity) { template bool BufferCache

::HasFastUniformBufferBound(size_t stage, u32 binding_index) const noexcept { - if constexpr (IS_OPENGL) { - return ((channel_state->fast_bound_uniform_buffers[stage] >> binding_index) & 1) != 0; - } else { - // Only OpenGL has fast uniform buffers - return false; - } + return ((channel_state->fast_bound_uniform_buffers[stage] >> binding_index) & 1u) != 0; } template diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h index 486d19fb79..09631ffd83 100644 --- a/src/video_core/buffer_cache/buffer_cache_base.h +++ b/src/video_core/buffer_cache/buffer_cache_base.h @@ -53,6 +53,7 @@ constexpr u32 NUM_COMPUTE_UNIFORM_BUFFERS = 8; constexpr u32 NUM_STORAGE_BUFFERS = 16; constexpr u32 NUM_TEXTURE_BUFFERS = 32; constexpr u32 NUM_STAGES = 5; +static_assert(NUM_GRAPHICS_UNIFORM_BUFFERS <= 32, "fast bitmask must fit u32"); using UniformBufferSizes = std::array, NUM_STAGES>; using ComputeUniformBufferSizes = std::array; @@ -137,8 +138,8 @@ public: u32 written_compute_texture_buffers = 0; u32 image_compute_texture_buffers = 0; - std::array uniform_cache_hits{}; - std::array uniform_cache_shots{}; + std::array uniform_cache_hits{}; + std::array uniform_cache_shots{}; u32 uniform_buffer_skip_cache_size = DEFAULT_SKIP_CACHE_SIZE; diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp index ecc4f77dc7..0fbe707b04 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp @@ -25,12 +25,12 @@ namespace { using namespace Common::Literals; -// Maximum potential alignment of a Vulkan buffer -constexpr VkDeviceSize MAX_ALIGNMENT = 256; +// Minimum alignment we want to enforce for the streaming ring +constexpr VkDeviceSize MIN_STREAM_ALIGNMENT = 256; // Stream buffer size in bytes constexpr VkDeviceSize MAX_STREAM_BUFFER_SIZE = 128_MiB; -size_t GetStreamBufferSize(const Device& device) { +size_t GetStreamBufferSize(const Device& device, VkDeviceSize alignment) { VkDeviceSize size{0}; if (device.HasDebuggingToolAttached()) { bool found_heap = false; @@ -53,8 +53,9 @@ size_t GetStreamBufferSize(const Device& device) { // Clamp to the configured maximum, align up for safety, and ensure a sane minimum so // region_size (stream_buffer_size / NUM_SYNCS) never becomes zero. - const VkDeviceSize aligned = (std::min)(Common::AlignUp(size, MAX_ALIGNMENT), MAX_STREAM_BUFFER_SIZE); - const VkDeviceSize min_size = MAX_ALIGNMENT * StagingBufferPool::NUM_SYNCS; + const VkDeviceSize aligned = + (std::min)(Common::AlignUp(size, alignment), MAX_STREAM_BUFFER_SIZE); + const VkDeviceSize min_size = alignment * StagingBufferPool::NUM_SYNCS; return static_cast((std::max)(aligned, min_size)); } } // Anonymous namespace @@ -62,8 +63,10 @@ size_t GetStreamBufferSize(const Device& device) { StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_, Scheduler& scheduler_) : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, - stream_buffer_size{GetStreamBufferSize(device)}, region_size{stream_buffer_size / - StagingBufferPool::NUM_SYNCS} { + stream_alignment{std::max(device_.GetUniformBufferAlignment(), + MIN_STREAM_ALIGNMENT)}, + stream_buffer_size{GetStreamBufferSize(device_, stream_alignment)}, + region_size{stream_buffer_size / StagingBufferPool::NUM_SYNCS} { VkBufferCreateInfo stream_ci = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .pNext = nullptr, @@ -116,10 +119,11 @@ void StagingBufferPool::TickFrame() { } StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) { - const size_t aligned_size = Common::AlignUp(size, MAX_ALIGNMENT); + const size_t alignment = static_cast(stream_alignment); + const size_t aligned_size = Common::AlignUp(size, alignment); const bool wraps = iterator + size >= stream_buffer_size; const size_t new_iterator = - wraps ? aligned_size : Common::AlignUp(iterator + size, MAX_ALIGNMENT); + wraps ? aligned_size : Common::AlignUp(iterator + size, alignment); const size_t begin_region = wraps ? 0 : Region(iterator); const size_t last_byte = new_iterator == 0 ? 0 : new_iterator - 1; const size_t end_region = (std::min)(Region(last_byte) + 1, NUM_SYNCS); @@ -145,7 +149,7 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) { current_tick); used_iterator = 0; iterator = 0; - free_iterator = size; + free_iterator = aligned_size; const size_t head_last_byte = aligned_size == 0 ? 0 : aligned_size - 1; const size_t head_end_region = (std::min)(Region(head_last_byte) + 1, NUM_SYNCS); if (AreRegionsActive(0, head_end_region)) { @@ -160,7 +164,7 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) { iterator = new_iterator; if (!wraps) { - free_iterator = (std::max)(free_iterator, offset + size); + free_iterator = (std::max)(free_iterator, offset + aligned_size); } return StagingBufferRef{ diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h index f63a203272..5c40ca069f 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -102,6 +105,7 @@ private: MemoryAllocator& memory_allocator; Scheduler& scheduler; + VkDeviceSize stream_alignment; vk::Buffer stream_buffer; std::span stream_pointer; VkDeviceSize stream_buffer_size; From 954c17c18a5e6a39c4f7edd80bbb4a1e0507d4e0 Mon Sep 17 00:00:00 2001 From: crueter Date: Wed, 8 Oct 2025 06:39:58 +0200 Subject: [PATCH 18/24] [frontend] change order of filters to match append rules (#2696) otherwise, FSR would change to Gaussian etc. in general, sans resolution, new enum values should always be appended Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2696 Reviewed-by: CamilleLaVey Reviewed-by: Lizzie --- src/android/app/src/main/res/values/arrays.xml | 8 ++++---- src/common/settings_enums.h | 2 +- src/qt_common/shared_translation.cpp | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index 7e44750909..2150d401db 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -253,16 +253,16 @@ @string/scaling_filter_nearest_neighbor @string/scaling_filter_bilinear @string/scaling_filter_bicubic - @string/scaling_filter_zero_tangent - @string/scaling_filter_bspline - @string/scaling_filter_mitchell - @string/scaling_filter_spline1 @string/scaling_filter_gaussian @string/scaling_filter_lanczos @string/scaling_filter_scale_force @string/scaling_filter_fsr @string/scaling_filter_area @string/scaling_filter_mmpx + @string/scaling_filter_zero_tangent + @string/scaling_filter_bspline + @string/scaling_filter_mitchell + @string/scaling_filter_spline1 diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index 3fcdf08256..ccf6f1cfb2 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -143,7 +143,7 @@ ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never); ENUM(FullscreenMode, Borderless, Exclusive); ENUM(NvdecEmulation, Off, Cpu, Gpu); ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res5_4X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, Res8X); -ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, ZeroTangent, BSpline, Mitchell, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, Mmpx, MaxEnum); +ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Gaussian, Lanczos, ScaleForce, Fsr, Area, ZeroTangent, BSpline, Mitchell, Spline1, Mmpx, MaxEnum); ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum); ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch); ENUM(ConsoleMode, Handheld, Docked); diff --git a/src/qt_common/shared_translation.cpp b/src/qt_common/shared_translation.cpp index 0b40ca9904..054d28e8e2 100644 --- a/src/qt_common/shared_translation.cpp +++ b/src/qt_common/shared_translation.cpp @@ -549,16 +549,16 @@ std::unique_ptr ComboboxEnumeration(QObject* parent) PAIR(ScalingFilter, NearestNeighbor, tr("Nearest Neighbor")), PAIR(ScalingFilter, Bilinear, tr("Bilinear")), PAIR(ScalingFilter, Bicubic, tr("Bicubic")), - PAIR(ScalingFilter, ZeroTangent, tr("Zero-Tangent")), - PAIR(ScalingFilter, BSpline, tr("B-Spline")), - PAIR(ScalingFilter, Mitchell, tr("Mitchell")), - PAIR(ScalingFilter, Spline1, tr("Spline-1")), PAIR(ScalingFilter, Gaussian, tr("Gaussian")), PAIR(ScalingFilter, Lanczos, tr("Lanczos")), PAIR(ScalingFilter, ScaleForce, tr("ScaleForce")), PAIR(ScalingFilter, Fsr, tr("AMD FidelityFX™️ Super Resolution")), PAIR(ScalingFilter, Area, tr("Area")), PAIR(ScalingFilter, Mmpx, tr("MMPX")), + PAIR(ScalingFilter, ZeroTangent, tr("Zero-Tangent")), + PAIR(ScalingFilter, BSpline, tr("B-Spline")), + PAIR(ScalingFilter, Mitchell, tr("Mitchell")), + PAIR(ScalingFilter, Spline1, tr("Spline-1")), }}); translations->insert({Settings::EnumMetadata::Index(), { From 3c6ef765af9b946240cedf053e593c0fc86a3f01 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Thu, 9 Oct 2025 21:37:27 +0200 Subject: [PATCH 19/24] revert [vk] Fast UBO: fix tracking, resize heuristics, add debug guard (#2695) (#2706) revert [vk] Fast UBO: fix tracking, resize heuristics, add debug guard (#2695) Well, stuff showed up after testing phase, that showed us this change break SMO and some mods after being merged directly into master, we will keep stuying why happens this and add a better handling later. Co-authored-by: Ribbit Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2695 Reviewed-by: CamilleLaVey Co-authored-by: Ribbit Co-committed-by: Ribbit Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2706 Co-authored-by: CamilleLaVey Co-committed-by: CamilleLaVey --- src/core/device_memory_manager.h | 6 --- src/core/device_memory_manager.inc | 26 ------------ src/video_core/buffer_cache/buffer_cache.h | 42 +++++++++---------- .../buffer_cache/buffer_cache_base.h | 5 +-- .../vk_staging_buffer_pool.cpp | 26 +++++------- .../renderer_vulkan/vk_staging_buffer_pool.h | 4 -- 6 files changed, 33 insertions(+), 76 deletions(-) diff --git a/src/core/device_memory_manager.h b/src/core/device_memory_manager.h index 192c6e5c01..6dcf7bb228 100644 --- a/src/core/device_memory_manager.h +++ b/src/core/device_memory_manager.h @@ -1,6 +1,3 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -112,9 +109,6 @@ public: void ReadBlock(DAddr address, void* dest_pointer, size_t size); void ReadBlockUnsafe(DAddr address, void* dest_pointer, size_t size); -#ifdef YUZU_DEBUG - bool ReadBlockFastChecked(DAddr address, void* dest_pointer, size_t size); -#endif void WriteBlock(DAddr address, const void* src_pointer, size_t size); void WriteBlockUnsafe(DAddr address, const void* src_pointer, size_t size); diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc index 3629579c09..52dff5df9a 100644 --- a/src/core/device_memory_manager.inc +++ b/src/core/device_memory_manager.inc @@ -1,6 +1,3 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -470,29 +467,6 @@ void DeviceMemoryManager::ReadBlockUnsafe(DAddr address, void* dest_poin }); } -#ifdef YUZU_DEBUG -template -bool DeviceMemoryManager::ReadBlockFastChecked(DAddr address, void* dest_pointer, - size_t size) { - bool success = true; - WalkBlock( - address, size, - [&](size_t copy_amount, DAddr current_vaddr) { - LOG_CRITICAL(Render, "DeviceMemory OOB/unmapped: addr=0x{:x} size={}", current_vaddr, - size); - std::memset(dest_pointer, 0, copy_amount); - success = false; - }, - [&](size_t copy_amount, const u8* const src_ptr) { - std::memcpy(dest_pointer, src_ptr, copy_amount); - }, - [&](const std::size_t copy_amount) { - dest_pointer = static_cast(dest_pointer) + copy_amount; - }); - return success; -} -#endif - template void DeviceMemoryManager::WriteBlockUnsafe(DAddr address, const void* src_pointer, size_t size) { diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 388c8034c5..5223afe937 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -386,10 +386,11 @@ void BufferCache

::BindHostComputeBuffers() { template void BufferCache

::SetUniformBuffersState(const std::array& mask, const UniformBufferSizes* sizes) { - const bool mask_changed = channel_state->enabled_uniform_buffer_masks != mask; - if (mask_changed) { - channel_state->fast_bound_uniform_buffers.fill(0); - if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { + if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { + if (channel_state->enabled_uniform_buffer_masks != mask) { + if constexpr (IS_OPENGL) { + channel_state->fast_bound_uniform_buffers.fill(0); + } channel_state->dirty_uniform_buffers.fill(~u32{0}); channel_state->uniform_buffer_binding_sizes.fill({}); } @@ -805,7 +806,7 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 channel_state->uniform_buffer_binding_sizes[stage][binding_index] != size; if (should_fast_bind) { // We only have to bind when the currently bound buffer is not the fast version - channel_state->fast_bound_uniform_buffers[stage] |= 1u << binding_index; + channel_state->fast_bound_uniform_buffers[stage] |= 1U << binding_index; channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size; runtime.BindFastUniformBuffer(stage, binding_index, size); } @@ -814,22 +815,13 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 return; } } - channel_state->fast_bound_uniform_buffers[stage] |= 1u << binding_index; - channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size; + if constexpr (IS_OPENGL) { + channel_state->fast_bound_uniform_buffers[stage] |= 1U << binding_index; + channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size; + } // Stream buffer path to avoid stalling on non-Nvidia drivers or Vulkan const std::span span = runtime.BindMappedUniformBuffer(stage, binding_index, size); -#ifdef YUZU_DEBUG - ASSERT(binding_index < NUM_GRAPHICS_UNIFORM_BUFFERS); - ASSERT(span.size() >= size && "UBO stream span too small"); - if (!device_memory.ReadBlockFastChecked(device_addr, span.data(), size)) { - LOG_CRITICAL(Render, "DeviceMemory OOB/unmapped: addr=0x{:x} size={}", device_addr, size); - channel_state->fast_bound_uniform_buffers[stage] &= ~(1u << binding_index); - ASSERT(false); - return; - } -#else device_memory.ReadBlockUnsafe(device_addr, span.data(), size); -#endif return; } // Classic cached path @@ -838,8 +830,7 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 } // Skip binding if it's not needed and if the bound buffer is not the fast version // This exists to avoid instances where the fast buffer is bound and a GPU write happens - const bool was_fast_bound = HasFastUniformBufferBound(stage, binding_index); - needs_bind |= was_fast_bound; + needs_bind |= HasFastUniformBufferBound(stage, binding_index); if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { needs_bind |= channel_state->uniform_buffer_binding_sizes[stage][binding_index] != size; } @@ -848,6 +839,9 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 } const u32 offset = buffer.Offset(device_addr); if constexpr (IS_OPENGL) { + // Fast buffer will be unbound + channel_state->fast_bound_uniform_buffers[stage] &= ~(1U << binding_index); + // Mark the index as dirty if offset doesn't match const bool is_copy_bind = offset != 0 && !runtime.SupportsNonZeroUniformOffset(); channel_state->dirty_uniform_buffers[stage] |= (is_copy_bind ? 1U : 0U) << index; @@ -861,7 +855,6 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 } else { runtime.BindUniformBuffer(buffer, offset, size); } - channel_state->fast_bound_uniform_buffers[stage] &= ~(1u << binding_index); } template @@ -1796,7 +1789,12 @@ std::span BufferCache

::ImmediateBuffer(size_t wanted_capacity) { template bool BufferCache

::HasFastUniformBufferBound(size_t stage, u32 binding_index) const noexcept { - return ((channel_state->fast_bound_uniform_buffers[stage] >> binding_index) & 1u) != 0; + if constexpr (IS_OPENGL) { + return ((channel_state->fast_bound_uniform_buffers[stage] >> binding_index) & 1) != 0; + } else { + // Only OpenGL has fast uniform buffers + return false; + } } template diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h index 09631ffd83..486d19fb79 100644 --- a/src/video_core/buffer_cache/buffer_cache_base.h +++ b/src/video_core/buffer_cache/buffer_cache_base.h @@ -53,7 +53,6 @@ constexpr u32 NUM_COMPUTE_UNIFORM_BUFFERS = 8; constexpr u32 NUM_STORAGE_BUFFERS = 16; constexpr u32 NUM_TEXTURE_BUFFERS = 32; constexpr u32 NUM_STAGES = 5; -static_assert(NUM_GRAPHICS_UNIFORM_BUFFERS <= 32, "fast bitmask must fit u32"); using UniformBufferSizes = std::array, NUM_STAGES>; using ComputeUniformBufferSizes = std::array; @@ -138,8 +137,8 @@ public: u32 written_compute_texture_buffers = 0; u32 image_compute_texture_buffers = 0; - std::array uniform_cache_hits{}; - std::array uniform_cache_shots{}; + std::array uniform_cache_hits{}; + std::array uniform_cache_shots{}; u32 uniform_buffer_skip_cache_size = DEFAULT_SKIP_CACHE_SIZE; diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp index 0fbe707b04..ecc4f77dc7 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp @@ -25,12 +25,12 @@ namespace { using namespace Common::Literals; -// Minimum alignment we want to enforce for the streaming ring -constexpr VkDeviceSize MIN_STREAM_ALIGNMENT = 256; +// Maximum potential alignment of a Vulkan buffer +constexpr VkDeviceSize MAX_ALIGNMENT = 256; // Stream buffer size in bytes constexpr VkDeviceSize MAX_STREAM_BUFFER_SIZE = 128_MiB; -size_t GetStreamBufferSize(const Device& device, VkDeviceSize alignment) { +size_t GetStreamBufferSize(const Device& device) { VkDeviceSize size{0}; if (device.HasDebuggingToolAttached()) { bool found_heap = false; @@ -53,9 +53,8 @@ size_t GetStreamBufferSize(const Device& device, VkDeviceSize alignment) { // Clamp to the configured maximum, align up for safety, and ensure a sane minimum so // region_size (stream_buffer_size / NUM_SYNCS) never becomes zero. - const VkDeviceSize aligned = - (std::min)(Common::AlignUp(size, alignment), MAX_STREAM_BUFFER_SIZE); - const VkDeviceSize min_size = alignment * StagingBufferPool::NUM_SYNCS; + const VkDeviceSize aligned = (std::min)(Common::AlignUp(size, MAX_ALIGNMENT), MAX_STREAM_BUFFER_SIZE); + const VkDeviceSize min_size = MAX_ALIGNMENT * StagingBufferPool::NUM_SYNCS; return static_cast((std::max)(aligned, min_size)); } } // Anonymous namespace @@ -63,10 +62,8 @@ size_t GetStreamBufferSize(const Device& device, VkDeviceSize alignment) { StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_, Scheduler& scheduler_) : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, - stream_alignment{std::max(device_.GetUniformBufferAlignment(), - MIN_STREAM_ALIGNMENT)}, - stream_buffer_size{GetStreamBufferSize(device_, stream_alignment)}, - region_size{stream_buffer_size / StagingBufferPool::NUM_SYNCS} { + stream_buffer_size{GetStreamBufferSize(device)}, region_size{stream_buffer_size / + StagingBufferPool::NUM_SYNCS} { VkBufferCreateInfo stream_ci = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .pNext = nullptr, @@ -119,11 +116,10 @@ void StagingBufferPool::TickFrame() { } StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) { - const size_t alignment = static_cast(stream_alignment); - const size_t aligned_size = Common::AlignUp(size, alignment); + const size_t aligned_size = Common::AlignUp(size, MAX_ALIGNMENT); const bool wraps = iterator + size >= stream_buffer_size; const size_t new_iterator = - wraps ? aligned_size : Common::AlignUp(iterator + size, alignment); + wraps ? aligned_size : Common::AlignUp(iterator + size, MAX_ALIGNMENT); const size_t begin_region = wraps ? 0 : Region(iterator); const size_t last_byte = new_iterator == 0 ? 0 : new_iterator - 1; const size_t end_region = (std::min)(Region(last_byte) + 1, NUM_SYNCS); @@ -149,7 +145,7 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) { current_tick); used_iterator = 0; iterator = 0; - free_iterator = aligned_size; + free_iterator = size; const size_t head_last_byte = aligned_size == 0 ? 0 : aligned_size - 1; const size_t head_end_region = (std::min)(Region(head_last_byte) + 1, NUM_SYNCS); if (AreRegionsActive(0, head_end_region)) { @@ -164,7 +160,7 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) { iterator = new_iterator; if (!wraps) { - free_iterator = (std::max)(free_iterator, offset + aligned_size); + free_iterator = (std::max)(free_iterator, offset + size); } return StagingBufferRef{ diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h index 5c40ca069f..f63a203272 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h @@ -1,6 +1,3 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -105,7 +102,6 @@ private: MemoryAllocator& memory_allocator; Scheduler& scheduler; - VkDeviceSize stream_alignment; vk::Buffer stream_buffer; std::span stream_pointer; VkDeviceSize stream_buffer_size; From bfffafe68bea923ddc56bb1b7da73d549865dc11 Mon Sep 17 00:00:00 2001 From: MaranBr Date: Fri, 10 Oct 2025 01:36:55 +0200 Subject: [PATCH 20/24] [common] Change web offline applet default setting to HLE (#2705) This prevents some games from ignoring the disable web applet setting. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2705 Co-authored-by: MaranBr Co-committed-by: MaranBr --- src/common/settings.h | 2 +- src/yuzu/configuration/configure_debug.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/common/settings.h b/src/common/settings.h index c6b52f7ba3..dd9b03f28e 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -161,7 +161,7 @@ struct Values { Category::LibraryApplet}; Setting photo_viewer_applet_mode{ linkage, AppletMode::LLE, "photo_viewer_applet_mode", Category::LibraryApplet}; - Setting offline_web_applet_mode{linkage, AppletMode::LLE, "offline_web_applet_mode", + Setting offline_web_applet_mode{linkage, AppletMode::HLE, "offline_web_applet_mode", Category::LibraryApplet}; Setting login_share_applet_mode{linkage, AppletMode::HLE, "login_share_applet_mode", Category::LibraryApplet}; diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index 18f629f639..b825348760 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp @@ -83,8 +83,7 @@ void ConfigureDebug::SetConfiguration() { #ifdef YUZU_USE_QT_WEB_ENGINE ui->disable_web_applet->setChecked(UISettings::values.disable_web_applet.GetValue()); #else - ui->disable_web_applet->setEnabled(false); - ui->disable_web_applet->setText(tr("Web applet not compiled")); + ui->disable_web_applet->setVisible(false); #endif } From b6241e4148d4a7bccedd3081707106edc58ff365 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Fri, 10 Oct 2025 01:55:43 +0200 Subject: [PATCH 21/24] revert [vk] StreamBuffer Changes (#2684) (#2707) revert [vk] StreamBuffer Changes (#2684) Streambuffer changes did broke stuff in other games that got out of our scope of testing, we're going to study this changes in the future for better graphic stability. Co-authored-by: Ribbit Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2684 Reviewed-by: MaranBr Reviewed-by: Lizzie Reviewed-by: CamilleLaVey Co-authored-by: Ribbit Co-committed-by: Ribbit Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2707 Reviewed-by: MaranBr Co-authored-by: CamilleLaVey Co-committed-by: CamilleLaVey --- .../vk_staging_buffer_pool.cpp | 60 +++++-------------- 1 file changed, 14 insertions(+), 46 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp index ecc4f77dc7..08513d1534 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp @@ -33,29 +33,19 @@ constexpr VkDeviceSize MAX_STREAM_BUFFER_SIZE = 128_MiB; size_t GetStreamBufferSize(const Device& device) { VkDeviceSize size{0}; if (device.HasDebuggingToolAttached()) { - bool found_heap = false; - ForEachDeviceLocalHostVisibleHeap(device, [&size, &found_heap](size_t /*index*/, VkMemoryHeap& heap) { + ForEachDeviceLocalHostVisibleHeap(device, [&size](size_t index, VkMemoryHeap& heap) { size = (std::max)(size, heap.size); - found_heap = true; }); - // If no suitable heap was found fall back to the default cap to avoid creating a zero-sized stream buffer. - if (!found_heap) { - size = MAX_STREAM_BUFFER_SIZE; - } else if (size <= 256_MiB) { - // If rebar is not supported, cut the max heap size to 40%. This will allow 2 captures to be - // loaded at the same time in RenderDoc. If rebar is supported, this shouldn't be an issue - // as the heap will be much larger. + // If rebar is not supported, cut the max heap size to 40%. This will allow 2 captures to be + // loaded at the same time in RenderDoc. If rebar is supported, this shouldn't be an issue + // as the heap will be much larger. + if (size <= 256_MiB) { size = size * 40 / 100; } } else { size = MAX_STREAM_BUFFER_SIZE; } - - // Clamp to the configured maximum, align up for safety, and ensure a sane minimum so - // region_size (stream_buffer_size / NUM_SYNCS) never becomes zero. - const VkDeviceSize aligned = (std::min)(Common::AlignUp(size, MAX_ALIGNMENT), MAX_STREAM_BUFFER_SIZE); - const VkDeviceSize min_size = MAX_ALIGNMENT * StagingBufferPool::NUM_SYNCS; - return static_cast((std::max)(aligned, min_size)); + return (std::min)(Common::AlignUp(size, MAX_ALIGNMENT), MAX_STREAM_BUFFER_SIZE); } } // Anonymous namespace @@ -116,53 +106,31 @@ void StagingBufferPool::TickFrame() { } StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) { - const size_t aligned_size = Common::AlignUp(size, MAX_ALIGNMENT); - const bool wraps = iterator + size >= stream_buffer_size; - const size_t new_iterator = - wraps ? aligned_size : Common::AlignUp(iterator + size, MAX_ALIGNMENT); - const size_t begin_region = wraps ? 0 : Region(iterator); - const size_t last_byte = new_iterator == 0 ? 0 : new_iterator - 1; - const size_t end_region = (std::min)(Region(last_byte) + 1, NUM_SYNCS); - const size_t guard_begin = (std::min)(Region(free_iterator) + 1, NUM_SYNCS); - - if (!wraps) { - if (guard_begin < end_region && AreRegionsActive(guard_begin, end_region)) { - // Avoid waiting for the previous usages to be free - return GetStagingBuffer(size, MemoryUsage::Upload); - } - } else if (guard_begin < NUM_SYNCS && AreRegionsActive(guard_begin, NUM_SYNCS)) { + if (AreRegionsActive(Region(free_iterator) + 1, + (std::min)(Region(iterator + size) + 1, NUM_SYNCS))) { // Avoid waiting for the previous usages to be free return GetStagingBuffer(size, MemoryUsage::Upload); } - const u64 current_tick = scheduler.CurrentTick(); std::fill(sync_ticks.begin() + Region(used_iterator), sync_ticks.begin() + Region(iterator), current_tick); used_iterator = iterator; + free_iterator = (std::max)(free_iterator, iterator + size); - if (wraps) { + if (iterator + size >= stream_buffer_size) { std::fill(sync_ticks.begin() + Region(used_iterator), sync_ticks.begin() + NUM_SYNCS, current_tick); used_iterator = 0; iterator = 0; free_iterator = size; - const size_t head_last_byte = aligned_size == 0 ? 0 : aligned_size - 1; - const size_t head_end_region = (std::min)(Region(head_last_byte) + 1, NUM_SYNCS); - if (AreRegionsActive(0, head_end_region)) { + + if (AreRegionsActive(0, Region(size) + 1)) { // Avoid waiting for the previous usages to be free return GetStagingBuffer(size, MemoryUsage::Upload); } } - - std::fill(sync_ticks.begin() + begin_region, sync_ticks.begin() + end_region, current_tick); - - const size_t offset = wraps ? 0 : iterator; - iterator = new_iterator; - - if (!wraps) { - free_iterator = (std::max)(free_iterator, offset + size); - } - + const size_t offset = iterator; + iterator = Common::AlignUp(iterator + size, MAX_ALIGNMENT); return StagingBufferRef{ .buffer = *stream_buffer, .offset = static_cast(offset), From 3656253262fd1c22e5a1ab43ae373173e571e11d Mon Sep 17 00:00:00 2001 From: crueter Date: Fri, 10 Oct 2025 05:59:31 +0200 Subject: [PATCH 22/24] [acc] do not consider system profile as orphaned (#2708) Profile 00000000000000000000000000000000 is apparently needed for acnh, etc Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2708 --- src/core/hle/service/acc/profile_manager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 4a892f7c65..12ea5f7aa1 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -509,6 +509,9 @@ std::vector ProfileManager::FindOrphanedProfiles() good_uuids.emplace_back(uuid_string); } + // used for acnh, etc + good_uuids.emplace_back("00000000000000000000000000000000"); + // TODO: fetch save_id programmatically const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "user/save/0000000000000000"; From f90e4a2243ce3f88962c266ace56473cc694b319 Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 1 Oct 2025 08:09:33 +0000 Subject: [PATCH 23/24] [arm] Add "debugging" cpu accuracy option to replace CPU debug toggle The debug toggle and the CPU accuracy options are mutually exclusive, if debug toggle on => cpu accuracy is ignored, if debug toggle off => cpu accuracy is used. So just add it to cpu accuracy and avoid the extra hassle. Signed-off-by: lizzie --- src/common/settings.cpp | 6 +- src/common/settings.h | 3 - src/common/settings_enums.h | 2 +- src/core/arm/dynarmic/arm_dynarmic_32.cpp | 77 ++++++++++----------- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 79 +++++++++++----------- src/qt_common/shared_translation.cpp | 1 + src/yuzu/configuration/configure_debug.cpp | 3 - src/yuzu/configuration/configure_debug.ui | 8 --- 8 files changed, 84 insertions(+), 95 deletions(-) diff --git a/src/common/settings.cpp b/src/common/settings.cpp index b849d7cb6a..e817acc36e 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -163,11 +163,11 @@ bool IsDMALevelSafe() { } bool IsFastmemEnabled() { - if (values.cpu_debug_mode) { - return static_cast(values.cpuopt_fastmem); + if (values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Debugging) { + return bool(values.cpuopt_fastmem); } if (values.cpu_accuracy.GetValue() == CpuAccuracy::Unsafe) { - return static_cast(values.cpuopt_unsafe_host_mmu); + return bool(values.cpuopt_unsafe_host_mmu); } #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) return false; diff --git a/src/common/settings.h b/src/common/settings.h index dd9b03f28e..b53a557d1a 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -275,9 +275,6 @@ struct Values { true, true, &use_custom_cpu_ticks}; - - SwitchableSetting cpu_debug_mode{linkage, false, "cpu_debug_mode", Category::CpuDebug}; - Setting cpuopt_page_tables{linkage, true, "cpuopt_page_tables", Category::CpuDebug}; Setting cpuopt_block_linking{linkage, true, "cpuopt_block_linking", Category::CpuDebug}; Setting cpuopt_return_stack_buffer{linkage, true, "cpuopt_return_stack_buffer", diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index ccf6f1cfb2..c8a5fc7bd9 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -136,7 +136,7 @@ ENUM(ShaderBackend, Glsl, Glasm, SpirV); ENUM(GpuAccuracy, Normal, High, Extreme); ENUM(DmaAccuracy, Default, Unsafe, Safe); ENUM(CpuBackend, Dynarmic, Nce); -ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid); +ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid, Debugging); ENUM(CpuClock, Boost, Fast) ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb); ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never); diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index d2035d0fe0..3c72ab2396 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -229,7 +229,8 @@ std::shared_ptr ArmDynarmic32::MakeJit(Common::PageTable* pa } // Safe optimizations - if (Settings::values.cpu_debug_mode) { + switch (Settings::values.cpu_accuracy.GetValue()) { + case Settings::CpuAccuracy::Debugging: if (!Settings::values.cpuopt_page_tables) { config.page_table = nullptr; } @@ -267,51 +268,51 @@ std::shared_ptr ArmDynarmic32::MakeJit(Common::PageTable* pa if (!Settings::values.cpuopt_ignore_memory_aborts) { config.check_halt_on_memory_access = true; } - } else { - // Unsafe optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) { - config.unsafe_optimizations = true; - if (!Settings::values.cpuopt_unsafe_host_mmu) { - config.fastmem_pointer = std::nullopt; - config.fastmem_exclusive_access = false; - } - if (Settings::values.cpuopt_unsafe_unfuse_fma) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; - } - if (Settings::values.cpuopt_unsafe_reduce_fp_error) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; - } - if (Settings::values.cpuopt_unsafe_ignore_standard_fpcr) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; - } - if (Settings::values.cpuopt_unsafe_inaccurate_nan) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; - } - if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; - } - } - - // Curated optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Auto) { - config.unsafe_optimizations = true; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) + break; + // Unsafe optimizations + case Settings::CpuAccuracy::Unsafe: + config.unsafe_optimizations = true; + if (!Settings::values.cpuopt_unsafe_host_mmu) { config.fastmem_pointer = std::nullopt; config.fastmem_exclusive_access = false; -#endif + } + if (Settings::values.cpuopt_unsafe_unfuse_fma) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + } + if (Settings::values.cpuopt_unsafe_reduce_fp_error) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; + } + if (Settings::values.cpuopt_unsafe_ignore_standard_fpcr) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; + } + if (Settings::values.cpuopt_unsafe_inaccurate_nan) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; + } + if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; } - - // Paranoia mode for debugging optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) { - config.unsafe_optimizations = false; - config.optimizations = Dynarmic::no_optimizations; - } + break; + // Curated optimizations + case Settings::CpuAccuracy::Auto: + config.unsafe_optimizations = true; +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) + config.fastmem_pointer = std::nullopt; + config.fastmem_exclusive_access = false; +#endif + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; + break; + // Paranoia mode for debugging optimizations + case Settings::CpuAccuracy::Paranoid: + config.unsafe_optimizations = false; + config.optimizations = Dynarmic::no_optimizations; + break; + case Settings::CpuAccuracy::Accurate: + default: + break; } - return std::make_unique(config); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 438b7b691c..707d51d2a2 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -287,8 +287,9 @@ std::shared_ptr ArmDynarmic64::MakeJit(Common::PageTable* pa config.code_cache_size = std::uint32_t(8_MiB); } - // Safe optimizations - if (Settings::values.cpu_debug_mode) { + switch (Settings::values.cpu_accuracy.GetValue()) { + // Debug mode + case Settings::CpuAccuracy::Debugging: if (!Settings::values.cpuopt_page_tables) { config.page_table = nullptr; } @@ -326,50 +327,50 @@ std::shared_ptr ArmDynarmic64::MakeJit(Common::PageTable* pa if (!Settings::values.cpuopt_ignore_memory_aborts) { config.check_halt_on_memory_access = true; } - } else { - // Unsafe optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) { - config.unsafe_optimizations = true; - if (!Settings::values.cpuopt_unsafe_host_mmu) { - config.fastmem_pointer = std::nullopt; - config.fastmem_exclusive_access = false; - } - if (Settings::values.cpuopt_unsafe_unfuse_fma) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; - } - if (Settings::values.cpuopt_unsafe_reduce_fp_error) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; - } - if (Settings::values.cpuopt_unsafe_inaccurate_nan) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; - } - if (Settings::values.cpuopt_unsafe_fastmem_check) { - config.fastmem_address_space_bits = 64; - } - if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; - } - } - - // Curated optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Auto) { - config.unsafe_optimizations = true; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) + break; + // Unsafe optimizations + case Settings::CpuAccuracy::Unsafe: + config.unsafe_optimizations = true; + if (!Settings::values.cpuopt_unsafe_host_mmu) { config.fastmem_pointer = std::nullopt; config.fastmem_exclusive_access = false; -#endif + } + if (Settings::values.cpuopt_unsafe_unfuse_fma) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + } + if (Settings::values.cpuopt_unsafe_reduce_fp_error) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; + } + if (Settings::values.cpuopt_unsafe_inaccurate_nan) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; + } + if (Settings::values.cpuopt_unsafe_fastmem_check) { config.fastmem_address_space_bits = 64; + } + if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; } - - // Paranoia mode for debugging optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) { - config.unsafe_optimizations = false; - config.optimizations = Dynarmic::no_optimizations; - } + break; + // Safe optimisations + case Settings::CpuAccuracy::Auto: + config.unsafe_optimizations = true; +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) + config.fastmem_pointer = std::nullopt; + config.fastmem_exclusive_access = false; +#endif + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + config.fastmem_address_space_bits = 64; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; + break; + // Paranoia mode for debugging optimizations + case Settings::CpuAccuracy::Paranoid: + config.unsafe_optimizations = false; + config.optimizations = Dynarmic::no_optimizations; + break; + case Settings::CpuAccuracy::Accurate: + default: + break; } - return std::make_shared(config); } diff --git a/src/qt_common/shared_translation.cpp b/src/qt_common/shared_translation.cpp index 054d28e8e2..910d0c0404 100644 --- a/src/qt_common/shared_translation.cpp +++ b/src/qt_common/shared_translation.cpp @@ -510,6 +510,7 @@ std::unique_ptr ComboboxEnumeration(QObject* parent) PAIR(CpuAccuracy, Accurate, tr("Accurate")), PAIR(CpuAccuracy, Unsafe, tr("Unsafe")), PAIR(CpuAccuracy, Paranoid, tr("Paranoid (disables most optimizations)")), + PAIR(CpuAccuracy, Debugging, tr("Debugging")), }}); translations->insert({Settings::EnumMetadata::Index(), { diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index b825348760..fbeceaaa0d 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp @@ -62,8 +62,6 @@ void ConfigureDebug::SetConfiguration() { ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug.GetValue()); ui->enable_shader_feedback->setEnabled(runtime_lock); ui->enable_shader_feedback->setChecked(Settings::values.renderer_shader_feedback.GetValue()); - ui->enable_cpu_debugging->setEnabled(runtime_lock); - ui->enable_cpu_debugging->setChecked(Settings::values.cpu_debug_mode.GetValue()); ui->enable_nsight_aftermath->setEnabled(runtime_lock); ui->enable_nsight_aftermath->setChecked(Settings::values.enable_nsight_aftermath.GetValue()); ui->dump_shaders->setEnabled(runtime_lock); @@ -106,7 +104,6 @@ void ConfigureDebug::ApplyConfiguration() { Settings::values.enable_renderdoc_hotkey = ui->enable_renderdoc_hotkey->isChecked(); Settings::values.disable_buffer_reorder = ui->disable_buffer_reorder->isChecked(); Settings::values.renderer_shader_feedback = ui->enable_shader_feedback->isChecked(); - Settings::values.cpu_debug_mode = ui->enable_cpu_debugging->isChecked(); Settings::values.enable_nsight_aftermath = ui->enable_nsight_aftermath->isChecked(); Settings::values.dump_shaders = ui->dump_shaders->isChecked(); Settings::values.dump_macros = ui->dump_macros->isChecked(); diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index bd7125712c..1f302bf118 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui @@ -435,13 +435,6 @@ - - - - Enable CPU Debugging - - - @@ -582,7 +575,6 @@ fs_access_log reporting_services quest_flag - enable_cpu_debugging use_debug_asserts From 4b9a0e4e6030ffbaec547b6cc4c50fb8f3f10415 Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 10 Oct 2025 04:07:26 +0000 Subject: [PATCH 24/24] remove from android Signed-off-by: lizzie --- .../yuzu_emu/features/settings/model/BooleanSetting.kt | 1 - .../yuzu_emu/features/settings/model/view/SettingsItem.kt | 8 -------- .../features/settings/ui/SettingsFragmentPresenter.kt | 1 - 3 files changed, 10 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index b26fb1dec5..e9fe2be53c 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt @@ -10,7 +10,6 @@ import org.yuzu.yuzu_emu.utils.NativeConfig enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { AUDIO_MUTED("audio_muted"), - CPU_DEBUG_MODE("cpu_debug_mode"), FASTMEM("cpuopt_fastmem"), FASTMEM_EXCLUSIVES("cpuopt_fastmem_exclusives"), CORE_SYNC_CORE_SPEED("sync_core_speed"), diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index ebc726225a..8c35155e78 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -764,13 +764,6 @@ abstract class SettingsItem( descriptionId = R.string.use_auto_stub_description ) ) - put( - SwitchSetting( - BooleanSetting.CPU_DEBUG_MODE, - titleId = R.string.cpu_debug_mode, - descriptionId = R.string.cpu_debug_mode_description - ) - ) val fastmem = object : AbstractBooleanSetting { override fun getBoolean(needsGlobal: Boolean): Boolean = @@ -784,7 +777,6 @@ abstract class SettingsItem( override val key: String = FASTMEM_COMBINED override val isRuntimeModifiable: Boolean = false - override val pairedSettingKey = BooleanSetting.CPU_DEBUG_MODE.key override val defaultValue: Boolean = true override val isSwitchable: Boolean = true override var global: Boolean diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index 0d882a7f01..d39c0c49bb 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -1158,7 +1158,6 @@ class SettingsFragmentPresenter( add(IntSetting.CPU_BACKEND.key) add(IntSetting.CPU_ACCURACY.key) add(BooleanSetting.USE_AUTO_STUB.key) - add(BooleanSetting.CPU_DEBUG_MODE.key) add(SettingsItem.FASTMEM_COMBINED) add(HeaderSetting(R.string.log))