diff options
| -rw-r--r-- | src/common/nvidia_flags.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 2 | ||||
| -rw-r--r-- | src/core/settings.h | 1 | ||||
| -rw-r--r-- | src/video_core/engines/engine_interface.h | 3 | ||||
| -rw-r--r-- | src/video_core/engines/fermi_2d.h | 2 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_memory.h | 2 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_dma.h | 2 | ||||
| -rw-r--r-- | src/video_core/query_cache.h | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_master_semaphore.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/texture_cache/util.cpp | 21 | ||||
| -rw-r--r-- | src/video_core/texture_cache/util.h | 5 | ||||
| -rw-r--r-- | src/yuzu/configuration/config.cpp | 14 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_graphics.cpp | 19 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_graphics.ui | 41 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 54 |
16 files changed, 155 insertions, 37 deletions
diff --git a/src/common/nvidia_flags.h b/src/common/nvidia_flags.h index 75a0233ac..8930efcec 100644 --- a/src/common/nvidia_flags.h +++ b/src/common/nvidia_flags.h | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | ||
| 6 | |||
| 5 | namespace Common { | 7 | namespace Common { |
| 6 | 8 | ||
| 7 | /// Configure platform specific flags for Nvidia's driver | 9 | /// Configure platform specific flags for Nvidia's driver |
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 1c86fdd20..b442dfe57 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h | |||
| @@ -402,7 +402,7 @@ public: | |||
| 402 | return wait_cancelled; | 402 | return wait_cancelled; |
| 403 | } | 403 | } |
| 404 | 404 | ||
| 405 | [[nodiscard]] void ClearWaitCancelled() { | 405 | void ClearWaitCancelled() { |
| 406 | wait_cancelled = false; | 406 | wait_cancelled = false; |
| 407 | } | 407 | } |
| 408 | 408 | ||
diff --git a/src/core/settings.h b/src/core/settings.h index a81016b23..6c03a6ea9 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -139,6 +139,7 @@ struct Values { | |||
| 139 | Setting<int> vulkan_device; | 139 | Setting<int> vulkan_device; |
| 140 | 140 | ||
| 141 | Setting<u16> resolution_factor{1}; | 141 | Setting<u16> resolution_factor{1}; |
| 142 | Setting<int> fullscreen_mode; | ||
| 142 | Setting<int> aspect_ratio; | 143 | Setting<int> aspect_ratio; |
| 143 | Setting<int> max_anisotropy; | 144 | Setting<int> max_anisotropy; |
| 144 | Setting<bool> use_frame_limit; | 145 | Setting<bool> use_frame_limit; |
diff --git a/src/video_core/engines/engine_interface.h b/src/video_core/engines/engine_interface.h index 18a9db7e6..c7ffd68c5 100644 --- a/src/video_core/engines/engine_interface.h +++ b/src/video_core/engines/engine_interface.h | |||
| @@ -4,13 +4,14 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <type_traits> | ||
| 8 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 9 | 8 | ||
| 10 | namespace Tegra::Engines { | 9 | namespace Tegra::Engines { |
| 11 | 10 | ||
| 12 | class EngineInterface { | 11 | class EngineInterface { |
| 13 | public: | 12 | public: |
| 13 | virtual ~EngineInterface() = default; | ||
| 14 | |||
| 14 | /// Write the value to the register identified by method. | 15 | /// Write the value to the register identified by method. |
| 15 | virtual void CallMethod(u32 method, u32 method_argument, bool is_last_call) = 0; | 16 | virtual void CallMethod(u32 method, u32 method_argument, bool is_last_call) = 0; |
| 16 | 17 | ||
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index c808a577d..a4170ffff 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h | |||
| @@ -35,7 +35,7 @@ namespace Tegra::Engines { | |||
| 35 | class Fermi2D final : public EngineInterface { | 35 | class Fermi2D final : public EngineInterface { |
| 36 | public: | 36 | public: |
| 37 | explicit Fermi2D(); | 37 | explicit Fermi2D(); |
| 38 | ~Fermi2D(); | 38 | ~Fermi2D() override; |
| 39 | 39 | ||
| 40 | /// Binds a rasterizer to this engine. | 40 | /// Binds a rasterizer to this engine. |
| 41 | void BindRasterizer(VideoCore::RasterizerInterface* rasterizer); | 41 | void BindRasterizer(VideoCore::RasterizerInterface* rasterizer); |
diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h index 19808a5c6..0d8ea09a9 100644 --- a/src/video_core/engines/kepler_memory.h +++ b/src/video_core/engines/kepler_memory.h | |||
| @@ -36,7 +36,7 @@ namespace Tegra::Engines { | |||
| 36 | class KeplerMemory final : public EngineInterface { | 36 | class KeplerMemory final : public EngineInterface { |
| 37 | public: | 37 | public: |
| 38 | explicit KeplerMemory(Core::System& system_, MemoryManager& memory_manager); | 38 | explicit KeplerMemory(Core::System& system_, MemoryManager& memory_manager); |
| 39 | ~KeplerMemory(); | 39 | ~KeplerMemory() override; |
| 40 | 40 | ||
| 41 | /// Write the value to the register identified by method. | 41 | /// Write the value to the register identified by method. |
| 42 | void CallMethod(u32 method, u32 method_argument, bool is_last_call) override; | 42 | void CallMethod(u32 method, u32 method_argument, bool is_last_call) override; |
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h index 3c59eeb13..c77f02a22 100644 --- a/src/video_core/engines/maxwell_dma.h +++ b/src/video_core/engines/maxwell_dma.h | |||
| @@ -188,7 +188,7 @@ public: | |||
| 188 | static_assert(sizeof(RemapConst) == 12); | 188 | static_assert(sizeof(RemapConst) == 12); |
| 189 | 189 | ||
| 190 | explicit MaxwellDMA(Core::System& system_, MemoryManager& memory_manager_); | 190 | explicit MaxwellDMA(Core::System& system_, MemoryManager& memory_manager_); |
| 191 | ~MaxwellDMA(); | 191 | ~MaxwellDMA() override; |
| 192 | 192 | ||
| 193 | /// Write the value to the register identified by method. | 193 | /// Write the value to the register identified by method. |
| 194 | void CallMethod(u32 method, u32 method_argument, bool is_last_call) override; | 194 | void CallMethod(u32 method, u32 method_argument, bool is_last_call) override; |
diff --git a/src/video_core/query_cache.h b/src/video_core/query_cache.h index 203f2af05..639d7ce7e 100644 --- a/src/video_core/query_cache.h +++ b/src/video_core/query_cache.h | |||
| @@ -208,9 +208,9 @@ public: | |||
| 208 | private: | 208 | private: |
| 209 | /// Flushes a memory range to guest memory and removes it from the cache. | 209 | /// Flushes a memory range to guest memory and removes it from the cache. |
| 210 | void FlushAndRemoveRegion(VAddr addr, std::size_t size) { | 210 | void FlushAndRemoveRegion(VAddr addr, std::size_t size) { |
| 211 | const u64 addr_begin = static_cast<u64>(addr); | 211 | const u64 addr_begin = addr; |
| 212 | const u64 addr_end = addr_begin + static_cast<u64>(size); | 212 | const u64 addr_end = addr_begin + size; |
| 213 | const auto in_range = [addr_begin, addr_end](CachedQuery& query) { | 213 | const auto in_range = [addr_begin, addr_end](const CachedQuery& query) { |
| 214 | const u64 cache_begin = query.GetCpuAddr(); | 214 | const u64 cache_begin = query.GetCpuAddr(); |
| 215 | const u64 cache_end = cache_begin + query.SizeInBytes(); | 215 | const u64 cache_end = cache_begin + query.SizeInBytes(); |
| 216 | return cache_begin < addr_end && addr_begin < cache_end; | 216 | return cache_begin < addr_end && addr_begin < cache_end; |
| @@ -230,8 +230,7 @@ private: | |||
| 230 | rasterizer.UpdatePagesCachedCount(query.GetCpuAddr(), query.SizeInBytes(), -1); | 230 | rasterizer.UpdatePagesCachedCount(query.GetCpuAddr(), query.SizeInBytes(), -1); |
| 231 | query.Flush(); | 231 | query.Flush(); |
| 232 | } | 232 | } |
| 233 | contents.erase(std::remove_if(std::begin(contents), std::end(contents), in_range), | 233 | std::erase_if(contents, in_range); |
| 234 | std::end(contents)); | ||
| 235 | } | 234 | } |
| 236 | } | 235 | } |
| 237 | 236 | ||
diff --git a/src/video_core/renderer_vulkan/vk_master_semaphore.h b/src/video_core/renderer_vulkan/vk_master_semaphore.h index 2c7ed654d..4b6d64daa 100644 --- a/src/video_core/renderer_vulkan/vk_master_semaphore.h +++ b/src/video_core/renderer_vulkan/vk_master_semaphore.h | |||
| @@ -35,8 +35,8 @@ public: | |||
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | /// Returns true when a tick has been hit by the GPU. | 37 | /// Returns true when a tick has been hit by the GPU. |
| 38 | [[nodiscard]] bool IsFree(u64 tick) { | 38 | [[nodiscard]] bool IsFree(u64 tick) const noexcept { |
| 39 | return gpu_tick.load(std::memory_order_relaxed) >= tick; | 39 | return KnownGpuTick() >= tick; |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | /// Advance to the logical tick. | 42 | /// Advance to the logical tick. |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 18155e449..bc2a53841 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | #include <span> | 7 | #include <span> |
| 8 | #include <vector> | 8 | #include <vector> |
| 9 | 9 | ||
| 10 | #include "common/bit_cast.h" | ||
| 11 | |||
| 10 | #include "video_core/engines/fermi_2d.h" | 12 | #include "video_core/engines/fermi_2d.h" |
| 11 | #include "video_core/renderer_vulkan/blit_image.h" | 13 | #include "video_core/renderer_vulkan/blit_image.h" |
| 12 | #include "video_core/renderer_vulkan/maxwell_to_vk.h" | 14 | #include "video_core/renderer_vulkan/maxwell_to_vk.h" |
| @@ -1062,14 +1064,13 @@ vk::ImageView ImageView::MakeDepthStencilView(VkImageAspectFlags aspect_mask) { | |||
| 1062 | Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& tsc) { | 1064 | Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& tsc) { |
| 1063 | const auto& device = runtime.device; | 1065 | const auto& device = runtime.device; |
| 1064 | const bool arbitrary_borders = runtime.device.IsExtCustomBorderColorSupported(); | 1066 | const bool arbitrary_borders = runtime.device.IsExtCustomBorderColorSupported(); |
| 1065 | const std::array<float, 4> color = tsc.BorderColor(); | 1067 | const auto color = tsc.BorderColor(); |
| 1066 | // C++20 bit_cast | 1068 | |
| 1067 | VkClearColorValue border_color; | ||
| 1068 | std::memcpy(&border_color, &color, sizeof(color)); | ||
| 1069 | const VkSamplerCustomBorderColorCreateInfoEXT border_ci{ | 1069 | const VkSamplerCustomBorderColorCreateInfoEXT border_ci{ |
| 1070 | .sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT, | 1070 | .sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT, |
| 1071 | .pNext = nullptr, | 1071 | .pNext = nullptr, |
| 1072 | .customBorderColor = border_color, | 1072 | // TODO: Make use of std::bit_cast once libc++ supports it. |
| 1073 | .customBorderColor = Common::BitCast<VkClearColorValue>(color), | ||
| 1073 | .format = VK_FORMAT_UNDEFINED, | 1074 | .format = VK_FORMAT_UNDEFINED, |
| 1074 | }; | 1075 | }; |
| 1075 | const void* pnext = nullptr; | 1076 | const void* pnext = nullptr; |
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp index c22dd0148..0ab297413 100644 --- a/src/video_core/texture_cache/util.cpp +++ b/src/video_core/texture_cache/util.cpp | |||
| @@ -268,16 +268,19 @@ template <u32 GOB_EXTENT> | |||
| 268 | return num_tiles << shift; | 268 | return num_tiles << shift; |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | [[nodiscard]] constexpr std::array<u32, MAX_MIP_LEVELS> CalculateLevelSizes(const LevelInfo& info, | 271 | [[nodiscard]] constexpr LevelArray CalculateLevelSizes(const LevelInfo& info, u32 num_levels) { |
| 272 | u32 num_levels) { | ||
| 273 | ASSERT(num_levels <= MAX_MIP_LEVELS); | 272 | ASSERT(num_levels <= MAX_MIP_LEVELS); |
| 274 | std::array<u32, MAX_MIP_LEVELS> sizes{}; | 273 | LevelArray sizes{}; |
| 275 | for (u32 level = 0; level < num_levels; ++level) { | 274 | for (u32 level = 0; level < num_levels; ++level) { |
| 276 | sizes[level] = CalculateLevelSize(info, level); | 275 | sizes[level] = CalculateLevelSize(info, level); |
| 277 | } | 276 | } |
| 278 | return sizes; | 277 | return sizes; |
| 279 | } | 278 | } |
| 280 | 279 | ||
| 280 | [[nodiscard]] u32 CalculateLevelBytes(const LevelArray& sizes, u32 num_levels) { | ||
| 281 | return std::reduce(sizes.begin(), sizes.begin() + num_levels, 0U); | ||
| 282 | } | ||
| 283 | |||
| 281 | [[nodiscard]] constexpr LevelInfo MakeLevelInfo(PixelFormat format, Extent3D size, Extent3D block, | 284 | [[nodiscard]] constexpr LevelInfo MakeLevelInfo(PixelFormat format, Extent3D size, Extent3D block, |
| 282 | u32 num_samples, u32 tile_width_spacing) { | 285 | u32 num_samples, u32 tile_width_spacing) { |
| 283 | const auto [samples_x, samples_y] = Samples(num_samples); | 286 | const auto [samples_x, samples_y] = Samples(num_samples); |
| @@ -566,10 +569,10 @@ void SwizzleBlockLinearImage(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr | |||
| 566 | 569 | ||
| 567 | const u32 num_levels = info.resources.levels; | 570 | const u32 num_levels = info.resources.levels; |
| 568 | const std::array sizes = CalculateLevelSizes(level_info, num_levels); | 571 | const std::array sizes = CalculateLevelSizes(level_info, num_levels); |
| 569 | size_t guest_offset = std::reduce(sizes.begin(), sizes.begin() + level, 0); | 572 | size_t guest_offset = CalculateLevelBytes(sizes, level); |
| 570 | const size_t layer_stride = | 573 | const size_t layer_stride = |
| 571 | AlignLayerSize(std::reduce(sizes.begin(), sizes.begin() + num_levels, 0), size, | 574 | AlignLayerSize(CalculateLevelBytes(sizes, num_levels), size, level_info.block, |
| 572 | level_info.block, tile_size.height, info.tile_width_spacing); | 575 | tile_size.height, info.tile_width_spacing); |
| 573 | const size_t subresource_size = sizes[level]; | 576 | const size_t subresource_size = sizes[level]; |
| 574 | 577 | ||
| 575 | const auto dst_data = std::make_unique<u8[]>(subresource_size); | 578 | const auto dst_data = std::make_unique<u8[]>(subresource_size); |
| @@ -643,10 +646,10 @@ u32 CalculateLayerSize(const ImageInfo& info) noexcept { | |||
| 643 | info.tile_width_spacing, info.resources.levels); | 646 | info.tile_width_spacing, info.resources.levels); |
| 644 | } | 647 | } |
| 645 | 648 | ||
| 646 | std::array<u32, MAX_MIP_LEVELS> CalculateMipLevelOffsets(const ImageInfo& info) noexcept { | 649 | LevelArray CalculateMipLevelOffsets(const ImageInfo& info) noexcept { |
| 647 | ASSERT(info.resources.levels <= static_cast<s32>(MAX_MIP_LEVELS)); | 650 | ASSERT(info.resources.levels <= static_cast<s32>(MAX_MIP_LEVELS)); |
| 648 | const LevelInfo level_info = MakeLevelInfo(info); | 651 | const LevelInfo level_info = MakeLevelInfo(info); |
| 649 | std::array<u32, MAX_MIP_LEVELS> offsets{}; | 652 | LevelArray offsets{}; |
| 650 | u32 offset = 0; | 653 | u32 offset = 0; |
| 651 | for (s32 level = 0; level < info.resources.levels; ++level) { | 654 | for (s32 level = 0; level < info.resources.levels; ++level) { |
| 652 | offsets[level] = offset; | 655 | offsets[level] = offset; |
| @@ -812,7 +815,7 @@ std::vector<BufferImageCopy> UnswizzleImage(Tegra::MemoryManager& gpu_memory, GP | |||
| 812 | const Extent2D tile_size = DefaultBlockSize(info.format); | 815 | const Extent2D tile_size = DefaultBlockSize(info.format); |
| 813 | const std::array level_sizes = CalculateLevelSizes(level_info, num_levels); | 816 | const std::array level_sizes = CalculateLevelSizes(level_info, num_levels); |
| 814 | const Extent2D gob = GobSize(bpp_log2, info.block.height, info.tile_width_spacing); | 817 | const Extent2D gob = GobSize(bpp_log2, info.block.height, info.tile_width_spacing); |
| 815 | const u32 layer_size = std::reduce(level_sizes.begin(), level_sizes.begin() + num_levels, 0); | 818 | const u32 layer_size = CalculateLevelBytes(level_sizes, num_levels); |
| 816 | const u32 layer_stride = AlignLayerSize(layer_size, size, level_info.block, tile_size.height, | 819 | const u32 layer_stride = AlignLayerSize(layer_size, size, level_info.block, tile_size.height, |
| 817 | info.tile_width_spacing); | 820 | info.tile_width_spacing); |
| 818 | size_t guest_offset = 0; | 821 | size_t guest_offset = 0; |
diff --git a/src/video_core/texture_cache/util.h b/src/video_core/texture_cache/util.h index 4d0072867..cdc5cbc75 100644 --- a/src/video_core/texture_cache/util.h +++ b/src/video_core/texture_cache/util.h | |||
| @@ -20,6 +20,8 @@ namespace VideoCommon { | |||
| 20 | 20 | ||
| 21 | using Tegra::Texture::TICEntry; | 21 | using Tegra::Texture::TICEntry; |
| 22 | 22 | ||
| 23 | using LevelArray = std::array<u32, MAX_MIP_LEVELS>; | ||
| 24 | |||
| 23 | struct OverlapResult { | 25 | struct OverlapResult { |
| 24 | GPUVAddr gpu_addr; | 26 | GPUVAddr gpu_addr; |
| 25 | VAddr cpu_addr; | 27 | VAddr cpu_addr; |
| @@ -36,8 +38,7 @@ struct OverlapResult { | |||
| 36 | 38 | ||
| 37 | [[nodiscard]] u32 CalculateLayerSize(const ImageInfo& info) noexcept; | 39 | [[nodiscard]] u32 CalculateLayerSize(const ImageInfo& info) noexcept; |
| 38 | 40 | ||
| 39 | [[nodiscard]] std::array<u32, MAX_MIP_LEVELS> CalculateMipLevelOffsets( | 41 | [[nodiscard]] LevelArray CalculateMipLevelOffsets(const ImageInfo& info) noexcept; |
| 40 | const ImageInfo& info) noexcept; | ||
| 41 | 42 | ||
| 42 | [[nodiscard]] std::vector<u32> CalculateSliceOffsets(const ImageInfo& info); | 43 | [[nodiscard]] std::vector<u32> CalculateSliceOffsets(const ImageInfo& info); |
| 43 | 44 | ||
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 1d6155999..50ea15e2a 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -771,6 +771,13 @@ void Config::ReadRendererValues() { | |||
| 771 | ReadSettingGlobal(Settings::values.renderer_backend, QStringLiteral("backend"), 0); | 771 | ReadSettingGlobal(Settings::values.renderer_backend, QStringLiteral("backend"), 0); |
| 772 | ReadSettingGlobal(Settings::values.renderer_debug, QStringLiteral("debug"), false); | 772 | ReadSettingGlobal(Settings::values.renderer_debug, QStringLiteral("debug"), false); |
| 773 | ReadSettingGlobal(Settings::values.vulkan_device, QStringLiteral("vulkan_device"), 0); | 773 | ReadSettingGlobal(Settings::values.vulkan_device, QStringLiteral("vulkan_device"), 0); |
| 774 | #ifdef _WIN32 | ||
| 775 | ReadSettingGlobal(Settings::values.fullscreen_mode, QStringLiteral("fullscreen_mode"), 0); | ||
| 776 | #else | ||
| 777 | // *nix platforms may have issues with the borderless windowed fullscreen mode. | ||
| 778 | // Default to exclusive fullscreen on these platforms for now. | ||
| 779 | ReadSettingGlobal(Settings::values.fullscreen_mode, QStringLiteral("fullscreen_mode"), 1); | ||
| 780 | #endif | ||
| 774 | ReadSettingGlobal(Settings::values.aspect_ratio, QStringLiteral("aspect_ratio"), 0); | 781 | ReadSettingGlobal(Settings::values.aspect_ratio, QStringLiteral("aspect_ratio"), 0); |
| 775 | ReadSettingGlobal(Settings::values.max_anisotropy, QStringLiteral("max_anisotropy"), 0); | 782 | ReadSettingGlobal(Settings::values.max_anisotropy, QStringLiteral("max_anisotropy"), 0); |
| 776 | ReadSettingGlobal(Settings::values.use_frame_limit, QStringLiteral("use_frame_limit"), true); | 783 | ReadSettingGlobal(Settings::values.use_frame_limit, QStringLiteral("use_frame_limit"), true); |
| @@ -1334,6 +1341,13 @@ void Config::SaveRendererValues() { | |||
| 1334 | Settings::values.renderer_backend.UsingGlobal(), 0); | 1341 | Settings::values.renderer_backend.UsingGlobal(), 0); |
| 1335 | WriteSetting(QStringLiteral("debug"), Settings::values.renderer_debug, false); | 1342 | WriteSetting(QStringLiteral("debug"), Settings::values.renderer_debug, false); |
| 1336 | WriteSettingGlobal(QStringLiteral("vulkan_device"), Settings::values.vulkan_device, 0); | 1343 | WriteSettingGlobal(QStringLiteral("vulkan_device"), Settings::values.vulkan_device, 0); |
| 1344 | #ifdef _WIN32 | ||
| 1345 | WriteSettingGlobal(QStringLiteral("fullscreen_mode"), Settings::values.fullscreen_mode, 0); | ||
| 1346 | #else | ||
| 1347 | // *nix platforms may have issues with the borderless windowed fullscreen mode. | ||
| 1348 | // Default to exclusive fullscreen on these platforms for now. | ||
| 1349 | WriteSettingGlobal(QStringLiteral("fullscreen_mode"), Settings::values.fullscreen_mode, 1); | ||
| 1350 | #endif | ||
| 1337 | WriteSettingGlobal(QStringLiteral("aspect_ratio"), Settings::values.aspect_ratio, 0); | 1351 | WriteSettingGlobal(QStringLiteral("aspect_ratio"), Settings::values.aspect_ratio, 0); |
| 1338 | WriteSettingGlobal(QStringLiteral("max_anisotropy"), Settings::values.max_anisotropy, 0); | 1352 | WriteSettingGlobal(QStringLiteral("max_anisotropy"), Settings::values.max_anisotropy, 0); |
| 1339 | WriteSettingGlobal(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true); | 1353 | WriteSettingGlobal(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true); |
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 49acc48b2..8a2008b2a 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp | |||
| @@ -77,18 +77,25 @@ void ConfigureGraphics::SetConfiguration() { | |||
| 77 | 77 | ||
| 78 | if (Settings::IsConfiguringGlobal()) { | 78 | if (Settings::IsConfiguringGlobal()) { |
| 79 | ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend.GetValue())); | 79 | ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend.GetValue())); |
| 80 | ui->fullscreen_mode_combobox->setCurrentIndex(Settings::values.fullscreen_mode.GetValue()); | ||
| 80 | ui->aspect_ratio_combobox->setCurrentIndex(Settings::values.aspect_ratio.GetValue()); | 81 | ui->aspect_ratio_combobox->setCurrentIndex(Settings::values.aspect_ratio.GetValue()); |
| 81 | } else { | 82 | } else { |
| 82 | ConfigurationShared::SetPerGameSetting(ui->api, &Settings::values.renderer_backend); | 83 | ConfigurationShared::SetPerGameSetting(ui->api, &Settings::values.renderer_backend); |
| 83 | ConfigurationShared::SetHighlight(ui->api_layout, | 84 | ConfigurationShared::SetHighlight(ui->api_layout, |
| 84 | !Settings::values.renderer_backend.UsingGlobal()); | 85 | !Settings::values.renderer_backend.UsingGlobal()); |
| 86 | |||
| 87 | ConfigurationShared::SetPerGameSetting(ui->fullscreen_mode_combobox, | ||
| 88 | &Settings::values.fullscreen_mode); | ||
| 89 | ConfigurationShared::SetHighlight(ui->fullscreen_mode_label, | ||
| 90 | !Settings::values.fullscreen_mode.UsingGlobal()); | ||
| 91 | |||
| 85 | ConfigurationShared::SetPerGameSetting(ui->aspect_ratio_combobox, | 92 | ConfigurationShared::SetPerGameSetting(ui->aspect_ratio_combobox, |
| 86 | &Settings::values.aspect_ratio); | 93 | &Settings::values.aspect_ratio); |
| 94 | ConfigurationShared::SetHighlight(ui->ar_label, | ||
| 95 | !Settings::values.aspect_ratio.UsingGlobal()); | ||
| 87 | 96 | ||
| 88 | ui->bg_combobox->setCurrentIndex(Settings::values.bg_red.UsingGlobal() ? 0 : 1); | 97 | ui->bg_combobox->setCurrentIndex(Settings::values.bg_red.UsingGlobal() ? 0 : 1); |
| 89 | ui->bg_button->setEnabled(!Settings::values.bg_red.UsingGlobal()); | 98 | ui->bg_button->setEnabled(!Settings::values.bg_red.UsingGlobal()); |
| 90 | ConfigurationShared::SetHighlight(ui->ar_label, | ||
| 91 | !Settings::values.aspect_ratio.UsingGlobal()); | ||
| 92 | ConfigurationShared::SetHighlight(ui->bg_layout, !Settings::values.bg_red.UsingGlobal()); | 99 | ConfigurationShared::SetHighlight(ui->bg_layout, !Settings::values.bg_red.UsingGlobal()); |
| 93 | } | 100 | } |
| 94 | 101 | ||
| @@ -107,6 +114,9 @@ void ConfigureGraphics::ApplyConfiguration() { | |||
| 107 | if (Settings::values.vulkan_device.UsingGlobal()) { | 114 | if (Settings::values.vulkan_device.UsingGlobal()) { |
| 108 | Settings::values.vulkan_device.SetValue(vulkan_device); | 115 | Settings::values.vulkan_device.SetValue(vulkan_device); |
| 109 | } | 116 | } |
| 117 | if (Settings::values.fullscreen_mode.UsingGlobal()) { | ||
| 118 | Settings::values.fullscreen_mode.SetValue(ui->fullscreen_mode_combobox->currentIndex()); | ||
| 119 | } | ||
| 110 | if (Settings::values.aspect_ratio.UsingGlobal()) { | 120 | if (Settings::values.aspect_ratio.UsingGlobal()) { |
| 111 | Settings::values.aspect_ratio.SetValue(ui->aspect_ratio_combobox->currentIndex()); | 121 | Settings::values.aspect_ratio.SetValue(ui->aspect_ratio_combobox->currentIndex()); |
| 112 | } | 122 | } |
| @@ -140,6 +150,8 @@ void ConfigureGraphics::ApplyConfiguration() { | |||
| 140 | } | 150 | } |
| 141 | } | 151 | } |
| 142 | 152 | ||
| 153 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.fullscreen_mode, | ||
| 154 | ui->fullscreen_mode_combobox); | ||
| 143 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.aspect_ratio, | 155 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.aspect_ratio, |
| 144 | ui->aspect_ratio_combobox); | 156 | ui->aspect_ratio_combobox); |
| 145 | 157 | ||
| @@ -253,6 +265,7 @@ void ConfigureGraphics::SetupPerGameUI() { | |||
| 253 | if (Settings::IsConfiguringGlobal()) { | 265 | if (Settings::IsConfiguringGlobal()) { |
| 254 | ui->api->setEnabled(Settings::values.renderer_backend.UsingGlobal()); | 266 | ui->api->setEnabled(Settings::values.renderer_backend.UsingGlobal()); |
| 255 | ui->device->setEnabled(Settings::values.renderer_backend.UsingGlobal()); | 267 | ui->device->setEnabled(Settings::values.renderer_backend.UsingGlobal()); |
| 268 | ui->fullscreen_mode_combobox->setEnabled(Settings::values.fullscreen_mode.UsingGlobal()); | ||
| 256 | ui->aspect_ratio_combobox->setEnabled(Settings::values.aspect_ratio.UsingGlobal()); | 269 | ui->aspect_ratio_combobox->setEnabled(Settings::values.aspect_ratio.UsingGlobal()); |
| 257 | ui->use_asynchronous_gpu_emulation->setEnabled( | 270 | ui->use_asynchronous_gpu_emulation->setEnabled( |
| 258 | Settings::values.use_asynchronous_gpu_emulation.UsingGlobal()); | 271 | Settings::values.use_asynchronous_gpu_emulation.UsingGlobal()); |
| @@ -278,6 +291,8 @@ void ConfigureGraphics::SetupPerGameUI() { | |||
| 278 | 291 | ||
| 279 | ConfigurationShared::SetColoredComboBox(ui->aspect_ratio_combobox, ui->ar_label, | 292 | ConfigurationShared::SetColoredComboBox(ui->aspect_ratio_combobox, ui->ar_label, |
| 280 | Settings::values.aspect_ratio.GetValue(true)); | 293 | Settings::values.aspect_ratio.GetValue(true)); |
| 294 | ConfigurationShared::SetColoredComboBox(ui->fullscreen_mode_combobox, ui->fullscreen_mode_label, | ||
| 295 | Settings::values.fullscreen_mode.GetValue(true)); | ||
| 281 | ConfigurationShared::InsertGlobalItem( | 296 | ConfigurationShared::InsertGlobalItem( |
| 282 | ui->api, static_cast<int>(Settings::values.renderer_backend.GetValue(true))); | 297 | ui->api, static_cast<int>(Settings::values.renderer_backend.GetValue(true))); |
| 283 | } | 298 | } |
diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui index 58486eb1e..ab0bd4d77 100644 --- a/src/yuzu/configuration/configure_graphics.ui +++ b/src/yuzu/configuration/configure_graphics.ui | |||
| @@ -105,8 +105,47 @@ | |||
| 105 | </widget> | 105 | </widget> |
| 106 | </item> | 106 | </item> |
| 107 | <item> | 107 | <item> |
| 108 | <widget class="QWidget" name="fullscreen_mode_layout" native="true"> | ||
| 109 | <layout class="QHBoxLayout" name="horizontalLayout_1"> | ||
| 110 | <property name="leftMargin"> | ||
| 111 | <number>0</number> | ||
| 112 | </property> | ||
| 113 | <property name="topMargin"> | ||
| 114 | <number>0</number> | ||
| 115 | </property> | ||
| 116 | <property name="rightMargin"> | ||
| 117 | <number>0</number> | ||
| 118 | </property> | ||
| 119 | <property name="bottomMargin"> | ||
| 120 | <number>0</number> | ||
| 121 | </property> | ||
| 122 | <item> | ||
| 123 | <widget class="QLabel" name="fullscreen_mode_label"> | ||
| 124 | <property name="text"> | ||
| 125 | <string>Fullscreen Mode:</string> | ||
| 126 | </property> | ||
| 127 | </widget> | ||
| 128 | </item> | ||
| 129 | <item> | ||
| 130 | <widget class="QComboBox" name="fullscreen_mode_combobox"> | ||
| 131 | <item> | ||
| 132 | <property name="text"> | ||
| 133 | <string>Borderless Windowed</string> | ||
| 134 | </property> | ||
| 135 | </item> | ||
| 136 | <item> | ||
| 137 | <property name="text"> | ||
| 138 | <string>Exclusive Fullscreen</string> | ||
| 139 | </property> | ||
| 140 | </item> | ||
| 141 | </widget> | ||
| 142 | </item> | ||
| 143 | </layout> | ||
| 144 | </widget> | ||
| 145 | </item> | ||
| 146 | <item> | ||
| 108 | <widget class="QWidget" name="aspect_ratio_layout" native="true"> | 147 | <widget class="QWidget" name="aspect_ratio_layout" native="true"> |
| 109 | <layout class="QHBoxLayout" name="horizontalLayout_6"> | 148 | <layout class="QHBoxLayout" name="horizontalLayout_2"> |
| 110 | <property name="leftMargin"> | 149 | <property name="leftMargin"> |
| 111 | <number>0</number> | 150 | <number>0</number> |
| 112 | </property> | 151 | </property> |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 06445b993..23ea4983d 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -2295,24 +2295,66 @@ void GMainWindow::ToggleFullscreen() { | |||
| 2295 | void GMainWindow::ShowFullscreen() { | 2295 | void GMainWindow::ShowFullscreen() { |
| 2296 | if (ui.action_Single_Window_Mode->isChecked()) { | 2296 | if (ui.action_Single_Window_Mode->isChecked()) { |
| 2297 | UISettings::values.geometry = saveGeometry(); | 2297 | UISettings::values.geometry = saveGeometry(); |
| 2298 | |||
| 2298 | ui.menubar->hide(); | 2299 | ui.menubar->hide(); |
| 2299 | statusBar()->hide(); | 2300 | statusBar()->hide(); |
| 2300 | showFullScreen(); | 2301 | |
| 2302 | if (Settings::values.fullscreen_mode.GetValue() == 1) { | ||
| 2303 | showFullScreen(); | ||
| 2304 | return; | ||
| 2305 | } | ||
| 2306 | |||
| 2307 | hide(); | ||
| 2308 | setWindowFlags(windowFlags() | Qt::FramelessWindowHint); | ||
| 2309 | const auto screen_geometry = QApplication::desktop()->screenGeometry(this); | ||
| 2310 | setGeometry(screen_geometry.x(), screen_geometry.y(), screen_geometry.width(), | ||
| 2311 | screen_geometry.height() + 1); | ||
| 2312 | raise(); | ||
| 2313 | showNormal(); | ||
| 2301 | } else { | 2314 | } else { |
| 2302 | UISettings::values.renderwindow_geometry = render_window->saveGeometry(); | 2315 | UISettings::values.renderwindow_geometry = render_window->saveGeometry(); |
| 2303 | render_window->showFullScreen(); | 2316 | |
| 2317 | if (Settings::values.fullscreen_mode.GetValue() == 1) { | ||
| 2318 | render_window->showFullScreen(); | ||
| 2319 | return; | ||
| 2320 | } | ||
| 2321 | |||
| 2322 | render_window->hide(); | ||
| 2323 | render_window->setWindowFlags(windowFlags() | Qt::FramelessWindowHint); | ||
| 2324 | const auto screen_geometry = QApplication::desktop()->screenGeometry(this); | ||
| 2325 | render_window->setGeometry(screen_geometry.x(), screen_geometry.y(), | ||
| 2326 | screen_geometry.width(), screen_geometry.height() + 1); | ||
| 2327 | render_window->raise(); | ||
| 2328 | render_window->showNormal(); | ||
| 2304 | } | 2329 | } |
| 2305 | } | 2330 | } |
| 2306 | 2331 | ||
| 2307 | void GMainWindow::HideFullscreen() { | 2332 | void GMainWindow::HideFullscreen() { |
| 2308 | if (ui.action_Single_Window_Mode->isChecked()) { | 2333 | if (ui.action_Single_Window_Mode->isChecked()) { |
| 2334 | if (Settings::values.fullscreen_mode.GetValue() == 1) { | ||
| 2335 | showNormal(); | ||
| 2336 | restoreGeometry(UISettings::values.geometry); | ||
| 2337 | } else { | ||
| 2338 | hide(); | ||
| 2339 | setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); | ||
| 2340 | restoreGeometry(UISettings::values.geometry); | ||
| 2341 | raise(); | ||
| 2342 | show(); | ||
| 2343 | } | ||
| 2344 | |||
| 2309 | statusBar()->setVisible(ui.action_Show_Status_Bar->isChecked()); | 2345 | statusBar()->setVisible(ui.action_Show_Status_Bar->isChecked()); |
| 2310 | ui.menubar->show(); | 2346 | ui.menubar->show(); |
| 2311 | showNormal(); | ||
| 2312 | restoreGeometry(UISettings::values.geometry); | ||
| 2313 | } else { | 2347 | } else { |
| 2314 | render_window->showNormal(); | 2348 | if (Settings::values.fullscreen_mode.GetValue() == 1) { |
| 2315 | render_window->restoreGeometry(UISettings::values.renderwindow_geometry); | 2349 | render_window->showNormal(); |
| 2350 | render_window->restoreGeometry(UISettings::values.renderwindow_geometry); | ||
| 2351 | } else { | ||
| 2352 | render_window->hide(); | ||
| 2353 | render_window->setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); | ||
| 2354 | render_window->restoreGeometry(UISettings::values.renderwindow_geometry); | ||
| 2355 | render_window->raise(); | ||
| 2356 | render_window->show(); | ||
| 2357 | } | ||
| 2316 | } | 2358 | } |
| 2317 | } | 2359 | } |
| 2318 | 2360 | ||