mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	gl_shader_disk: Make use of std::nullopt where applicable (#5293)
Some implementations can use the std::nullopt_t constructor of
std::optional to avoid needing to completely zero out the internal
buffer of the optional and instead only set the validity byte within it.
e.g. Consider the following function:
std::optional<std::vector<ShaderDiskCacheRaw>> fn() {
    return {};
}
With libc++ this will result in the following code generation on x86-64:
Fn():
  mov     rax, rdi
  vxorps  xmm0, xmm0, xmm0
  vmovups ymmword ptr [rdi], ymm0
  vzeroupper
  ret
With libstdc++, we also get the similar equivalent:
Fn():
  vpxor   xmm0, xmm0, xmm0
  mov     rax, rdi
  vmovdqu XMMWORD PTR [rdi], xmm0
  vmovdqu XMMWORD PTR [rdi+16], xmm0
  ret
If we change this function to return std::nullopt instead, then this
simplifies both the code gen from libc++ and libstdc++ down to:
Fn():
  mov     BYTE PTR [rdi+24], 0
  mov     rax, rdi
  ret
Given how little of a change is necessary to result in better code
generation, this is essentially a "free" very minor optimization.
			
			
This commit is contained in:
		
							parent
							
								
									4a677e83fe
								
							
						
					
					
						commit
						85d37c9994
					
				
					 1 changed files with 24 additions and 22 deletions
				
			
		|  | @ -106,15 +106,17 @@ ShaderDiskCache::ShaderDiskCache(bool separable) : separable{separable} {} | |||
| 
 | ||||
| std::optional<std::vector<ShaderDiskCacheRaw>> ShaderDiskCache::LoadTransferable() { | ||||
|     const bool has_title_id = GetProgramID() != 0; | ||||
|     if (!Settings::values.use_hw_shader || !Settings::values.use_disk_shader_cache || !has_title_id) | ||||
|         return {}; | ||||
|     if (!Settings::values.use_hw_shader || !Settings::values.use_disk_shader_cache || | ||||
|         !has_title_id) { | ||||
|         return std::nullopt; | ||||
|     } | ||||
|     tried_to_load = true; | ||||
| 
 | ||||
|     FileUtil::IOFile file(GetTransferablePath(), "rb"); | ||||
|     if (!file.IsOpen()) { | ||||
|         LOG_INFO(Render_OpenGL, "No transferable shader cache found for game with title id={}", | ||||
|                  GetTitleID()); | ||||
|         return {}; | ||||
|         return std::nullopt; | ||||
|     } | ||||
| 
 | ||||
|     u32 version{}; | ||||
|  | @ -122,19 +124,19 @@ std::optional<std::vector<ShaderDiskCacheRaw>> ShaderDiskCache::LoadTransferable | |||
|         LOG_ERROR(Render_OpenGL, | ||||
|                   "Failed to get transferable cache version for title id={} - skipping", | ||||
|                   GetTitleID()); | ||||
|         return {}; | ||||
|         return std::nullopt; | ||||
|     } | ||||
| 
 | ||||
|     if (version < NativeVersion) { | ||||
|         LOG_INFO(Render_OpenGL, "Transferable shader cache is old - removing"); | ||||
|         file.Close(); | ||||
|         InvalidateAll(); | ||||
|         return {}; | ||||
|         return std::nullopt; | ||||
|     } | ||||
|     if (version > NativeVersion) { | ||||
|         LOG_WARNING(Render_OpenGL, "Transferable shader cache was generated with a newer version " | ||||
|                                    "of the emulator - skipping"); | ||||
|         return {}; | ||||
|         return std::nullopt; | ||||
|     } | ||||
| 
 | ||||
|     // Version is valid, load the shaders
 | ||||
|  | @ -143,7 +145,7 @@ std::optional<std::vector<ShaderDiskCacheRaw>> ShaderDiskCache::LoadTransferable | |||
|         TransferableEntryKind kind{}; | ||||
|         if (file.ReadBytes(&kind, sizeof(u32)) != sizeof(u32)) { | ||||
|             LOG_ERROR(Render_OpenGL, "Failed to read transferable file - skipping"); | ||||
|             return {}; | ||||
|             return std::nullopt; | ||||
|         } | ||||
| 
 | ||||
|         switch (kind) { | ||||
|  | @ -151,7 +153,7 @@ std::optional<std::vector<ShaderDiskCacheRaw>> ShaderDiskCache::LoadTransferable | |||
|             ShaderDiskCacheRaw entry; | ||||
|             if (!entry.Load(file)) { | ||||
|                 LOG_ERROR(Render_OpenGL, "Failed to load transferable raw entry - skipping"); | ||||
|                 return {}; | ||||
|                 return std::nullopt; | ||||
|             } | ||||
|             transferable.emplace(entry.GetUniqueIdentifier(), ShaderDiskCacheRaw{}); | ||||
|             raws.push_back(std::move(entry)); | ||||
|  | @ -160,7 +162,7 @@ std::optional<std::vector<ShaderDiskCacheRaw>> ShaderDiskCache::LoadTransferable | |||
|         default: | ||||
|             LOG_ERROR(Render_OpenGL, "Unknown transferable shader cache entry kind={} - skipping", | ||||
|                       static_cast<u32>(kind)); | ||||
|             return {}; | ||||
|             return std::nullopt; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -203,11 +205,11 @@ ShaderDiskCache::LoadPrecompiledFile(FileUtil::IOFile& file) { | |||
| 
 | ||||
|     ShaderCacheVersionHash file_hash{}; | ||||
|     if (!LoadArrayFromPrecompiled(file_hash.data(), file_hash.size())) { | ||||
|         return {}; | ||||
|         return std::nullopt; | ||||
|     } | ||||
|     if (GetShaderCacheVersionHash() != file_hash) { | ||||
|         LOG_INFO(Render_OpenGL, "Precompiled cache is from another version of the emulator"); | ||||
|         return {}; | ||||
|         return std::nullopt; | ||||
|     } | ||||
| 
 | ||||
|     std::unordered_map<u64, ShaderDiskCacheDecompiled> decompiled; | ||||
|  | @ -215,19 +217,19 @@ ShaderDiskCache::LoadPrecompiledFile(FileUtil::IOFile& file) { | |||
|     while (decompressed_precompiled_cache_offset < decompressed_precompiled_cache.size()) { | ||||
|         PrecompiledEntryKind kind{}; | ||||
|         if (!LoadObjectFromPrecompiled(kind)) { | ||||
|             return {}; | ||||
|             return std::nullopt; | ||||
|         } | ||||
| 
 | ||||
|         switch (kind) { | ||||
|         case PrecompiledEntryKind::Decompiled: { | ||||
|             u64 unique_identifier{}; | ||||
|             if (!LoadObjectFromPrecompiled(unique_identifier)) { | ||||
|                 return {}; | ||||
|                 return std::nullopt; | ||||
|             } | ||||
| 
 | ||||
|             auto entry = LoadDecompiledEntry(); | ||||
|             if (!entry) { | ||||
|                 return {}; | ||||
|                 return std::nullopt; | ||||
|             } | ||||
|             decompiled.insert({unique_identifier, std::move(*entry)}); | ||||
|             break; | ||||
|  | @ -235,29 +237,29 @@ ShaderDiskCache::LoadPrecompiledFile(FileUtil::IOFile& file) { | |||
|         case PrecompiledEntryKind::Dump: { | ||||
|             u64 unique_identifier; | ||||
|             if (!LoadObjectFromPrecompiled(unique_identifier)) { | ||||
|                 return {}; | ||||
|                 return std::nullopt; | ||||
|             } | ||||
| 
 | ||||
|             ShaderDiskCacheDump dump; | ||||
|             if (!LoadObjectFromPrecompiled(dump.binary_format)) { | ||||
|                 return {}; | ||||
|                 return std::nullopt; | ||||
|             } | ||||
| 
 | ||||
|             u32 binary_length{}; | ||||
|             if (!LoadObjectFromPrecompiled(binary_length)) { | ||||
|                 return {}; | ||||
|                 return std::nullopt; | ||||
|             } | ||||
| 
 | ||||
|             dump.binary.resize(binary_length); | ||||
|             if (!LoadArrayFromPrecompiled(dump.binary.data(), dump.binary.size())) { | ||||
|                 return {}; | ||||
|                 return std::nullopt; | ||||
|             } | ||||
| 
 | ||||
|             dumps.insert({unique_identifier, dump}); | ||||
|             break; | ||||
|         } | ||||
|         default: | ||||
|             return {}; | ||||
|             return std::nullopt; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -271,17 +273,17 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCache::LoadDecompiledEntry() | |||
| 
 | ||||
|     bool sanitize_mul; | ||||
|     if (!LoadObjectFromPrecompiled(sanitize_mul)) { | ||||
|         return {}; | ||||
|         return std::nullopt; | ||||
|     } | ||||
| 
 | ||||
|     u32 code_size{}; | ||||
|     if (!LoadObjectFromPrecompiled(code_size)) { | ||||
|         return {}; | ||||
|         return std::nullopt; | ||||
|     } | ||||
| 
 | ||||
|     std::string code(code_size, '\0'); | ||||
|     if (!LoadArrayFromPrecompiled(code.data(), code.size())) { | ||||
|         return {}; | ||||
|         return std::nullopt; | ||||
|     } | ||||
| 
 | ||||
|     ShaderDiskCacheDecompiled entry; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue