mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	common: Add more robust ZSTD handling. (#7071)
This commit is contained in:
		
							parent
							
								
									07839fb3ce
								
							
						
					
					
						commit
						4c59443ed2
					
				
					 3 changed files with 35 additions and 8 deletions
				
			
		|  | @ -11,20 +11,25 @@ namespace Common::Compression { | |||
| 
 | ||||
| std::vector<u8> CompressDataZSTD(std::span<const u8> source, s32 compression_level) { | ||||
|     compression_level = std::clamp(compression_level, ZSTD_minCLevel(), ZSTD_maxCLevel()); | ||||
| 
 | ||||
|     const std::size_t max_compressed_size = ZSTD_compressBound(source.size()); | ||||
|     std::vector<u8> compressed(max_compressed_size); | ||||
| 
 | ||||
|     if (ZSTD_isError(max_compressed_size)) { | ||||
|         LOG_ERROR(Common, "Error determining ZSTD maximum compressed size: {} ({})", | ||||
|                   ZSTD_getErrorName(max_compressed_size), max_compressed_size); | ||||
|         return {}; | ||||
|     } | ||||
| 
 | ||||
|     std::vector<u8> compressed(max_compressed_size); | ||||
|     const std::size_t compressed_size = ZSTD_compress( | ||||
|         compressed.data(), compressed.size(), source.data(), source.size(), compression_level); | ||||
| 
 | ||||
|     if (ZSTD_isError(compressed_size)) { | ||||
|         // Compression failed
 | ||||
|         LOG_ERROR(Common, "Error compressing ZSTD data: {} ({})", | ||||
|                   ZSTD_getErrorName(compressed_size), compressed_size); | ||||
|         return {}; | ||||
|     } | ||||
| 
 | ||||
|     compressed.resize(compressed_size); | ||||
| 
 | ||||
|     return compressed; | ||||
| } | ||||
| 
 | ||||
|  | @ -35,15 +40,32 @@ std::vector<u8> CompressDataZSTDDefault(std::span<const u8> source) { | |||
| std::vector<u8> DecompressDataZSTD(std::span<const u8> compressed) { | ||||
|     const std::size_t decompressed_size = | ||||
|         ZSTD_getFrameContentSize(compressed.data(), compressed.size()); | ||||
|     std::vector<u8> decompressed(decompressed_size); | ||||
| 
 | ||||
|     if (decompressed_size == ZSTD_CONTENTSIZE_UNKNOWN) { | ||||
|         LOG_ERROR(Common, "ZSTD decompressed size could not be determined."); | ||||
|         return {}; | ||||
|     } | ||||
|     if (decompressed_size == ZSTD_CONTENTSIZE_ERROR || ZSTD_isError(decompressed_size)) { | ||||
|         LOG_ERROR(Common, "Error determining ZSTD decompressed size: {} ({})", | ||||
|                   ZSTD_getErrorName(decompressed_size), decompressed_size); | ||||
|         return {}; | ||||
|     } | ||||
| 
 | ||||
|     std::vector<u8> decompressed(decompressed_size); | ||||
|     const std::size_t uncompressed_result_size = ZSTD_decompress( | ||||
|         decompressed.data(), decompressed.size(), compressed.data(), compressed.size()); | ||||
| 
 | ||||
|     if (decompressed_size != uncompressed_result_size || ZSTD_isError(uncompressed_result_size)) { | ||||
|         // Decompression failed
 | ||||
|     if (decompressed_size != uncompressed_result_size) { | ||||
|         LOG_ERROR(Common, "ZSTD decompression expected {} bytes, got {}", decompressed_size, | ||||
|                   uncompressed_result_size); | ||||
|         return {}; | ||||
|     } | ||||
|     if (ZSTD_isError(uncompressed_result_size)) { | ||||
|         LOG_ERROR(Common, "Error decompressing ZSTD data: {} ({})", | ||||
|                   ZSTD_getErrorName(uncompressed_result_size), uncompressed_result_size); | ||||
|         return {}; | ||||
|     } | ||||
| 
 | ||||
|     return decompressed; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -206,6 +206,10 @@ ShaderDiskCache::LoadPrecompiledFile(FileUtil::IOFile& file, bool compressed) { | |||
|     if (compressed) { | ||||
|         const std::vector<u8> decompressed = | ||||
|             Common::Compression::DecompressDataZSTD(precompiled_file); | ||||
|         if (decompressed.empty()) { | ||||
|             LOG_ERROR(Render_OpenGL, "Could not decompress precompiled shader cache."); | ||||
|             return std::nullopt; | ||||
|         } | ||||
|         SaveArrayToPrecompiled(decompressed.data(), decompressed.size()); | ||||
|     } else { | ||||
|         SaveArrayToPrecompiled(precompiled_file.data(), precompiled_file.size()); | ||||
|  |  | |||
|  | @ -10,10 +10,11 @@ | |||
| 
 | ||||
| namespace Pica::Shader::Generator { | ||||
| 
 | ||||
| // NOTE: Changing the order impacts shader transferable and precompiled cache loading.
 | ||||
| enum ProgramType : u32 { | ||||
|     VS = 0, | ||||
|     GS = 2, | ||||
|     FS = 1, | ||||
|     GS = 2, | ||||
| }; | ||||
| 
 | ||||
| enum Attributes { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue