diff options
| -rw-r--r-- | externals/nx_tzdb/CMakeLists.txt | 4 | ||||
| m--------- | externals/nx_tzdb/tzdb_to_nx | 0 | ||||
| -rw-r--r-- | src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt | 172 | ||||
| -rw-r--r-- | src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt | 2 | ||||
| -rw-r--r-- | src/android/app/src/main/jni/native.cpp | 20 | ||||
| -rw-r--r-- | src/core/hle/service/time/time_zone_manager.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/memory_manager.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 22 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 10 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.h | 23 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_graphics.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/vk_device_info.cpp | 13 | ||||
| -rw-r--r-- | src/yuzu/vk_device_info.h | 4 |
15 files changed, 184 insertions, 106 deletions
diff --git a/externals/nx_tzdb/CMakeLists.txt b/externals/nx_tzdb/CMakeLists.txt index d5a1c6317..593786250 100644 --- a/externals/nx_tzdb/CMakeLists.txt +++ b/externals/nx_tzdb/CMakeLists.txt | |||
| @@ -7,7 +7,7 @@ add_library(nx_tzdb INTERFACE) | |||
| 7 | 7 | ||
| 8 | find_program(GIT git) | 8 | find_program(GIT git) |
| 9 | find_program(GNU_MAKE make) | 9 | find_program(GNU_MAKE make) |
| 10 | find_program(GNU_DATE date) | 10 | find_program(DATE_PROG date) |
| 11 | 11 | ||
| 12 | set(CAN_BUILD_NX_TZDB true) | 12 | set(CAN_BUILD_NX_TZDB true) |
| 13 | 13 | ||
| @@ -17,7 +17,7 @@ endif() | |||
| 17 | if (NOT GNU_MAKE) | 17 | if (NOT GNU_MAKE) |
| 18 | set(CAN_BUILD_NX_TZDB false) | 18 | set(CAN_BUILD_NX_TZDB false) |
| 19 | endif() | 19 | endif() |
| 20 | if (NOT GNU_DATE) | 20 | if (NOT DATE_PROG) |
| 21 | set(CAN_BUILD_NX_TZDB false) | 21 | set(CAN_BUILD_NX_TZDB false) |
| 22 | endif() | 22 | endif() |
| 23 | if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR ANDROID) | 23 | if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR ANDROID) |
diff --git a/externals/nx_tzdb/tzdb_to_nx b/externals/nx_tzdb/tzdb_to_nx | |||
| Subproject 34df65eff295c2bd9ee9e6a077d662486d5cabb | Subproject 8c272f21d19c6e821345fd055f41b9640f9189d | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt index 6f8adbba5..5a36ffad4 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt | |||
| @@ -68,79 +68,109 @@ class HomeSettingsFragment : Fragment() { | |||
| 68 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | 68 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
| 69 | mainActivity = requireActivity() as MainActivity | 69 | mainActivity = requireActivity() as MainActivity |
| 70 | 70 | ||
| 71 | val optionsList: MutableList<HomeSetting> = mutableListOf( | 71 | val optionsList: MutableList<HomeSetting> = mutableListOf<HomeSetting>().apply { |
| 72 | HomeSetting( | 72 | add( |
| 73 | R.string.advanced_settings, | 73 | HomeSetting( |
| 74 | R.string.settings_description, | 74 | R.string.advanced_settings, |
| 75 | R.drawable.ic_settings | 75 | R.string.settings_description, |
| 76 | ) { SettingsActivity.launch(requireContext(), SettingsFile.FILE_NAME_CONFIG, "") }, | 76 | R.drawable.ic_settings |
| 77 | HomeSetting( | 77 | ) { SettingsActivity.launch(requireContext(), SettingsFile.FILE_NAME_CONFIG, "") } |
| 78 | R.string.open_user_folder, | 78 | ) |
| 79 | R.string.open_user_folder_description, | 79 | add( |
| 80 | R.drawable.ic_folder_open | 80 | HomeSetting( |
| 81 | ) { openFileManager() }, | 81 | R.string.open_user_folder, |
| 82 | HomeSetting( | 82 | R.string.open_user_folder_description, |
| 83 | R.string.preferences_theme, | 83 | R.drawable.ic_folder_open |
| 84 | R.string.theme_and_color_description, | 84 | ) { openFileManager() } |
| 85 | R.drawable.ic_palette | 85 | ) |
| 86 | ) { SettingsActivity.launch(requireContext(), Settings.SECTION_THEME, "") }, | 86 | add( |
| 87 | HomeSetting( | 87 | HomeSetting( |
| 88 | R.string.install_gpu_driver, | 88 | R.string.preferences_theme, |
| 89 | R.string.install_gpu_driver_description, | 89 | R.string.theme_and_color_description, |
| 90 | R.drawable.ic_exit | 90 | R.drawable.ic_palette |
| 91 | ) { driverInstaller() }, | 91 | ) { SettingsActivity.launch(requireContext(), Settings.SECTION_THEME, "") } |
| 92 | HomeSetting( | 92 | ) |
| 93 | R.string.install_amiibo_keys, | 93 | |
| 94 | R.string.install_amiibo_keys_description, | 94 | if (GpuDriverHelper.supportsCustomDriverLoading()) { |
| 95 | R.drawable.ic_nfc | 95 | add( |
| 96 | ) { mainActivity.getAmiiboKey.launch(arrayOf("*/*")) }, | 96 | HomeSetting( |
| 97 | HomeSetting( | 97 | R.string.install_gpu_driver, |
| 98 | R.string.install_game_content, | 98 | R.string.install_gpu_driver_description, |
| 99 | R.string.install_game_content_description, | 99 | R.drawable.ic_exit |
| 100 | R.drawable.ic_system_update_alt | 100 | ) { driverInstaller() } |
| 101 | ) { mainActivity.installGameUpdate.launch(arrayOf("*/*")) }, | ||
| 102 | HomeSetting( | ||
| 103 | R.string.select_games_folder, | ||
| 104 | R.string.select_games_folder_description, | ||
| 105 | R.drawable.ic_add | ||
| 106 | ) { | ||
| 107 | mainActivity.getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data) | ||
| 108 | }, | ||
| 109 | HomeSetting( | ||
| 110 | R.string.manage_save_data, | ||
| 111 | R.string.import_export_saves_description, | ||
| 112 | R.drawable.ic_save | ||
| 113 | ) { | ||
| 114 | ImportExportSavesFragment().show( | ||
| 115 | parentFragmentManager, | ||
| 116 | ImportExportSavesFragment.TAG | ||
| 117 | ) | 101 | ) |
| 118 | }, | ||
| 119 | HomeSetting( | ||
| 120 | R.string.install_prod_keys, | ||
| 121 | R.string.install_prod_keys_description, | ||
| 122 | R.drawable.ic_unlock | ||
| 123 | ) { mainActivity.getProdKey.launch(arrayOf("*/*")) }, | ||
| 124 | HomeSetting( | ||
| 125 | R.string.install_firmware, | ||
| 126 | R.string.install_firmware_description, | ||
| 127 | R.drawable.ic_firmware | ||
| 128 | ) { mainActivity.getFirmware.launch(arrayOf("application/zip")) }, | ||
| 129 | HomeSetting( | ||
| 130 | R.string.share_log, | ||
| 131 | R.string.share_log_description, | ||
| 132 | R.drawable.ic_log | ||
| 133 | ) { shareLog() }, | ||
| 134 | HomeSetting( | ||
| 135 | R.string.about, | ||
| 136 | R.string.about_description, | ||
| 137 | R.drawable.ic_info_outline | ||
| 138 | ) { | ||
| 139 | exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true) | ||
| 140 | parentFragmentManager.primaryNavigationFragment?.findNavController() | ||
| 141 | ?.navigate(R.id.action_homeSettingsFragment_to_aboutFragment) | ||
| 142 | } | 102 | } |
| 143 | ) | 103 | |
| 104 | add( | ||
| 105 | HomeSetting( | ||
| 106 | R.string.install_amiibo_keys, | ||
| 107 | R.string.install_amiibo_keys_description, | ||
| 108 | R.drawable.ic_nfc | ||
| 109 | ) { mainActivity.getAmiiboKey.launch(arrayOf("*/*")) } | ||
| 110 | ) | ||
| 111 | add( | ||
| 112 | HomeSetting( | ||
| 113 | R.string.install_game_content, | ||
| 114 | R.string.install_game_content_description, | ||
| 115 | R.drawable.ic_system_update_alt | ||
| 116 | ) { mainActivity.installGameUpdate.launch(arrayOf("*/*")) } | ||
| 117 | ) | ||
| 118 | add( | ||
| 119 | HomeSetting( | ||
| 120 | R.string.select_games_folder, | ||
| 121 | R.string.select_games_folder_description, | ||
| 122 | R.drawable.ic_add | ||
| 123 | ) { | ||
| 124 | mainActivity.getGamesDirectory.launch( | ||
| 125 | Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data | ||
| 126 | ) | ||
| 127 | } | ||
| 128 | ) | ||
| 129 | add( | ||
| 130 | HomeSetting( | ||
| 131 | R.string.manage_save_data, | ||
| 132 | R.string.import_export_saves_description, | ||
| 133 | R.drawable.ic_save | ||
| 134 | ) { | ||
| 135 | ImportExportSavesFragment().show( | ||
| 136 | parentFragmentManager, | ||
| 137 | ImportExportSavesFragment.TAG | ||
| 138 | ) | ||
| 139 | } | ||
| 140 | ) | ||
| 141 | add( | ||
| 142 | HomeSetting( | ||
| 143 | R.string.install_prod_keys, | ||
| 144 | R.string.install_prod_keys_description, | ||
| 145 | R.drawable.ic_unlock | ||
| 146 | ) { mainActivity.getProdKey.launch(arrayOf("*/*")) } | ||
| 147 | ) | ||
| 148 | add( | ||
| 149 | HomeSetting( | ||
| 150 | R.string.install_firmware, | ||
| 151 | R.string.install_firmware_description, | ||
| 152 | R.drawable.ic_firmware | ||
| 153 | ) { mainActivity.getFirmware.launch(arrayOf("application/zip")) } | ||
| 154 | ) | ||
| 155 | add( | ||
| 156 | HomeSetting( | ||
| 157 | R.string.share_log, | ||
| 158 | R.string.share_log_description, | ||
| 159 | R.drawable.ic_log | ||
| 160 | ) { shareLog() } | ||
| 161 | ) | ||
| 162 | add( | ||
| 163 | HomeSetting( | ||
| 164 | R.string.about, | ||
| 165 | R.string.about_description, | ||
| 166 | R.drawable.ic_info_outline | ||
| 167 | ) { | ||
| 168 | exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true) | ||
| 169 | parentFragmentManager.primaryNavigationFragment?.findNavController() | ||
| 170 | ?.navigate(R.id.action_homeSettingsFragment_to_aboutFragment) | ||
| 171 | } | ||
| 172 | ) | ||
| 173 | } | ||
| 144 | 174 | ||
| 145 | if (!BuildConfig.PREMIUM) { | 175 | if (!BuildConfig.PREMIUM) { |
| 146 | optionsList.add( | 176 | optionsList.add( |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt index dad159481..1d4695a2a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt | |||
| @@ -113,6 +113,8 @@ object GpuDriverHelper { | |||
| 113 | initializeDriverParameters(context) | 113 | initializeDriverParameters(context) |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | external fun supportsCustomDriverLoading(): Boolean | ||
| 117 | |||
| 116 | // Parse the custom driver metadata to retrieve the name. | 118 | // Parse the custom driver metadata to retrieve the name. |
| 117 | val customDriverName: String? | 119 | val customDriverName: String? |
| 118 | get() { | 120 | get() { |
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index f9617202b..632aa50b3 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp | |||
| @@ -560,6 +560,26 @@ void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeGpuDriver( | |||
| 560 | GetJString(env, custom_driver_name), GetJString(env, file_redirect_dir)); | 560 | GetJString(env, custom_driver_name), GetJString(env, file_redirect_dir)); |
| 561 | } | 561 | } |
| 562 | 562 | ||
| 563 | [[maybe_unused]] static bool CheckKgslPresent() { | ||
| 564 | constexpr auto KgslPath{"/dev/kgsl-3d0"}; | ||
| 565 | |||
| 566 | return access(KgslPath, F_OK) == 0; | ||
| 567 | } | ||
| 568 | |||
| 569 | [[maybe_unused]] bool SupportsCustomDriver() { | ||
| 570 | return android_get_device_api_level() >= 28 && CheckKgslPresent(); | ||
| 571 | } | ||
| 572 | |||
| 573 | jboolean JNICALL Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_supportsCustomDriverLoading( | ||
| 574 | [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject instance) { | ||
| 575 | #ifdef ARCHITECTURE_arm64 | ||
| 576 | // If the KGSL device exists custom drivers can be loaded using adrenotools | ||
| 577 | return SupportsCustomDriver(); | ||
| 578 | #else | ||
| 579 | return false; | ||
| 580 | #endif | ||
| 581 | } | ||
| 582 | |||
| 563 | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadKeys(JNIEnv* env, | 583 | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadKeys(JNIEnv* env, |
| 564 | [[maybe_unused]] jclass clazz) { | 584 | [[maybe_unused]] jclass clazz) { |
| 565 | Core::Crypto::KeyManager::Instance().ReloadKeys(); | 585 | Core::Crypto::KeyManager::Instance().ReloadKeys(); |
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp index 63aacd19f..205371a26 100644 --- a/src/core/hle/service/time/time_zone_manager.cpp +++ b/src/core/hle/service/time/time_zone_manager.cpp | |||
| @@ -911,9 +911,13 @@ static Result ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, | |||
| 911 | 911 | ||
| 912 | calendar_additional_info.is_dst = rules.ttis[tti_index].is_dst; | 912 | calendar_additional_info.is_dst = rules.ttis[tti_index].is_dst; |
| 913 | const char* time_zone{&rules.chars[rules.ttis[tti_index].abbreviation_list_index]}; | 913 | const char* time_zone{&rules.chars[rules.ttis[tti_index].abbreviation_list_index]}; |
| 914 | for (int index{}; time_zone[index] != '\0'; ++index) { | 914 | u32 index; |
| 915 | for (index = 0; time_zone[index] != '\0' && time_zone[index] != ',' && | ||
| 916 | index < calendar_additional_info.timezone_name.size() - 1; | ||
| 917 | ++index) { | ||
| 915 | calendar_additional_info.timezone_name[index] = time_zone[index]; | 918 | calendar_additional_info.timezone_name[index] = time_zone[index]; |
| 916 | } | 919 | } |
| 920 | calendar_additional_info.timezone_name[index] = '\0'; | ||
| 917 | return ResultSuccess; | 921 | return ResultSuccess; |
| 918 | } | 922 | } |
| 919 | 923 | ||
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 7b2cde7a7..b2f7e160a 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -111,7 +111,7 @@ GPUVAddr MemoryManager::PageTableOp(GPUVAddr gpu_addr, [[maybe_unused]] VAddr cp | |||
| 111 | [[maybe_unused]] const auto current_entry_type = GetEntry<false>(current_gpu_addr); | 111 | [[maybe_unused]] const auto current_entry_type = GetEntry<false>(current_gpu_addr); |
| 112 | SetEntry<false>(current_gpu_addr, entry_type); | 112 | SetEntry<false>(current_gpu_addr, entry_type); |
| 113 | if (current_entry_type != entry_type) { | 113 | if (current_entry_type != entry_type) { |
| 114 | rasterizer->ModifyGPUMemory(unique_identifier, gpu_addr, page_size); | 114 | rasterizer->ModifyGPUMemory(unique_identifier, current_gpu_addr, page_size); |
| 115 | } | 115 | } |
| 116 | if constexpr (entry_type == EntryType::Mapped) { | 116 | if constexpr (entry_type == EntryType::Mapped) { |
| 117 | const VAddr current_cpu_addr = cpu_addr + offset; | 117 | const VAddr current_cpu_addr = cpu_addr + offset; |
| @@ -134,7 +134,7 @@ GPUVAddr MemoryManager::BigPageTableOp(GPUVAddr gpu_addr, [[maybe_unused]] VAddr | |||
| 134 | [[maybe_unused]] const auto current_entry_type = GetEntry<true>(current_gpu_addr); | 134 | [[maybe_unused]] const auto current_entry_type = GetEntry<true>(current_gpu_addr); |
| 135 | SetEntry<true>(current_gpu_addr, entry_type); | 135 | SetEntry<true>(current_gpu_addr, entry_type); |
| 136 | if (current_entry_type != entry_type) { | 136 | if (current_entry_type != entry_type) { |
| 137 | rasterizer->ModifyGPUMemory(unique_identifier, gpu_addr, big_page_size); | 137 | rasterizer->ModifyGPUMemory(unique_identifier, current_gpu_addr, big_page_size); |
| 138 | } | 138 | } |
| 139 | if constexpr (entry_type == EntryType::Mapped) { | 139 | if constexpr (entry_type == EntryType::Mapped) { |
| 140 | const VAddr current_cpu_addr = cpu_addr + offset; | 140 | const VAddr current_cpu_addr = cpu_addr + offset; |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 18e040a1b..a2cfb2105 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -705,10 +705,7 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline( | |||
| 705 | std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline( | 705 | std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline( |
| 706 | ShaderPools& pools, const ComputePipelineCacheKey& key, Shader::Environment& env, | 706 | ShaderPools& pools, const ComputePipelineCacheKey& key, Shader::Environment& env, |
| 707 | PipelineStatistics* statistics, bool build_in_parallel) try { | 707 | PipelineStatistics* statistics, bool build_in_parallel) try { |
| 708 | // TODO: Remove this when Intel fixes their shader compiler. | 708 | if (device.HasBrokenCompute()) { |
| 709 | // https://github.com/IGCIT/Intel-GPU-Community-Issue-Tracker-IGCIT/issues/159 | ||
| 710 | if (device.GetDriverID() == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS && | ||
| 711 | !Settings::values.enable_compute_pipelines.GetValue()) { | ||
| 712 | LOG_ERROR(Render_Vulkan, "Skipping 0x{:016x}", key.Hash()); | 709 | LOG_ERROR(Render_Vulkan, "Skipping 0x{:016x}", key.Hash()); |
| 713 | return nullptr; | 710 | return nullptr; |
| 714 | } | 711 | } |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 4027d860b..d25339c8c 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -300,7 +300,7 @@ void TextureCache<P>::SynchronizeComputeDescriptors() { | |||
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | template <class P> | 302 | template <class P> |
| 303 | bool TextureCache<P>::RescaleRenderTargets(bool is_clear) { | 303 | bool TextureCache<P>::RescaleRenderTargets() { |
| 304 | auto& flags = maxwell3d->dirty.flags; | 304 | auto& flags = maxwell3d->dirty.flags; |
| 305 | u32 scale_rating = 0; | 305 | u32 scale_rating = 0; |
| 306 | bool rescaled = false; | 306 | bool rescaled = false; |
| @@ -338,13 +338,13 @@ bool TextureCache<P>::RescaleRenderTargets(bool is_clear) { | |||
| 338 | ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index]; | 338 | ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index]; |
| 339 | if (flags[Dirty::ColorBuffer0 + index] || force) { | 339 | if (flags[Dirty::ColorBuffer0 + index] || force) { |
| 340 | flags[Dirty::ColorBuffer0 + index] = false; | 340 | flags[Dirty::ColorBuffer0 + index] = false; |
| 341 | BindRenderTarget(&color_buffer_id, FindColorBuffer(index, is_clear)); | 341 | BindRenderTarget(&color_buffer_id, FindColorBuffer(index)); |
| 342 | } | 342 | } |
| 343 | check_rescale(color_buffer_id, tmp_color_images[index]); | 343 | check_rescale(color_buffer_id, tmp_color_images[index]); |
| 344 | } | 344 | } |
| 345 | if (flags[Dirty::ZetaBuffer] || force) { | 345 | if (flags[Dirty::ZetaBuffer] || force) { |
| 346 | flags[Dirty::ZetaBuffer] = false; | 346 | flags[Dirty::ZetaBuffer] = false; |
| 347 | BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear)); | 347 | BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer()); |
| 348 | } | 348 | } |
| 349 | check_rescale(render_targets.depth_buffer_id, tmp_depth_image); | 349 | check_rescale(render_targets.depth_buffer_id, tmp_depth_image); |
| 350 | 350 | ||
| @@ -409,7 +409,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) { | |||
| 409 | return; | 409 | return; |
| 410 | } | 410 | } |
| 411 | 411 | ||
| 412 | const bool rescaled = RescaleRenderTargets(is_clear); | 412 | const bool rescaled = RescaleRenderTargets(); |
| 413 | if (is_rescaling != rescaled) { | 413 | if (is_rescaling != rescaled) { |
| 414 | flags[Dirty::RescaleViewports] = true; | 414 | flags[Dirty::RescaleViewports] = true; |
| 415 | flags[Dirty::RescaleScissors] = true; | 415 | flags[Dirty::RescaleScissors] = true; |
| @@ -1678,7 +1678,7 @@ SamplerId TextureCache<P>::FindSampler(const TSCEntry& config) { | |||
| 1678 | } | 1678 | } |
| 1679 | 1679 | ||
| 1680 | template <class P> | 1680 | template <class P> |
| 1681 | ImageViewId TextureCache<P>::FindColorBuffer(size_t index, bool is_clear) { | 1681 | ImageViewId TextureCache<P>::FindColorBuffer(size_t index) { |
| 1682 | const auto& regs = maxwell3d->regs; | 1682 | const auto& regs = maxwell3d->regs; |
| 1683 | if (index >= regs.rt_control.count) { | 1683 | if (index >= regs.rt_control.count) { |
| 1684 | return ImageViewId{}; | 1684 | return ImageViewId{}; |
| @@ -1692,11 +1692,11 @@ ImageViewId TextureCache<P>::FindColorBuffer(size_t index, bool is_clear) { | |||
| 1692 | return ImageViewId{}; | 1692 | return ImageViewId{}; |
| 1693 | } | 1693 | } |
| 1694 | const ImageInfo info(regs.rt[index], regs.anti_alias_samples_mode); | 1694 | const ImageInfo info(regs.rt[index], regs.anti_alias_samples_mode); |
| 1695 | return FindRenderTargetView(info, gpu_addr, is_clear); | 1695 | return FindRenderTargetView(info, gpu_addr); |
| 1696 | } | 1696 | } |
| 1697 | 1697 | ||
| 1698 | template <class P> | 1698 | template <class P> |
| 1699 | ImageViewId TextureCache<P>::FindDepthBuffer(bool is_clear) { | 1699 | ImageViewId TextureCache<P>::FindDepthBuffer() { |
| 1700 | const auto& regs = maxwell3d->regs; | 1700 | const auto& regs = maxwell3d->regs; |
| 1701 | if (!regs.zeta_enable) { | 1701 | if (!regs.zeta_enable) { |
| 1702 | return ImageViewId{}; | 1702 | return ImageViewId{}; |
| @@ -1706,18 +1706,16 @@ ImageViewId TextureCache<P>::FindDepthBuffer(bool is_clear) { | |||
| 1706 | return ImageViewId{}; | 1706 | return ImageViewId{}; |
| 1707 | } | 1707 | } |
| 1708 | const ImageInfo info(regs.zeta, regs.zeta_size, regs.anti_alias_samples_mode); | 1708 | const ImageInfo info(regs.zeta, regs.zeta_size, regs.anti_alias_samples_mode); |
| 1709 | return FindRenderTargetView(info, gpu_addr, is_clear); | 1709 | return FindRenderTargetView(info, gpu_addr); |
| 1710 | } | 1710 | } |
| 1711 | 1711 | ||
| 1712 | template <class P> | 1712 | template <class P> |
| 1713 | ImageViewId TextureCache<P>::FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr, | 1713 | ImageViewId TextureCache<P>::FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr) { |
| 1714 | bool is_clear) { | ||
| 1715 | const auto options = is_clear ? RelaxedOptions::Samples : RelaxedOptions{}; | ||
| 1716 | ImageId image_id{}; | 1714 | ImageId image_id{}; |
| 1717 | bool delete_state = has_deleted_images; | 1715 | bool delete_state = has_deleted_images; |
| 1718 | do { | 1716 | do { |
| 1719 | has_deleted_images = false; | 1717 | has_deleted_images = false; |
| 1720 | image_id = FindOrInsertImage(info, gpu_addr, options); | 1718 | image_id = FindOrInsertImage(info, gpu_addr); |
| 1721 | delete_state |= has_deleted_images; | 1719 | delete_state |= has_deleted_images; |
| 1722 | } while (has_deleted_images); | 1720 | } while (has_deleted_images); |
| 1723 | has_deleted_images = delete_state; | 1721 | has_deleted_images = delete_state; |
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index d96ddea9d..44232b961 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h | |||
| @@ -178,9 +178,8 @@ public: | |||
| 178 | void SynchronizeComputeDescriptors(); | 178 | void SynchronizeComputeDescriptors(); |
| 179 | 179 | ||
| 180 | /// Updates the Render Targets if they can be rescaled | 180 | /// Updates the Render Targets if they can be rescaled |
| 181 | /// @param is_clear True when the render targets are being used for clears | ||
| 182 | /// @retval True if the Render Targets have been rescaled. | 181 | /// @retval True if the Render Targets have been rescaled. |
| 183 | bool RescaleRenderTargets(bool is_clear); | 182 | bool RescaleRenderTargets(); |
| 184 | 183 | ||
| 185 | /// Update bound render targets and upload memory if necessary | 184 | /// Update bound render targets and upload memory if necessary |
| 186 | /// @param is_clear True when the render targets are being used for clears | 185 | /// @param is_clear True when the render targets are being used for clears |
| @@ -336,14 +335,13 @@ private: | |||
| 336 | [[nodiscard]] SamplerId FindSampler(const TSCEntry& config); | 335 | [[nodiscard]] SamplerId FindSampler(const TSCEntry& config); |
| 337 | 336 | ||
| 338 | /// Find or create an image view for the given color buffer index | 337 | /// Find or create an image view for the given color buffer index |
| 339 | [[nodiscard]] ImageViewId FindColorBuffer(size_t index, bool is_clear); | 338 | [[nodiscard]] ImageViewId FindColorBuffer(size_t index); |
| 340 | 339 | ||
| 341 | /// Find or create an image view for the depth buffer | 340 | /// Find or create an image view for the depth buffer |
| 342 | [[nodiscard]] ImageViewId FindDepthBuffer(bool is_clear); | 341 | [[nodiscard]] ImageViewId FindDepthBuffer(); |
| 343 | 342 | ||
| 344 | /// Find or create a view for a render target with the given image parameters | 343 | /// Find or create a view for a render target with the given image parameters |
| 345 | [[nodiscard]] ImageViewId FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr, | 344 | [[nodiscard]] ImageViewId FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr); |
| 346 | bool is_clear); | ||
| 347 | 345 | ||
| 348 | /// Iterates over all the images in a region calling func | 346 | /// Iterates over all the images in a region calling func |
| 349 | template <typename Func> | 347 | template <typename Func> |
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index dcedf4425..fa9cde75b 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -562,6 +562,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 562 | LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits"); | 562 | LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits"); |
| 563 | cant_blit_msaa = true; | 563 | cant_blit_msaa = true; |
| 564 | } | 564 | } |
| 565 | has_broken_compute = | ||
| 566 | CheckBrokenCompute(properties.driver.driverID, properties.properties.driverVersion) && | ||
| 567 | !Settings::values.enable_compute_pipelines.GetValue(); | ||
| 565 | if (is_intel_anv || (is_qualcomm && !is_s8gen2)) { | 568 | if (is_intel_anv || (is_qualcomm && !is_s8gen2)) { |
| 566 | LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format"); | 569 | LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format"); |
| 567 | must_emulate_bgr565 = true; | 570 | must_emulate_bgr565 = true; |
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 8c7e44fcb..0b634a876 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <vector> | 10 | #include <vector> |
| 11 | 11 | ||
| 12 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 13 | #include "common/logging/log.h" | ||
| 13 | #include "common/settings.h" | 14 | #include "common/settings.h" |
| 14 | #include "video_core/vulkan_common/vulkan_wrapper.h" | 15 | #include "video_core/vulkan_common/vulkan_wrapper.h" |
| 15 | 16 | ||
| @@ -518,6 +519,11 @@ public: | |||
| 518 | return has_renderdoc || has_nsight_graphics || Settings::values.renderer_debug.GetValue(); | 519 | return has_renderdoc || has_nsight_graphics || Settings::values.renderer_debug.GetValue(); |
| 519 | } | 520 | } |
| 520 | 521 | ||
| 522 | /// @returns True if compute pipelines can cause crashing. | ||
| 523 | bool HasBrokenCompute() const { | ||
| 524 | return has_broken_compute; | ||
| 525 | } | ||
| 526 | |||
| 521 | /// Returns true when the device does not properly support cube compatibility. | 527 | /// Returns true when the device does not properly support cube compatibility. |
| 522 | bool HasBrokenCubeImageCompability() const { | 528 | bool HasBrokenCubeImageCompability() const { |
| 523 | return has_broken_cube_compatibility; | 529 | return has_broken_cube_compatibility; |
| @@ -579,6 +585,22 @@ public: | |||
| 579 | return supports_conditional_barriers; | 585 | return supports_conditional_barriers; |
| 580 | } | 586 | } |
| 581 | 587 | ||
| 588 | [[nodiscard]] static constexpr bool CheckBrokenCompute(VkDriverId driver_id, | ||
| 589 | u32 driver_version) { | ||
| 590 | if (driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { | ||
| 591 | const u32 major = VK_API_VERSION_MAJOR(driver_version); | ||
| 592 | const u32 minor = VK_API_VERSION_MINOR(driver_version); | ||
| 593 | const u32 patch = VK_API_VERSION_PATCH(driver_version); | ||
| 594 | if (major == 0 && minor == 405 && patch < 286) { | ||
| 595 | LOG_WARNING( | ||
| 596 | Render_Vulkan, | ||
| 597 | "Intel proprietary drivers 0.405.0 until 0.405.286 have broken compute"); | ||
| 598 | return true; | ||
| 599 | } | ||
| 600 | } | ||
| 601 | return false; | ||
| 602 | } | ||
| 603 | |||
| 582 | private: | 604 | private: |
| 583 | /// Checks if the physical device is suitable and configures the object state | 605 | /// Checks if the physical device is suitable and configures the object state |
| 584 | /// with all necessary info about its properties. | 606 | /// with all necessary info about its properties. |
| @@ -672,6 +694,7 @@ private: | |||
| 672 | bool is_integrated{}; ///< Is GPU an iGPU. | 694 | bool is_integrated{}; ///< Is GPU an iGPU. |
| 673 | bool is_virtual{}; ///< Is GPU a virtual GPU. | 695 | bool is_virtual{}; ///< Is GPU a virtual GPU. |
| 674 | bool is_non_gpu{}; ///< Is SoftwareRasterizer, FPGA, non-GPU device. | 696 | bool is_non_gpu{}; ///< Is SoftwareRasterizer, FPGA, non-GPU device. |
| 697 | bool has_broken_compute{}; ///< Compute shaders can cause crashes | ||
| 675 | bool has_broken_cube_compatibility{}; ///< Has broken cube compatibility bit | 698 | bool has_broken_cube_compatibility{}; ///< Has broken cube compatibility bit |
| 676 | bool has_renderdoc{}; ///< Has RenderDoc attached | 699 | bool has_renderdoc{}; ///< Has RenderDoc attached |
| 677 | bool has_nsight_graphics{}; ///< Has Nsight Graphics attached | 700 | bool has_nsight_graphics{}; ///< Has Nsight Graphics attached |
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 78b487494..a4965524a 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp | |||
| @@ -508,7 +508,7 @@ void ConfigureGraphics::RetrieveVulkanDevices() { | |||
| 508 | vulkan_devices.push_back(QString::fromStdString(record.name)); | 508 | vulkan_devices.push_back(QString::fromStdString(record.name)); |
| 509 | device_present_modes.push_back(record.vsync_support); | 509 | device_present_modes.push_back(record.vsync_support); |
| 510 | 510 | ||
| 511 | if (record.is_intel_proprietary) { | 511 | if (record.has_broken_compute) { |
| 512 | expose_compute_option(); | 512 | expose_compute_option(); |
| 513 | } | 513 | } |
| 514 | } | 514 | } |
diff --git a/src/yuzu/vk_device_info.cpp b/src/yuzu/vk_device_info.cpp index 9bd1ec686..7c26a3dc7 100644 --- a/src/yuzu/vk_device_info.cpp +++ b/src/yuzu/vk_device_info.cpp | |||
| @@ -5,10 +5,12 @@ | |||
| 5 | #include <vector> | 5 | #include <vector> |
| 6 | #include "common/dynamic_library.h" | 6 | #include "common/dynamic_library.h" |
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "video_core/vulkan_common/vulkan_device.h" | ||
| 8 | #include "video_core/vulkan_common/vulkan_instance.h" | 9 | #include "video_core/vulkan_common/vulkan_instance.h" |
| 9 | #include "video_core/vulkan_common/vulkan_library.h" | 10 | #include "video_core/vulkan_common/vulkan_library.h" |
| 10 | #include "video_core/vulkan_common/vulkan_surface.h" | 11 | #include "video_core/vulkan_common/vulkan_surface.h" |
| 11 | #include "video_core/vulkan_common/vulkan_wrapper.h" | 12 | #include "video_core/vulkan_common/vulkan_wrapper.h" |
| 13 | #include "vulkan/vulkan_core.h" | ||
| 12 | #include "yuzu/qt_common.h" | 14 | #include "yuzu/qt_common.h" |
| 13 | #include "yuzu/vk_device_info.h" | 15 | #include "yuzu/vk_device_info.h" |
| 14 | 16 | ||
| @@ -16,8 +18,8 @@ class QWindow; | |||
| 16 | 18 | ||
| 17 | namespace VkDeviceInfo { | 19 | namespace VkDeviceInfo { |
| 18 | Record::Record(std::string_view name_, const std::vector<VkPresentModeKHR>& vsync_modes_, | 20 | Record::Record(std::string_view name_, const std::vector<VkPresentModeKHR>& vsync_modes_, |
| 19 | bool is_intel_proprietary_) | 21 | bool has_broken_compute_) |
| 20 | : name{name_}, vsync_support{vsync_modes_}, is_intel_proprietary{is_intel_proprietary_} {} | 22 | : name{name_}, vsync_support{vsync_modes_}, has_broken_compute{has_broken_compute_} {} |
| 21 | 23 | ||
| 22 | Record::~Record() = default; | 24 | Record::~Record() = default; |
| 23 | 25 | ||
| @@ -48,9 +50,10 @@ void PopulateRecords(std::vector<Record>& records, QWindow* window) try { | |||
| 48 | properties.pNext = &driver_properties; | 50 | properties.pNext = &driver_properties; |
| 49 | dld.vkGetPhysicalDeviceProperties2(physical_device, &properties); | 51 | dld.vkGetPhysicalDeviceProperties2(physical_device, &properties); |
| 50 | 52 | ||
| 51 | records.push_back(VkDeviceInfo::Record(name, present_modes, | 53 | bool has_broken_compute{Vulkan::Device::CheckBrokenCompute( |
| 52 | driver_properties.driverID == | 54 | driver_properties.driverID, properties.properties.driverVersion)}; |
| 53 | VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS)); | 55 | |
| 56 | records.push_back(VkDeviceInfo::Record(name, present_modes, has_broken_compute)); | ||
| 54 | } | 57 | } |
| 55 | } catch (const Vulkan::vk::Exception& exception) { | 58 | } catch (const Vulkan::vk::Exception& exception) { |
| 56 | LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what()); | 59 | LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what()); |
diff --git a/src/yuzu/vk_device_info.h b/src/yuzu/vk_device_info.h index 5a6c64416..bda8262f4 100644 --- a/src/yuzu/vk_device_info.h +++ b/src/yuzu/vk_device_info.h | |||
| @@ -24,12 +24,12 @@ namespace VkDeviceInfo { | |||
| 24 | class Record { | 24 | class Record { |
| 25 | public: | 25 | public: |
| 26 | explicit Record(std::string_view name, const std::vector<VkPresentModeKHR>& vsync_modes, | 26 | explicit Record(std::string_view name, const std::vector<VkPresentModeKHR>& vsync_modes, |
| 27 | bool is_intel_proprietary); | 27 | bool has_broken_compute); |
| 28 | ~Record(); | 28 | ~Record(); |
| 29 | 29 | ||
| 30 | const std::string name; | 30 | const std::string name; |
| 31 | const std::vector<VkPresentModeKHR> vsync_support; | 31 | const std::vector<VkPresentModeKHR> vsync_support; |
| 32 | const bool is_intel_proprietary; | 32 | const bool has_broken_compute; |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | void PopulateRecords(std::vector<Record>& records, QWindow* window); | 35 | void PopulateRecords(std::vector<Record>& records, QWindow* window); |