mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Custom textures rewrite (#6452)
* common: Add thread pool from yuzu * Is really useful for asynchronous operations like shader compilation and custom textures, will be used in following PRs * core: Improve ImageInterface * Provide a default implementation so frontends don't have to duplicate code registering the lodepng version * Add a dds version too which we will use in the next commit * rasterizer_cache: Rewrite custom textures * There's just too much to talk about here, look at the PR description for more details * rasterizer_cache: Implement basic pack configuration file * custom_tex_manager: Flip dumped textures * custom_tex_manager: Optimize custom texture hashing * If no convertions are needed then we can hash the decoded data directly removing the needed for duplicate decode * custom_tex_manager: Implement asynchronous texture loading * The file loading and decoding is offloaded into worker threads, while the upload itself still occurs in the main thread to avoid having to manage shared contexts * Address review comments * custom_tex_manager: Introduce custom material support * video_core: Move custom textures to separate directory * Also split the files to make the code cleaner * gl_texture_runtime: Generate mipmaps for material * custom_tex_manager: Prevent memory overflow when preloading * externals: Add dds-ktx as submodule * string_util: Return vector from SplitString * No code benefits from passing it as an argument * custom_textures: Use json config file * gl_rasterizer: Only bind material for unit 0 * Address review comments
This commit is contained in:
		
							parent
							
								
									d16dce6d99
								
							
						
					
					
						commit
						06f3c90cfb
					
				
					 87 changed files with 2154 additions and 544 deletions
				
			
		|  | @ -368,6 +368,7 @@ public final class SettingsFragmentPresenter { | |||
|         SettingSection utilitySection = mSettings.getSection(Settings.SECTION_UTILITY); | ||||
|         Setting dumpTextures = utilitySection.getSetting(SettingsFile.KEY_DUMP_TEXTURES); | ||||
|         Setting customTextures = utilitySection.getSetting(SettingsFile.KEY_CUSTOM_TEXTURES); | ||||
|         Setting asyncCustomLoading = utilitySection.getSetting(SettingsFile.KEY_ASYNC_CUSTOM_LOADING); | ||||
|         //Setting preloadTextures = utilitySection.getSetting(SettingsFile.KEY_PRELOAD_TEXTURES); | ||||
| 
 | ||||
|         sl.add(new HeaderSetting(null, null, R.string.renderer, 0)); | ||||
|  | @ -389,6 +390,7 @@ public final class SettingsFragmentPresenter { | |||
|         sl.add(new HeaderSetting(null, null, R.string.utility, 0)); | ||||
|         sl.add(new CheckBoxSetting(SettingsFile.KEY_DUMP_TEXTURES, Settings.SECTION_UTILITY, R.string.dump_textures, R.string.dump_textures_description, false, dumpTextures)); | ||||
|         sl.add(new CheckBoxSetting(SettingsFile.KEY_CUSTOM_TEXTURES, Settings.SECTION_UTILITY, R.string.custom_textures, R.string.custom_textures_description, false, customTextures)); | ||||
|         sl.add(new CheckBoxSetting(SettingsFile.KEY_ASYNC_CUSTOM_LOADING, Settings.SECTION_UTILITY, R.string.async_custom_loading, R.string.async_custom_loading_description, true, asyncCustomLoading)); | ||||
|         //Disabled until custom texture implementation gets rewrite, current one overloads RAM and crashes Citra. | ||||
|         //sl.add(new CheckBoxSetting(SettingsFile.KEY_PRELOAD_TEXTURES, Settings.SECTION_UTILITY, R.string.preload_textures, R.string.preload_textures_description, false, preloadTextures)); | ||||
|     } | ||||
|  |  | |||
|  | @ -73,6 +73,7 @@ public final class SettingsFile { | |||
|     public static final String KEY_DUMP_TEXTURES = "dump_textures"; | ||||
|     public static final String KEY_CUSTOM_TEXTURES = "custom_textures"; | ||||
|     public static final String KEY_PRELOAD_TEXTURES = "preload_textures"; | ||||
|     public static final String KEY_ASYNC_CUSTOM_LOADING = "async_custom_loading"; | ||||
| 
 | ||||
|     public static final String KEY_AUDIO_OUTPUT_ENGINE = "output_engine"; | ||||
|     public static final String KEY_ENABLE_AUDIO_STRETCHING = "enable_audio_stretching"; | ||||
|  |  | |||
|  | @ -25,8 +25,6 @@ add_library(citra-android SHARED | |||
|     game_settings.h | ||||
|     id_cache.cpp | ||||
|     id_cache.h | ||||
|     lodepng_image_interface.cpp | ||||
|     lodepng_image_interface.h | ||||
|     mic.cpp | ||||
|     mic.h | ||||
|     native.cpp | ||||
|  | @ -36,6 +34,6 @@ add_library(citra-android SHARED | |||
| ) | ||||
| 
 | ||||
| target_link_libraries(citra-android PRIVATE audio_core common core input_common network) | ||||
| target_link_libraries(citra-android PRIVATE android camera2ndk EGL glad inih jnigraphics lodepng log mediandk yuv) | ||||
| target_link_libraries(citra-android PRIVATE android camera2ndk EGL glad inih jnigraphics log mediandk yuv) | ||||
| 
 | ||||
| set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} citra-android) | ||||
|  |  | |||
|  | @ -62,8 +62,7 @@ JNIEXPORT void JNICALL Java_org_citra_citra_1emu_features_cheats_model_Cheat_set | |||
| JNIEXPORT jint JNICALL Java_org_citra_citra_1emu_features_cheats_model_Cheat_isValidGatewayCode( | ||||
|     JNIEnv* env, jclass, jstring j_code) { | ||||
|     const std::string code = GetJString(env, j_code); | ||||
|     std::vector<std::string> code_lines; | ||||
|     Common::SplitString(code, '\n', code_lines); | ||||
|     const auto code_lines = Common::SplitString(code, '\n'); | ||||
| 
 | ||||
|     for (int i = 0; i < code_lines.size(); ++i) { | ||||
|         Cheats::GatewayCheat::CheatLine cheat_line(code_lines[i]); | ||||
|  |  | |||
|  | @ -195,6 +195,7 @@ void Config::ReadValues() { | |||
|     ReadSetting("Utility", Settings::values.dump_textures); | ||||
|     ReadSetting("Utility", Settings::values.custom_textures); | ||||
|     ReadSetting("Utility", Settings::values.preload_textures); | ||||
|     ReadSetting("Utility", Settings::values.async_custom_loading); | ||||
| 
 | ||||
|     // Audio
 | ||||
|     ReadSetting("Audio", Settings::values.audio_emulation); | ||||
|  |  | |||
|  | @ -213,6 +213,10 @@ custom_textures = | |||
| # 0 (default): Off, 1: On | ||||
| preload_textures = | ||||
| 
 | ||||
| # Loads custom textures asynchronously with background threads. | ||||
| # 0: Off, 1 (default): On | ||||
| async_custom_loading = | ||||
| 
 | ||||
| [Audio] | ||||
| # Whether or not to enable DSP LLE | ||||
| # 0 (default): No, 1: Yes | ||||
|  |  | |||
|  | @ -1,44 +0,0 @@ | |||
| // Copyright 2019 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <lodepng.h> | ||||
| #include "common/file_util.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "jni/lodepng_image_interface.h" | ||||
| 
 | ||||
| bool LodePNGImageInterface::DecodePNG(std::vector<u8>& dst, u32& width, u32& height, | ||||
|                                       const std::string& path) { | ||||
|     FileUtil::IOFile file(path, "rb"); | ||||
|     size_t read_size = file.GetSize(); | ||||
|     std::vector<u8> in(read_size); | ||||
|     if (file.ReadBytes(&in[0], read_size) != read_size) { | ||||
|         LOG_CRITICAL(Frontend, "Failed to decode {}", path); | ||||
|     } | ||||
|     u32 lodepng_ret = lodepng::decode(dst, width, height, in); | ||||
|     if (lodepng_ret) { | ||||
|         LOG_CRITICAL(Frontend, "Failed to decode {} because {}", path, | ||||
|                      lodepng_error_text(lodepng_ret)); | ||||
|         return false; | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| bool LodePNGImageInterface::EncodePNG(const std::string& path, const std::vector<u8>& src, | ||||
|                                       u32 width, u32 height) { | ||||
|     std::vector<u8> out; | ||||
|     u32 lodepng_ret = lodepng::encode(out, src, width, height); | ||||
|     if (lodepng_ret) { | ||||
|         LOG_CRITICAL(Frontend, "Failed to encode {} because {}", path, | ||||
|                      lodepng_error_text(lodepng_ret)); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     FileUtil::IOFile file(path, "wb"); | ||||
|     if (file.WriteBytes(&out[0], out.size()) != out.size()) { | ||||
|         LOG_CRITICAL(Frontend, "Failed to save encode to path={}", path); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
|  | @ -1,14 +0,0 @@ | |||
| // Copyright 2019 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "core/frontend/image_interface.h" | ||||
| 
 | ||||
| class LodePNGImageInterface final : public Frontend::ImageInterface { | ||||
| public: | ||||
|     bool DecodePNG(std::vector<u8>& dst, u32& width, u32& height, const std::string& path) override; | ||||
|     bool EncodePNG(const std::string& path, const std::vector<u8>& src, u32 width, | ||||
|                    u32 height) override; | ||||
| }; | ||||
|  | @ -39,7 +39,6 @@ | |||
| #include "jni/game_settings.h" | ||||
| #include "jni/id_cache.h" | ||||
| #include "jni/input_manager.h" | ||||
| #include "jni/lodepng_image_interface.h" | ||||
| #include "jni/mic.h" | ||||
| #include "jni/native.h" | ||||
| #include "jni/ndk_motion.h" | ||||
|  | @ -184,9 +183,6 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) { | |||
|     system.RegisterMiiSelector(std::make_shared<MiiSelector::AndroidMiiSelector>()); | ||||
|     system.RegisterSoftwareKeyboard(std::make_shared<SoftwareKeyboard::AndroidKeyboard>()); | ||||
| 
 | ||||
|     // Register generic image interface
 | ||||
|     Core::System::GetInstance().RegisterImageInterface(std::make_shared<LodePNGImageInterface>()); | ||||
| 
 | ||||
|     // Register real Mic factory
 | ||||
|     Frontend::Mic::RegisterRealMicFactory(std::make_unique<Mic::AndroidFactory>()); | ||||
| 
 | ||||
|  |  | |||
|  | @ -116,6 +116,8 @@ | |||
|     <string name="custom_textures_description">Uses custom textures found in load/textures/[GAME ID]</string> | ||||
|     <string name="preload_textures">Preload custom textures</string> | ||||
|     <string name="preload_textures_description">Loads all custom textures into memory. This feature can use a lot of memory.</string> | ||||
|     <string name="async_custom_loading">Async custom texture loading</string> | ||||
|     <string name="async_custom_loading_description">Loads custom textures in the background with worker threads to reduce loading stutter.</string> | ||||
|     <!-- Premium strings --> | ||||
|     <string name="premium_text">Premium</string> | ||||
|     <string name="premium_settings_upsell">Upgrade to Premium and support Citra!</string> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue