diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp | 9 | ||||
| -rw-r--r-- | src/audio_core/adsp/apps/audio_renderer/audio_renderer.h | 2 | ||||
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 46 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 16 | ||||
| -rw-r--r-- | src/video_core/texture_cache/util.cpp | 41 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_memory_allocator.cpp | 8 | ||||
| -rw-r--r-- | src/yuzu/applets/qt_controller.cpp | 39 | ||||
| -rw-r--r-- | src/yuzu/applets/qt_controller.h | 6 | ||||
| -rw-r--r-- | src/yuzu/applets/qt_controller.ui | 54 |
10 files changed, 167 insertions, 68 deletions
diff --git a/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp index 972d5e45b..ef301d8b4 100644 --- a/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp +++ b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp | |||
| @@ -77,6 +77,7 @@ void AudioRenderer::Wait() { | |||
| 77 | "{}, got {}", | 77 | "{}, got {}", |
| 78 | Message::RenderResponse, msg); | 78 | Message::RenderResponse, msg); |
| 79 | } | 79 | } |
| 80 | PostDSPClearCommandBuffer(); | ||
| 80 | } | 81 | } |
| 81 | 82 | ||
| 82 | void AudioRenderer::Send(Direction dir, u32 message) { | 83 | void AudioRenderer::Send(Direction dir, u32 message) { |
| @@ -96,6 +97,14 @@ void AudioRenderer::SetCommandBuffer(s32 session_id, CpuAddr buffer, u64 size, u | |||
| 96 | command_buffers[session_id].reset_buffer = reset; | 97 | command_buffers[session_id].reset_buffer = reset; |
| 97 | } | 98 | } |
| 98 | 99 | ||
| 100 | void AudioRenderer::PostDSPClearCommandBuffer() noexcept { | ||
| 101 | for (auto& buffer : command_buffers) { | ||
| 102 | buffer.buffer = 0; | ||
| 103 | buffer.size = 0; | ||
| 104 | buffer.reset_buffer = false; | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 99 | u32 AudioRenderer::GetRemainCommandCount(s32 session_id) const noexcept { | 108 | u32 AudioRenderer::GetRemainCommandCount(s32 session_id) const noexcept { |
| 100 | return command_buffers[session_id].remaining_command_count; | 109 | return command_buffers[session_id].remaining_command_count; |
| 101 | } | 110 | } |
diff --git a/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h index 85874d88a..57b89d9fe 100644 --- a/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h +++ b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h | |||
| @@ -85,6 +85,8 @@ private: | |||
| 85 | */ | 85 | */ |
| 86 | void CreateSinkStreams(); | 86 | void CreateSinkStreams(); |
| 87 | 87 | ||
| 88 | void PostDSPClearCommandBuffer() noexcept; | ||
| 89 | |||
| 88 | /// Core system | 90 | /// Core system |
| 89 | Core::System& system; | 91 | Core::System& system; |
| 90 | /// The output sink the AudioRenderer will send samples to | 92 | /// The output sink the AudioRenderer will send samples to |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 9e90c587c..9b2698fad 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -544,7 +544,7 @@ void BufferCache<P>::CommitAsyncFlushesHigh() { | |||
| 544 | it++; | 544 | it++; |
| 545 | } | 545 | } |
| 546 | 546 | ||
| 547 | boost::container::small_vector<std::pair<BufferCopy, BufferId>, 1> downloads; | 547 | boost::container::small_vector<std::pair<BufferCopy, BufferId>, 16> downloads; |
| 548 | u64 total_size_bytes = 0; | 548 | u64 total_size_bytes = 0; |
| 549 | u64 largest_copy = 0; | 549 | u64 largest_copy = 0; |
| 550 | for (const IntervalSet& intervals : committed_ranges) { | 550 | for (const IntervalSet& intervals : committed_ranges) { |
| @@ -914,6 +914,11 @@ void BufferCache<P>::BindHostGraphicsStorageBuffers(size_t stage) { | |||
| 914 | 914 | ||
| 915 | const u32 offset = buffer.Offset(binding.cpu_addr); | 915 | const u32 offset = buffer.Offset(binding.cpu_addr); |
| 916 | const bool is_written = ((channel_state->written_storage_buffers[stage] >> index) & 1) != 0; | 916 | const bool is_written = ((channel_state->written_storage_buffers[stage] >> index) & 1) != 0; |
| 917 | |||
| 918 | if (is_written) { | ||
| 919 | MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, size); | ||
| 920 | } | ||
| 921 | |||
| 917 | if constexpr (NEEDS_BIND_STORAGE_INDEX) { | 922 | if constexpr (NEEDS_BIND_STORAGE_INDEX) { |
| 918 | runtime.BindStorageBuffer(stage, binding_index, buffer, offset, size, is_written); | 923 | runtime.BindStorageBuffer(stage, binding_index, buffer, offset, size, is_written); |
| 919 | ++binding_index; | 924 | ++binding_index; |
| @@ -931,6 +936,11 @@ void BufferCache<P>::BindHostGraphicsTextureBuffers(size_t stage) { | |||
| 931 | const u32 size = binding.size; | 936 | const u32 size = binding.size; |
| 932 | SynchronizeBuffer(buffer, binding.cpu_addr, size); | 937 | SynchronizeBuffer(buffer, binding.cpu_addr, size); |
| 933 | 938 | ||
| 939 | const bool is_written = ((channel_state->written_texture_buffers[stage] >> index) & 1) != 0; | ||
| 940 | if (is_written) { | ||
| 941 | MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, size); | ||
| 942 | } | ||
| 943 | |||
| 934 | const u32 offset = buffer.Offset(binding.cpu_addr); | 944 | const u32 offset = buffer.Offset(binding.cpu_addr); |
| 935 | const PixelFormat format = binding.format; | 945 | const PixelFormat format = binding.format; |
| 936 | if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) { | 946 | if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) { |
| @@ -962,6 +972,8 @@ void BufferCache<P>::BindHostTransformFeedbackBuffers() { | |||
| 962 | const u32 size = binding.size; | 972 | const u32 size = binding.size; |
| 963 | SynchronizeBuffer(buffer, binding.cpu_addr, size); | 973 | SynchronizeBuffer(buffer, binding.cpu_addr, size); |
| 964 | 974 | ||
| 975 | MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, size); | ||
| 976 | |||
| 965 | const u32 offset = buffer.Offset(binding.cpu_addr); | 977 | const u32 offset = buffer.Offset(binding.cpu_addr); |
| 966 | host_bindings.buffers.push_back(&buffer); | 978 | host_bindings.buffers.push_back(&buffer); |
| 967 | host_bindings.offsets.push_back(offset); | 979 | host_bindings.offsets.push_back(offset); |
| @@ -1011,6 +1023,11 @@ void BufferCache<P>::BindHostComputeStorageBuffers() { | |||
| 1011 | const u32 offset = buffer.Offset(binding.cpu_addr); | 1023 | const u32 offset = buffer.Offset(binding.cpu_addr); |
| 1012 | const bool is_written = | 1024 | const bool is_written = |
| 1013 | ((channel_state->written_compute_storage_buffers >> index) & 1) != 0; | 1025 | ((channel_state->written_compute_storage_buffers >> index) & 1) != 0; |
| 1026 | |||
| 1027 | if (is_written) { | ||
| 1028 | MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, size); | ||
| 1029 | } | ||
| 1030 | |||
| 1014 | if constexpr (NEEDS_BIND_STORAGE_INDEX) { | 1031 | if constexpr (NEEDS_BIND_STORAGE_INDEX) { |
| 1015 | runtime.BindComputeStorageBuffer(binding_index, buffer, offset, size, is_written); | 1032 | runtime.BindComputeStorageBuffer(binding_index, buffer, offset, size, is_written); |
| 1016 | ++binding_index; | 1033 | ++binding_index; |
| @@ -1028,6 +1045,12 @@ void BufferCache<P>::BindHostComputeTextureBuffers() { | |||
| 1028 | const u32 size = binding.size; | 1045 | const u32 size = binding.size; |
| 1029 | SynchronizeBuffer(buffer, binding.cpu_addr, size); | 1046 | SynchronizeBuffer(buffer, binding.cpu_addr, size); |
| 1030 | 1047 | ||
| 1048 | const bool is_written = | ||
| 1049 | ((channel_state->written_compute_texture_buffers >> index) & 1) != 0; | ||
| 1050 | if (is_written) { | ||
| 1051 | MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, size); | ||
| 1052 | } | ||
| 1053 | |||
| 1031 | const u32 offset = buffer.Offset(binding.cpu_addr); | 1054 | const u32 offset = buffer.Offset(binding.cpu_addr); |
| 1032 | const PixelFormat format = binding.format; | 1055 | const PixelFormat format = binding.format; |
| 1033 | if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) { | 1056 | if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) { |
| @@ -1201,16 +1224,11 @@ void BufferCache<P>::UpdateUniformBuffers(size_t stage) { | |||
| 1201 | 1224 | ||
| 1202 | template <class P> | 1225 | template <class P> |
| 1203 | void BufferCache<P>::UpdateStorageBuffers(size_t stage) { | 1226 | void BufferCache<P>::UpdateStorageBuffers(size_t stage) { |
| 1204 | const u32 written_mask = channel_state->written_storage_buffers[stage]; | ||
| 1205 | ForEachEnabledBit(channel_state->enabled_storage_buffers[stage], [&](u32 index) { | 1227 | ForEachEnabledBit(channel_state->enabled_storage_buffers[stage], [&](u32 index) { |
| 1206 | // Resolve buffer | 1228 | // Resolve buffer |
| 1207 | Binding& binding = channel_state->storage_buffers[stage][index]; | 1229 | Binding& binding = channel_state->storage_buffers[stage][index]; |
| 1208 | const BufferId buffer_id = FindBuffer(binding.cpu_addr, binding.size); | 1230 | const BufferId buffer_id = FindBuffer(binding.cpu_addr, binding.size); |
| 1209 | binding.buffer_id = buffer_id; | 1231 | binding.buffer_id = buffer_id; |
| 1210 | // Mark buffer as written if needed | ||
| 1211 | if (((written_mask >> index) & 1) != 0) { | ||
| 1212 | MarkWrittenBuffer(buffer_id, binding.cpu_addr, binding.size); | ||
| 1213 | } | ||
| 1214 | }); | 1232 | }); |
| 1215 | } | 1233 | } |
| 1216 | 1234 | ||
| @@ -1219,10 +1237,6 @@ void BufferCache<P>::UpdateTextureBuffers(size_t stage) { | |||
| 1219 | ForEachEnabledBit(channel_state->enabled_texture_buffers[stage], [&](u32 index) { | 1237 | ForEachEnabledBit(channel_state->enabled_texture_buffers[stage], [&](u32 index) { |
| 1220 | Binding& binding = channel_state->texture_buffers[stage][index]; | 1238 | Binding& binding = channel_state->texture_buffers[stage][index]; |
| 1221 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); | 1239 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); |
| 1222 | // Mark buffer as written if needed | ||
| 1223 | if (((channel_state->written_texture_buffers[stage] >> index) & 1) != 0) { | ||
| 1224 | MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, binding.size); | ||
| 1225 | } | ||
| 1226 | }); | 1240 | }); |
| 1227 | } | 1241 | } |
| 1228 | 1242 | ||
| @@ -1252,7 +1266,6 @@ void BufferCache<P>::UpdateTransformFeedbackBuffer(u32 index) { | |||
| 1252 | .size = size, | 1266 | .size = size, |
| 1253 | .buffer_id = buffer_id, | 1267 | .buffer_id = buffer_id, |
| 1254 | }; | 1268 | }; |
| 1255 | MarkWrittenBuffer(buffer_id, *cpu_addr, size); | ||
| 1256 | } | 1269 | } |
| 1257 | 1270 | ||
| 1258 | template <class P> | 1271 | template <class P> |
| @@ -1279,10 +1292,6 @@ void BufferCache<P>::UpdateComputeStorageBuffers() { | |||
| 1279 | // Resolve buffer | 1292 | // Resolve buffer |
| 1280 | Binding& binding = channel_state->compute_storage_buffers[index]; | 1293 | Binding& binding = channel_state->compute_storage_buffers[index]; |
| 1281 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); | 1294 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); |
| 1282 | // Mark as written if needed | ||
| 1283 | if (((channel_state->written_compute_storage_buffers >> index) & 1) != 0) { | ||
| 1284 | MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, binding.size); | ||
| 1285 | } | ||
| 1286 | }); | 1295 | }); |
| 1287 | } | 1296 | } |
| 1288 | 1297 | ||
| @@ -1291,18 +1300,11 @@ void BufferCache<P>::UpdateComputeTextureBuffers() { | |||
| 1291 | ForEachEnabledBit(channel_state->enabled_compute_texture_buffers, [&](u32 index) { | 1300 | ForEachEnabledBit(channel_state->enabled_compute_texture_buffers, [&](u32 index) { |
| 1292 | Binding& binding = channel_state->compute_texture_buffers[index]; | 1301 | Binding& binding = channel_state->compute_texture_buffers[index]; |
| 1293 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); | 1302 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); |
| 1294 | // Mark as written if needed | ||
| 1295 | if (((channel_state->written_compute_texture_buffers >> index) & 1) != 0) { | ||
| 1296 | MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, binding.size); | ||
| 1297 | } | ||
| 1298 | }); | 1303 | }); |
| 1299 | } | 1304 | } |
| 1300 | 1305 | ||
| 1301 | template <class P> | 1306 | template <class P> |
| 1302 | void BufferCache<P>::MarkWrittenBuffer(BufferId buffer_id, VAddr cpu_addr, u32 size) { | 1307 | void BufferCache<P>::MarkWrittenBuffer(BufferId buffer_id, VAddr cpu_addr, u32 size) { |
| 1303 | if (memory_tracker.IsRegionCpuModified(cpu_addr, size)) { | ||
| 1304 | SynchronizeBuffer(slot_buffers[buffer_id], cpu_addr, size); | ||
| 1305 | } | ||
| 1306 | memory_tracker.MarkRegionAsGpuModified(cpu_addr, size); | 1308 | memory_tracker.MarkRegionAsGpuModified(cpu_addr, size); |
| 1307 | 1309 | ||
| 1308 | const IntervalType base_interval{cpu_addr, cpu_addr + size}; | 1310 | const IntervalType base_interval{cpu_addr, cpu_addr + size}; |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 9cafd2983..512eef575 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -1048,6 +1048,10 @@ void Image::Scale(bool up_scale) { | |||
| 1048 | } | 1048 | } |
| 1049 | 1049 | ||
| 1050 | bool Image::ScaleUp(bool ignore) { | 1050 | bool Image::ScaleUp(bool ignore) { |
| 1051 | const auto& resolution = runtime->resolution; | ||
| 1052 | if (!resolution.active) { | ||
| 1053 | return false; | ||
| 1054 | } | ||
| 1051 | if (True(flags & ImageFlagBits::Rescaled)) { | 1055 | if (True(flags & ImageFlagBits::Rescaled)) { |
| 1052 | return false; | 1056 | return false; |
| 1053 | } | 1057 | } |
| @@ -1060,9 +1064,6 @@ bool Image::ScaleUp(bool ignore) { | |||
| 1060 | return false; | 1064 | return false; |
| 1061 | } | 1065 | } |
| 1062 | flags |= ImageFlagBits::Rescaled; | 1066 | flags |= ImageFlagBits::Rescaled; |
| 1063 | if (!runtime->resolution.active) { | ||
| 1064 | return false; | ||
| 1065 | } | ||
| 1066 | has_scaled = true; | 1067 | has_scaled = true; |
| 1067 | if (ignore) { | 1068 | if (ignore) { |
| 1068 | current_texture = upscaled_backup.handle; | 1069 | current_texture = upscaled_backup.handle; |
| @@ -1073,13 +1074,14 @@ bool Image::ScaleUp(bool ignore) { | |||
| 1073 | } | 1074 | } |
| 1074 | 1075 | ||
| 1075 | bool Image::ScaleDown(bool ignore) { | 1076 | bool Image::ScaleDown(bool ignore) { |
| 1076 | if (False(flags & ImageFlagBits::Rescaled)) { | 1077 | const auto& resolution = runtime->resolution; |
| 1078 | if (!resolution.active) { | ||
| 1077 | return false; | 1079 | return false; |
| 1078 | } | 1080 | } |
| 1079 | flags &= ~ImageFlagBits::Rescaled; | 1081 | if (False(flags & ImageFlagBits::Rescaled)) { |
| 1080 | if (!runtime->resolution.active) { | ||
| 1081 | return false; | 1082 | return false; |
| 1082 | } | 1083 | } |
| 1084 | flags &= ~ImageFlagBits::Rescaled; | ||
| 1083 | if (ignore) { | 1085 | if (ignore) { |
| 1084 | current_texture = texture.handle; | 1086 | current_texture = texture.handle; |
| 1085 | return true; | 1087 | return true; |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 00ab47268..1b8bb9662 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -1530,15 +1530,15 @@ bool Image::IsRescaled() const noexcept { | |||
| 1530 | } | 1530 | } |
| 1531 | 1531 | ||
| 1532 | bool Image::ScaleUp(bool ignore) { | 1532 | bool Image::ScaleUp(bool ignore) { |
| 1533 | const auto& resolution = runtime->resolution; | ||
| 1534 | if (!resolution.active) { | ||
| 1535 | return false; | ||
| 1536 | } | ||
| 1533 | if (True(flags & ImageFlagBits::Rescaled)) { | 1537 | if (True(flags & ImageFlagBits::Rescaled)) { |
| 1534 | return false; | 1538 | return false; |
| 1535 | } | 1539 | } |
| 1536 | ASSERT(info.type != ImageType::Linear); | 1540 | ASSERT(info.type != ImageType::Linear); |
| 1537 | flags |= ImageFlagBits::Rescaled; | 1541 | flags |= ImageFlagBits::Rescaled; |
| 1538 | const auto& resolution = runtime->resolution; | ||
| 1539 | if (!resolution.active) { | ||
| 1540 | return false; | ||
| 1541 | } | ||
| 1542 | has_scaled = true; | 1542 | has_scaled = true; |
| 1543 | if (!scaled_image) { | 1543 | if (!scaled_image) { |
| 1544 | const bool is_2d = info.type == ImageType::e2D; | 1544 | const bool is_2d = info.type == ImageType::e2D; |
| @@ -1567,15 +1567,15 @@ bool Image::ScaleUp(bool ignore) { | |||
| 1567 | } | 1567 | } |
| 1568 | 1568 | ||
| 1569 | bool Image::ScaleDown(bool ignore) { | 1569 | bool Image::ScaleDown(bool ignore) { |
| 1570 | const auto& resolution = runtime->resolution; | ||
| 1571 | if (!resolution.active) { | ||
| 1572 | return false; | ||
| 1573 | } | ||
| 1570 | if (False(flags & ImageFlagBits::Rescaled)) { | 1574 | if (False(flags & ImageFlagBits::Rescaled)) { |
| 1571 | return false; | 1575 | return false; |
| 1572 | } | 1576 | } |
| 1573 | ASSERT(info.type != ImageType::Linear); | 1577 | ASSERT(info.type != ImageType::Linear); |
| 1574 | flags &= ~ImageFlagBits::Rescaled; | 1578 | flags &= ~ImageFlagBits::Rescaled; |
| 1575 | const auto& resolution = runtime->resolution; | ||
| 1576 | if (!resolution.active) { | ||
| 1577 | return false; | ||
| 1578 | } | ||
| 1579 | current_image = *original_image; | 1579 | current_image = *original_image; |
| 1580 | if (ignore) { | 1580 | if (ignore) { |
| 1581 | return true; | 1581 | return true; |
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp index 0a86ce139..8151cabf0 100644 --- a/src/video_core/texture_cache/util.cpp +++ b/src/video_core/texture_cache/util.cpp | |||
| @@ -68,6 +68,7 @@ struct LevelInfo { | |||
| 68 | Extent2D tile_size; | 68 | Extent2D tile_size; |
| 69 | u32 bpp_log2; | 69 | u32 bpp_log2; |
| 70 | u32 tile_width_spacing; | 70 | u32 tile_width_spacing; |
| 71 | u32 num_levels; | ||
| 71 | }; | 72 | }; |
| 72 | 73 | ||
| 73 | [[nodiscard]] constexpr u32 AdjustTileSize(u32 shift, u32 unit_factor, u32 dimension) { | 74 | [[nodiscard]] constexpr u32 AdjustTileSize(u32 shift, u32 unit_factor, u32 dimension) { |
| @@ -118,11 +119,11 @@ template <u32 GOB_EXTENT> | |||
| 118 | } | 119 | } |
| 119 | 120 | ||
| 120 | [[nodiscard]] constexpr Extent3D AdjustMipBlockSize(Extent3D num_tiles, Extent3D block_size, | 121 | [[nodiscard]] constexpr Extent3D AdjustMipBlockSize(Extent3D num_tiles, Extent3D block_size, |
| 121 | u32 level) { | 122 | u32 level, u32 num_levels) { |
| 122 | return { | 123 | return { |
| 123 | .width = AdjustMipBlockSize<GOB_SIZE_X>(num_tiles.width, block_size.width, level), | 124 | .width = AdjustMipBlockSize<GOB_SIZE_X>(num_tiles.width, block_size.width, level), |
| 124 | .height = AdjustMipBlockSize<GOB_SIZE_Y>(num_tiles.height, block_size.height, level), | 125 | .height = AdjustMipBlockSize<GOB_SIZE_Y>(num_tiles.height, block_size.height, level), |
| 125 | .depth = level == 0 | 126 | .depth = level == 0 && num_levels == 1 |
| 126 | ? block_size.depth | 127 | ? block_size.depth |
| 127 | : AdjustMipBlockSize<GOB_SIZE_Z>(num_tiles.depth, block_size.depth, level), | 128 | : AdjustMipBlockSize<GOB_SIZE_Z>(num_tiles.depth, block_size.depth, level), |
| 128 | }; | 129 | }; |
| @@ -166,13 +167,6 @@ template <u32 GOB_EXTENT> | |||
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | [[nodiscard]] constexpr Extent3D TileShift(const LevelInfo& info, u32 level) { | 169 | [[nodiscard]] constexpr Extent3D TileShift(const LevelInfo& info, u32 level) { |
| 169 | if (level == 0) { | ||
| 170 | return Extent3D{ | ||
| 171 | .width = info.block.width, | ||
| 172 | .height = info.block.height, | ||
| 173 | .depth = info.block.depth, | ||
| 174 | }; | ||
| 175 | } | ||
| 176 | const Extent3D blocks = NumLevelBlocks(info, level); | 170 | const Extent3D blocks = NumLevelBlocks(info, level); |
| 177 | return Extent3D{ | 171 | return Extent3D{ |
| 178 | .width = AdjustTileSize(info.block.width, GOB_SIZE_X, blocks.width), | 172 | .width = AdjustTileSize(info.block.width, GOB_SIZE_X, blocks.width), |
| @@ -257,7 +251,7 @@ template <u32 GOB_EXTENT> | |||
| 257 | } | 251 | } |
| 258 | 252 | ||
| 259 | [[nodiscard]] constexpr LevelInfo MakeLevelInfo(PixelFormat format, Extent3D size, Extent3D block, | 253 | [[nodiscard]] constexpr LevelInfo MakeLevelInfo(PixelFormat format, Extent3D size, Extent3D block, |
| 260 | u32 tile_width_spacing) { | 254 | u32 tile_width_spacing, u32 num_levels) { |
| 261 | const u32 bytes_per_block = BytesPerBlock(format); | 255 | const u32 bytes_per_block = BytesPerBlock(format); |
| 262 | return { | 256 | return { |
| 263 | .size = | 257 | .size = |
| @@ -270,16 +264,18 @@ template <u32 GOB_EXTENT> | |||
| 270 | .tile_size = DefaultBlockSize(format), | 264 | .tile_size = DefaultBlockSize(format), |
| 271 | .bpp_log2 = BytesPerBlockLog2(bytes_per_block), | 265 | .bpp_log2 = BytesPerBlockLog2(bytes_per_block), |
| 272 | .tile_width_spacing = tile_width_spacing, | 266 | .tile_width_spacing = tile_width_spacing, |
| 267 | .num_levels = num_levels, | ||
| 273 | }; | 268 | }; |
| 274 | } | 269 | } |
| 275 | 270 | ||
| 276 | [[nodiscard]] constexpr LevelInfo MakeLevelInfo(const ImageInfo& info) { | 271 | [[nodiscard]] constexpr LevelInfo MakeLevelInfo(const ImageInfo& info) { |
| 277 | return MakeLevelInfo(info.format, info.size, info.block, info.tile_width_spacing); | 272 | return MakeLevelInfo(info.format, info.size, info.block, info.tile_width_spacing, |
| 273 | info.resources.levels); | ||
| 278 | } | 274 | } |
| 279 | 275 | ||
| 280 | [[nodiscard]] constexpr u32 CalculateLevelOffset(PixelFormat format, Extent3D size, Extent3D block, | 276 | [[nodiscard]] constexpr u32 CalculateLevelOffset(PixelFormat format, Extent3D size, Extent3D block, |
| 281 | u32 tile_width_spacing, u32 level) { | 277 | u32 tile_width_spacing, u32 level) { |
| 282 | const LevelInfo info = MakeLevelInfo(format, size, block, tile_width_spacing); | 278 | const LevelInfo info = MakeLevelInfo(format, size, block, tile_width_spacing, level); |
| 283 | u32 offset = 0; | 279 | u32 offset = 0; |
| 284 | for (u32 current_level = 0; current_level < level; ++current_level) { | 280 | for (u32 current_level = 0; current_level < level; ++current_level) { |
| 285 | offset += CalculateLevelSize(info, current_level); | 281 | offset += CalculateLevelSize(info, current_level); |
| @@ -466,7 +462,7 @@ template <u32 GOB_EXTENT> | |||
| 466 | }; | 462 | }; |
| 467 | const u32 bpp_log2 = BytesPerBlockLog2(info.format); | 463 | const u32 bpp_log2 = BytesPerBlockLog2(info.format); |
| 468 | const u32 alignment = StrideAlignment(num_tiles, info.block, bpp_log2, info.tile_width_spacing); | 464 | const u32 alignment = StrideAlignment(num_tiles, info.block, bpp_log2, info.tile_width_spacing); |
| 469 | const Extent3D mip_block = AdjustMipBlockSize(num_tiles, info.block, 0); | 465 | const Extent3D mip_block = AdjustMipBlockSize(num_tiles, info.block, 0, info.resources.levels); |
| 470 | return Extent3D{ | 466 | return Extent3D{ |
| 471 | .width = Common::AlignUpLog2(num_tiles.width, alignment), | 467 | .width = Common::AlignUpLog2(num_tiles.width, alignment), |
| 472 | .height = Common::AlignUpLog2(num_tiles.height, GOB_SIZE_Y_SHIFT + mip_block.height), | 468 | .height = Common::AlignUpLog2(num_tiles.height, GOB_SIZE_Y_SHIFT + mip_block.height), |
| @@ -533,7 +529,8 @@ void SwizzleBlockLinearImage(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr | |||
| 533 | UNIMPLEMENTED_IF(copy.image_extent != level_size); | 529 | UNIMPLEMENTED_IF(copy.image_extent != level_size); |
| 534 | 530 | ||
| 535 | const Extent3D num_tiles = AdjustTileSize(level_size, tile_size); | 531 | const Extent3D num_tiles = AdjustTileSize(level_size, tile_size); |
| 536 | const Extent3D block = AdjustMipBlockSize(num_tiles, level_info.block, level); | 532 | const Extent3D block = |
| 533 | AdjustMipBlockSize(num_tiles, level_info.block, level, level_info.num_levels); | ||
| 537 | 534 | ||
| 538 | size_t host_offset = copy.buffer_offset; | 535 | size_t host_offset = copy.buffer_offset; |
| 539 | 536 | ||
| @@ -698,7 +695,7 @@ u32 CalculateLevelStrideAlignment(const ImageInfo& info, u32 level) { | |||
| 698 | const Extent2D tile_size = DefaultBlockSize(info.format); | 695 | const Extent2D tile_size = DefaultBlockSize(info.format); |
| 699 | const Extent3D level_size = AdjustMipSize(info.size, level); | 696 | const Extent3D level_size = AdjustMipSize(info.size, level); |
| 700 | const Extent3D num_tiles = AdjustTileSize(level_size, tile_size); | 697 | const Extent3D num_tiles = AdjustTileSize(level_size, tile_size); |
| 701 | const Extent3D block = AdjustMipBlockSize(num_tiles, info.block, level); | 698 | const Extent3D block = AdjustMipBlockSize(num_tiles, info.block, level, info.resources.levels); |
| 702 | const u32 bpp_log2 = BytesPerBlockLog2(info.format); | 699 | const u32 bpp_log2 = BytesPerBlockLog2(info.format); |
| 703 | return StrideAlignment(num_tiles, block, bpp_log2, info.tile_width_spacing); | 700 | return StrideAlignment(num_tiles, block, bpp_log2, info.tile_width_spacing); |
| 704 | } | 701 | } |
| @@ -887,7 +884,8 @@ boost::container::small_vector<BufferImageCopy, 16> UnswizzleImage(Tegra::Memory | |||
| 887 | .image_extent = level_size, | 884 | .image_extent = level_size, |
| 888 | }; | 885 | }; |
| 889 | const Extent3D num_tiles = AdjustTileSize(level_size, tile_size); | 886 | const Extent3D num_tiles = AdjustTileSize(level_size, tile_size); |
| 890 | const Extent3D block = AdjustMipBlockSize(num_tiles, level_info.block, level); | 887 | const Extent3D block = |
| 888 | AdjustMipBlockSize(num_tiles, level_info.block, level, level_info.num_levels); | ||
| 891 | const u32 stride_alignment = StrideAlignment(num_tiles, info.block, gob, bpp_log2); | 889 | const u32 stride_alignment = StrideAlignment(num_tiles, info.block, gob, bpp_log2); |
| 892 | size_t guest_layer_offset = 0; | 890 | size_t guest_layer_offset = 0; |
| 893 | 891 | ||
| @@ -1041,7 +1039,7 @@ Extent3D MipBlockSize(const ImageInfo& info, u32 level) { | |||
| 1041 | const Extent2D tile_size = DefaultBlockSize(info.format); | 1039 | const Extent2D tile_size = DefaultBlockSize(info.format); |
| 1042 | const Extent3D level_size = AdjustMipSize(info.size, level); | 1040 | const Extent3D level_size = AdjustMipSize(info.size, level); |
| 1043 | const Extent3D num_tiles = AdjustTileSize(level_size, tile_size); | 1041 | const Extent3D num_tiles = AdjustTileSize(level_size, tile_size); |
| 1044 | return AdjustMipBlockSize(num_tiles, level_info.block, level); | 1042 | return AdjustMipBlockSize(num_tiles, level_info.block, level, level_info.num_levels); |
| 1045 | } | 1043 | } |
| 1046 | 1044 | ||
| 1047 | boost::container::small_vector<SwizzleParameters, 16> FullUploadSwizzles(const ImageInfo& info) { | 1045 | boost::container::small_vector<SwizzleParameters, 16> FullUploadSwizzles(const ImageInfo& info) { |
| @@ -1063,7 +1061,8 @@ boost::container::small_vector<SwizzleParameters, 16> FullUploadSwizzles(const I | |||
| 1063 | for (s32 level = 0; level < num_levels; ++level) { | 1061 | for (s32 level = 0; level < num_levels; ++level) { |
| 1064 | const Extent3D level_size = AdjustMipSize(size, level); | 1062 | const Extent3D level_size = AdjustMipSize(size, level); |
| 1065 | const Extent3D num_tiles = AdjustTileSize(level_size, tile_size); | 1063 | const Extent3D num_tiles = AdjustTileSize(level_size, tile_size); |
| 1066 | const Extent3D block = AdjustMipBlockSize(num_tiles, level_info.block, level); | 1064 | const Extent3D block = |
| 1065 | AdjustMipBlockSize(num_tiles, level_info.block, level, level_info.num_levels); | ||
| 1067 | params[level] = SwizzleParameters{ | 1066 | params[level] = SwizzleParameters{ |
| 1068 | .num_tiles = num_tiles, | 1067 | .num_tiles = num_tiles, |
| 1069 | .block = block, | 1068 | .block = block, |
| @@ -1292,11 +1291,11 @@ u32 MapSizeBytes(const ImageBase& image) { | |||
| 1292 | } | 1291 | } |
| 1293 | } | 1292 | } |
| 1294 | 1293 | ||
| 1295 | static_assert(CalculateLevelSize(LevelInfo{{1920, 1080, 1}, {0, 2, 0}, {1, 1}, 2, 0}, 0) == | 1294 | static_assert(CalculateLevelSize(LevelInfo{{1920, 1080, 1}, {0, 2, 0}, {1, 1}, 2, 0, 1}, 0) == |
| 1296 | 0x7f8000); | 1295 | 0x7f8000); |
| 1297 | static_assert(CalculateLevelSize(LevelInfo{{32, 32, 1}, {0, 0, 4}, {1, 1}, 4, 0}, 0) == 0x40000); | 1296 | static_assert(CalculateLevelSize(LevelInfo{{32, 32, 1}, {0, 0, 4}, {1, 1}, 4, 0, 1}, 0) == 0x4000); |
| 1298 | 1297 | ||
| 1299 | static_assert(CalculateLevelSize(LevelInfo{{128, 8, 1}, {0, 4, 0}, {1, 1}, 4, 0}, 0) == 0x40000); | 1298 | static_assert(CalculateLevelSize(LevelInfo{{128, 8, 1}, {0, 4, 0}, {1, 1}, 4, 0, 1}, 0) == 0x4000); |
| 1300 | 1299 | ||
| 1301 | static_assert(CalculateLevelOffset(PixelFormat::R8_SINT, {1920, 1080, 1}, {0, 2, 0}, 0, 7) == | 1300 | static_assert(CalculateLevelOffset(PixelFormat::R8_SINT, {1920, 1080, 1}, {0, 2, 0}, 0, 7) == |
| 1302 | 0x2afc00); | 1301 | 0x2afc00); |
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index 82767fdf0..8dd1667f3 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp | |||
| @@ -66,9 +66,10 @@ struct Range { | |||
| 66 | switch (usage) { | 66 | switch (usage) { |
| 67 | case MemoryUsage::Upload: | 67 | case MemoryUsage::Upload: |
| 68 | case MemoryUsage::Stream: | 68 | case MemoryUsage::Stream: |
| 69 | return VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; | 69 | return VMA_ALLOCATION_CREATE_MAPPED_BIT | |
| 70 | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; | ||
| 70 | case MemoryUsage::Download: | 71 | case MemoryUsage::Download: |
| 71 | return VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT; | 72 | return VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT; |
| 72 | case MemoryUsage::DeviceLocal: | 73 | case MemoryUsage::DeviceLocal: |
| 73 | return {}; | 74 | return {}; |
| 74 | } | 75 | } |
| @@ -252,8 +253,7 @@ vk::Image MemoryAllocator::CreateImage(const VkImageCreateInfo& ci) const { | |||
| 252 | 253 | ||
| 253 | vk::Buffer MemoryAllocator::CreateBuffer(const VkBufferCreateInfo& ci, MemoryUsage usage) const { | 254 | vk::Buffer MemoryAllocator::CreateBuffer(const VkBufferCreateInfo& ci, MemoryUsage usage) const { |
| 254 | const VmaAllocationCreateInfo alloc_ci = { | 255 | const VmaAllocationCreateInfo alloc_ci = { |
| 255 | .flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT | | 256 | .flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT | MemoryUsageVmaFlags(usage), |
| 256 | MemoryUsageVmaFlags(usage), | ||
| 257 | .usage = MemoryUsageVma(usage), | 257 | .usage = MemoryUsageVma(usage), |
| 258 | .requiredFlags = 0, | 258 | .requiredFlags = 0, |
| 259 | .preferredFlags = MemoryUsagePreferedVmaFlags(usage), | 259 | .preferredFlags = MemoryUsagePreferedVmaFlags(usage), |
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp index d15559518..ca0e14fad 100644 --- a/src/yuzu/applets/qt_controller.cpp +++ b/src/yuzu/applets/qt_controller.cpp | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include "yuzu/configuration/configure_vibration.h" | 23 | #include "yuzu/configuration/configure_vibration.h" |
| 24 | #include "yuzu/configuration/input_profiles.h" | 24 | #include "yuzu/configuration/input_profiles.h" |
| 25 | #include "yuzu/main.h" | 25 | #include "yuzu/main.h" |
| 26 | #include "yuzu/util/controller_navigation.h" | ||
| 26 | 27 | ||
| 27 | namespace { | 28 | namespace { |
| 28 | 29 | ||
| @@ -132,6 +133,8 @@ QtControllerSelectorDialog::QtControllerSelectorDialog( | |||
| 132 | ui->checkboxPlayer7Connected, ui->checkboxPlayer8Connected, | 133 | ui->checkboxPlayer7Connected, ui->checkboxPlayer8Connected, |
| 133 | }; | 134 | }; |
| 134 | 135 | ||
| 136 | ui->labelError->setVisible(false); | ||
| 137 | |||
| 135 | // Setup/load everything prior to setting up connections. | 138 | // Setup/load everything prior to setting up connections. |
| 136 | // This avoids unintentionally changing the states of elements while loading them in. | 139 | // This avoids unintentionally changing the states of elements while loading them in. |
| 137 | SetSupportedControllers(); | 140 | SetSupportedControllers(); |
| @@ -143,6 +146,8 @@ QtControllerSelectorDialog::QtControllerSelectorDialog( | |||
| 143 | 146 | ||
| 144 | LoadConfiguration(); | 147 | LoadConfiguration(); |
| 145 | 148 | ||
| 149 | controller_navigation = new ControllerNavigation(system.HIDCore(), this); | ||
| 150 | |||
| 146 | for (std::size_t i = 0; i < NUM_PLAYERS; ++i) { | 151 | for (std::size_t i = 0; i < NUM_PLAYERS; ++i) { |
| 147 | SetExplainText(i); | 152 | SetExplainText(i); |
| 148 | UpdateControllerIcon(i); | 153 | UpdateControllerIcon(i); |
| @@ -151,6 +156,8 @@ QtControllerSelectorDialog::QtControllerSelectorDialog( | |||
| 151 | 156 | ||
| 152 | connect(player_groupboxes[i], &QGroupBox::toggled, [this, i](bool checked) { | 157 | connect(player_groupboxes[i], &QGroupBox::toggled, [this, i](bool checked) { |
| 153 | if (checked) { | 158 | if (checked) { |
| 159 | // Hide eventual error message about number of controllers | ||
| 160 | ui->labelError->setVisible(false); | ||
| 154 | for (std::size_t index = 0; index <= i; ++index) { | 161 | for (std::size_t index = 0; index <= i; ++index) { |
| 155 | connected_controller_checkboxes[index]->setChecked(checked); | 162 | connected_controller_checkboxes[index]->setChecked(checked); |
| 156 | } | 163 | } |
| @@ -199,6 +206,12 @@ QtControllerSelectorDialog::QtControllerSelectorDialog( | |||
| 199 | connect(ui->buttonBox, &QDialogButtonBox::accepted, this, | 206 | connect(ui->buttonBox, &QDialogButtonBox::accepted, this, |
| 200 | &QtControllerSelectorDialog::ApplyConfiguration); | 207 | &QtControllerSelectorDialog::ApplyConfiguration); |
| 201 | 208 | ||
| 209 | connect(controller_navigation, &ControllerNavigation::TriggerKeyboardEvent, | ||
| 210 | [this](Qt::Key key) { | ||
| 211 | QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier); | ||
| 212 | QCoreApplication::postEvent(this, event); | ||
| 213 | }); | ||
| 214 | |||
| 202 | // Enhancement: Check if the parameters have already been met before disconnecting controllers. | 215 | // Enhancement: Check if the parameters have already been met before disconnecting controllers. |
| 203 | // If all the parameters are met AND only allows a single player, | 216 | // If all the parameters are met AND only allows a single player, |
| 204 | // stop the constructor here as we do not need to continue. | 217 | // stop the constructor here as we do not need to continue. |
| @@ -217,6 +230,7 @@ QtControllerSelectorDialog::QtControllerSelectorDialog( | |||
| 217 | } | 230 | } |
| 218 | 231 | ||
| 219 | QtControllerSelectorDialog::~QtControllerSelectorDialog() { | 232 | QtControllerSelectorDialog::~QtControllerSelectorDialog() { |
| 233 | controller_navigation->UnloadController(); | ||
| 220 | system.HIDCore().DisableAllControllerConfiguration(); | 234 | system.HIDCore().DisableAllControllerConfiguration(); |
| 221 | } | 235 | } |
| 222 | 236 | ||
| @@ -291,6 +305,31 @@ void QtControllerSelectorDialog::CallConfigureInputProfileDialog() { | |||
| 291 | dialog.exec(); | 305 | dialog.exec(); |
| 292 | } | 306 | } |
| 293 | 307 | ||
| 308 | void QtControllerSelectorDialog::keyPressEvent(QKeyEvent* evt) { | ||
| 309 | const auto num_connected_players = static_cast<int>( | ||
| 310 | std::count_if(player_groupboxes.begin(), player_groupboxes.end(), | ||
| 311 | [](const QGroupBox* player) { return player->isChecked(); })); | ||
| 312 | |||
| 313 | const auto min_supported_players = parameters.enable_single_mode ? 1 : parameters.min_players; | ||
| 314 | const auto max_supported_players = parameters.enable_single_mode ? 1 : parameters.max_players; | ||
| 315 | |||
| 316 | if ((evt->key() == Qt::Key_Enter || evt->key() == Qt::Key_Return) && !parameters_met) { | ||
| 317 | // Display error message when trying to validate using "Enter" and "OK" button is disabled | ||
| 318 | ui->labelError->setVisible(true); | ||
| 319 | return; | ||
| 320 | } else if (evt->key() == Qt::Key_Left && num_connected_players > min_supported_players) { | ||
| 321 | // Remove a player if possible | ||
| 322 | connected_controller_checkboxes[num_connected_players - 1]->setChecked(false); | ||
| 323 | return; | ||
| 324 | } else if (evt->key() == Qt::Key_Right && num_connected_players < max_supported_players) { | ||
| 325 | // Add a player, if possible | ||
| 326 | ui->labelError->setVisible(false); | ||
| 327 | connected_controller_checkboxes[num_connected_players]->setChecked(true); | ||
| 328 | return; | ||
| 329 | } | ||
| 330 | QDialog::keyPressEvent(evt); | ||
| 331 | } | ||
| 332 | |||
| 294 | bool QtControllerSelectorDialog::CheckIfParametersMet() { | 333 | bool QtControllerSelectorDialog::CheckIfParametersMet() { |
| 295 | // Here, we check and validate the current configuration against all applicable parameters. | 334 | // Here, we check and validate the current configuration against all applicable parameters. |
| 296 | const auto num_connected_players = static_cast<int>( | 335 | const auto num_connected_players = static_cast<int>( |
diff --git a/src/yuzu/applets/qt_controller.h b/src/yuzu/applets/qt_controller.h index 2fdc35857..7f0673d06 100644 --- a/src/yuzu/applets/qt_controller.h +++ b/src/yuzu/applets/qt_controller.h | |||
| @@ -34,6 +34,8 @@ class HIDCore; | |||
| 34 | enum class NpadStyleIndex : u8; | 34 | enum class NpadStyleIndex : u8; |
| 35 | } // namespace Core::HID | 35 | } // namespace Core::HID |
| 36 | 36 | ||
| 37 | class ControllerNavigation; | ||
| 38 | |||
| 37 | class QtControllerSelectorDialog final : public QDialog { | 39 | class QtControllerSelectorDialog final : public QDialog { |
| 38 | Q_OBJECT | 40 | Q_OBJECT |
| 39 | 41 | ||
| @@ -46,6 +48,8 @@ public: | |||
| 46 | 48 | ||
| 47 | int exec() override; | 49 | int exec() override; |
| 48 | 50 | ||
| 51 | void keyPressEvent(QKeyEvent* evt) override; | ||
| 52 | |||
| 49 | private: | 53 | private: |
| 50 | // Applies the current configuration. | 54 | // Applies the current configuration. |
| 51 | void ApplyConfiguration(); | 55 | void ApplyConfiguration(); |
| @@ -110,6 +114,8 @@ private: | |||
| 110 | 114 | ||
| 111 | Core::System& system; | 115 | Core::System& system; |
| 112 | 116 | ||
| 117 | ControllerNavigation* controller_navigation = nullptr; | ||
| 118 | |||
| 113 | // This is true if and only if all parameters are met. Otherwise, this is false. | 119 | // This is true if and only if all parameters are met. Otherwise, this is false. |
| 114 | // This determines whether the "OK" button can be clicked to exit the applet. | 120 | // This determines whether the "OK" button can be clicked to exit the applet. |
| 115 | bool parameters_met{false}; | 121 | bool parameters_met{false}; |
diff --git a/src/yuzu/applets/qt_controller.ui b/src/yuzu/applets/qt_controller.ui index 729e921ee..6f7cb3c13 100644 --- a/src/yuzu/applets/qt_controller.ui +++ b/src/yuzu/applets/qt_controller.ui | |||
| @@ -2624,13 +2624,53 @@ | |||
| 2624 | </spacer> | 2624 | </spacer> |
| 2625 | </item> | 2625 | </item> |
| 2626 | <item alignment="Qt::AlignBottom"> | 2626 | <item alignment="Qt::AlignBottom"> |
| 2627 | <widget class="QDialogButtonBox" name="buttonBox"> | 2627 | <widget class="QWidget" name="closeButtons" native="true"> |
| 2628 | <property name="enabled"> | 2628 | <layout class="QVBoxLayout" name="verticalLayout_46"> |
| 2629 | <bool>true</bool> | 2629 | <property name="spacing"> |
| 2630 | </property> | 2630 | <number>7</number> |
| 2631 | <property name="standardButtons"> | 2631 | </property> |
| 2632 | <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> | 2632 | <property name="leftMargin"> |
| 2633 | </property> | 2633 | <number>0</number> |
| 2634 | </property> | ||
| 2635 | <property name="topMargin"> | ||
| 2636 | <number>0</number> | ||
| 2637 | </property> | ||
| 2638 | <property name="rightMargin"> | ||
| 2639 | <number>0</number> | ||
| 2640 | </property> | ||
| 2641 | <property name="bottomMargin"> | ||
| 2642 | <number>0</number> | ||
| 2643 | </property> | ||
| 2644 | <item> | ||
| 2645 | <widget class="QLabel" name="labelError"> | ||
| 2646 | <property name="enabled"> | ||
| 2647 | <bool>true</bool> | ||
| 2648 | </property> | ||
| 2649 | <property name="styleSheet"> | ||
| 2650 | <string notr="true">QLabel { color : red; }</string> | ||
| 2651 | </property> | ||
| 2652 | <property name="text"> | ||
| 2653 | <string>Not enough controllers</string> | ||
| 2654 | </property> | ||
| 2655 | <property name="alignment"> | ||
| 2656 | <set>Qt::AlignCenter</set> | ||
| 2657 | </property> | ||
| 2658 | <property name="margin"> | ||
| 2659 | <number>0</number> | ||
| 2660 | </property> | ||
| 2661 | </widget> | ||
| 2662 | </item> | ||
| 2663 | <item> | ||
| 2664 | <widget class="QDialogButtonBox" name="buttonBox"> | ||
| 2665 | <property name="enabled"> | ||
| 2666 | <bool>true</bool> | ||
| 2667 | </property> | ||
| 2668 | <property name="standardButtons"> | ||
| 2669 | <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> | ||
| 2670 | </property> | ||
| 2671 | </widget> | ||
| 2672 | </item> | ||
| 2673 | </layout> | ||
| 2634 | </widget> | 2674 | </widget> |
| 2635 | </item> | 2675 | </item> |
| 2636 | </layout> | 2676 | </layout> |