mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +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() { | std::optional<std::vector<ShaderDiskCacheRaw>> ShaderDiskCache::LoadTransferable() { | ||||||
|     const bool has_title_id = GetProgramID() != 0; |     const bool has_title_id = GetProgramID() != 0; | ||||||
|     if (!Settings::values.use_hw_shader || !Settings::values.use_disk_shader_cache || !has_title_id) |     if (!Settings::values.use_hw_shader || !Settings::values.use_disk_shader_cache || | ||||||
|         return {}; |         !has_title_id) { | ||||||
|  |         return std::nullopt; | ||||||
|  |     } | ||||||
|     tried_to_load = true; |     tried_to_load = true; | ||||||
| 
 | 
 | ||||||
|     FileUtil::IOFile file(GetTransferablePath(), "rb"); |     FileUtil::IOFile file(GetTransferablePath(), "rb"); | ||||||
|     if (!file.IsOpen()) { |     if (!file.IsOpen()) { | ||||||
|         LOG_INFO(Render_OpenGL, "No transferable shader cache found for game with title id={}", |         LOG_INFO(Render_OpenGL, "No transferable shader cache found for game with title id={}", | ||||||
|                  GetTitleID()); |                  GetTitleID()); | ||||||
|         return {}; |         return std::nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     u32 version{}; |     u32 version{}; | ||||||
|  | @ -122,19 +124,19 @@ std::optional<std::vector<ShaderDiskCacheRaw>> ShaderDiskCache::LoadTransferable | ||||||
|         LOG_ERROR(Render_OpenGL, |         LOG_ERROR(Render_OpenGL, | ||||||
|                   "Failed to get transferable cache version for title id={} - skipping", |                   "Failed to get transferable cache version for title id={} - skipping", | ||||||
|                   GetTitleID()); |                   GetTitleID()); | ||||||
|         return {}; |         return std::nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (version < NativeVersion) { |     if (version < NativeVersion) { | ||||||
|         LOG_INFO(Render_OpenGL, "Transferable shader cache is old - removing"); |         LOG_INFO(Render_OpenGL, "Transferable shader cache is old - removing"); | ||||||
|         file.Close(); |         file.Close(); | ||||||
|         InvalidateAll(); |         InvalidateAll(); | ||||||
|         return {}; |         return std::nullopt; | ||||||
|     } |     } | ||||||
|     if (version > NativeVersion) { |     if (version > NativeVersion) { | ||||||
|         LOG_WARNING(Render_OpenGL, "Transferable shader cache was generated with a newer version " |         LOG_WARNING(Render_OpenGL, "Transferable shader cache was generated with a newer version " | ||||||
|                                    "of the emulator - skipping"); |                                    "of the emulator - skipping"); | ||||||
|         return {}; |         return std::nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Version is valid, load the shaders
 |     // Version is valid, load the shaders
 | ||||||
|  | @ -143,7 +145,7 @@ std::optional<std::vector<ShaderDiskCacheRaw>> ShaderDiskCache::LoadTransferable | ||||||
|         TransferableEntryKind kind{}; |         TransferableEntryKind kind{}; | ||||||
|         if (file.ReadBytes(&kind, sizeof(u32)) != sizeof(u32)) { |         if (file.ReadBytes(&kind, sizeof(u32)) != sizeof(u32)) { | ||||||
|             LOG_ERROR(Render_OpenGL, "Failed to read transferable file - skipping"); |             LOG_ERROR(Render_OpenGL, "Failed to read transferable file - skipping"); | ||||||
|             return {}; |             return std::nullopt; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         switch (kind) { |         switch (kind) { | ||||||
|  | @ -151,7 +153,7 @@ std::optional<std::vector<ShaderDiskCacheRaw>> ShaderDiskCache::LoadTransferable | ||||||
|             ShaderDiskCacheRaw entry; |             ShaderDiskCacheRaw entry; | ||||||
|             if (!entry.Load(file)) { |             if (!entry.Load(file)) { | ||||||
|                 LOG_ERROR(Render_OpenGL, "Failed to load transferable raw entry - skipping"); |                 LOG_ERROR(Render_OpenGL, "Failed to load transferable raw entry - skipping"); | ||||||
|                 return {}; |                 return std::nullopt; | ||||||
|             } |             } | ||||||
|             transferable.emplace(entry.GetUniqueIdentifier(), ShaderDiskCacheRaw{}); |             transferable.emplace(entry.GetUniqueIdentifier(), ShaderDiskCacheRaw{}); | ||||||
|             raws.push_back(std::move(entry)); |             raws.push_back(std::move(entry)); | ||||||
|  | @ -160,7 +162,7 @@ std::optional<std::vector<ShaderDiskCacheRaw>> ShaderDiskCache::LoadTransferable | ||||||
|         default: |         default: | ||||||
|             LOG_ERROR(Render_OpenGL, "Unknown transferable shader cache entry kind={} - skipping", |             LOG_ERROR(Render_OpenGL, "Unknown transferable shader cache entry kind={} - skipping", | ||||||
|                       static_cast<u32>(kind)); |                       static_cast<u32>(kind)); | ||||||
|             return {}; |             return std::nullopt; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -203,11 +205,11 @@ ShaderDiskCache::LoadPrecompiledFile(FileUtil::IOFile& file) { | ||||||
| 
 | 
 | ||||||
|     ShaderCacheVersionHash file_hash{}; |     ShaderCacheVersionHash file_hash{}; | ||||||
|     if (!LoadArrayFromPrecompiled(file_hash.data(), file_hash.size())) { |     if (!LoadArrayFromPrecompiled(file_hash.data(), file_hash.size())) { | ||||||
|         return {}; |         return std::nullopt; | ||||||
|     } |     } | ||||||
|     if (GetShaderCacheVersionHash() != file_hash) { |     if (GetShaderCacheVersionHash() != file_hash) { | ||||||
|         LOG_INFO(Render_OpenGL, "Precompiled cache is from another version of the emulator"); |         LOG_INFO(Render_OpenGL, "Precompiled cache is from another version of the emulator"); | ||||||
|         return {}; |         return std::nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::unordered_map<u64, ShaderDiskCacheDecompiled> decompiled; |     std::unordered_map<u64, ShaderDiskCacheDecompiled> decompiled; | ||||||
|  | @ -215,19 +217,19 @@ ShaderDiskCache::LoadPrecompiledFile(FileUtil::IOFile& file) { | ||||||
|     while (decompressed_precompiled_cache_offset < decompressed_precompiled_cache.size()) { |     while (decompressed_precompiled_cache_offset < decompressed_precompiled_cache.size()) { | ||||||
|         PrecompiledEntryKind kind{}; |         PrecompiledEntryKind kind{}; | ||||||
|         if (!LoadObjectFromPrecompiled(kind)) { |         if (!LoadObjectFromPrecompiled(kind)) { | ||||||
|             return {}; |             return std::nullopt; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         switch (kind) { |         switch (kind) { | ||||||
|         case PrecompiledEntryKind::Decompiled: { |         case PrecompiledEntryKind::Decompiled: { | ||||||
|             u64 unique_identifier{}; |             u64 unique_identifier{}; | ||||||
|             if (!LoadObjectFromPrecompiled(unique_identifier)) { |             if (!LoadObjectFromPrecompiled(unique_identifier)) { | ||||||
|                 return {}; |                 return std::nullopt; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             auto entry = LoadDecompiledEntry(); |             auto entry = LoadDecompiledEntry(); | ||||||
|             if (!entry) { |             if (!entry) { | ||||||
|                 return {}; |                 return std::nullopt; | ||||||
|             } |             } | ||||||
|             decompiled.insert({unique_identifier, std::move(*entry)}); |             decompiled.insert({unique_identifier, std::move(*entry)}); | ||||||
|             break; |             break; | ||||||
|  | @ -235,29 +237,29 @@ ShaderDiskCache::LoadPrecompiledFile(FileUtil::IOFile& file) { | ||||||
|         case PrecompiledEntryKind::Dump: { |         case PrecompiledEntryKind::Dump: { | ||||||
|             u64 unique_identifier; |             u64 unique_identifier; | ||||||
|             if (!LoadObjectFromPrecompiled(unique_identifier)) { |             if (!LoadObjectFromPrecompiled(unique_identifier)) { | ||||||
|                 return {}; |                 return std::nullopt; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             ShaderDiskCacheDump dump; |             ShaderDiskCacheDump dump; | ||||||
|             if (!LoadObjectFromPrecompiled(dump.binary_format)) { |             if (!LoadObjectFromPrecompiled(dump.binary_format)) { | ||||||
|                 return {}; |                 return std::nullopt; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             u32 binary_length{}; |             u32 binary_length{}; | ||||||
|             if (!LoadObjectFromPrecompiled(binary_length)) { |             if (!LoadObjectFromPrecompiled(binary_length)) { | ||||||
|                 return {}; |                 return std::nullopt; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             dump.binary.resize(binary_length); |             dump.binary.resize(binary_length); | ||||||
|             if (!LoadArrayFromPrecompiled(dump.binary.data(), dump.binary.size())) { |             if (!LoadArrayFromPrecompiled(dump.binary.data(), dump.binary.size())) { | ||||||
|                 return {}; |                 return std::nullopt; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             dumps.insert({unique_identifier, dump}); |             dumps.insert({unique_identifier, dump}); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         default: |         default: | ||||||
|             return {}; |             return std::nullopt; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -271,17 +273,17 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCache::LoadDecompiledEntry() | ||||||
| 
 | 
 | ||||||
|     bool sanitize_mul; |     bool sanitize_mul; | ||||||
|     if (!LoadObjectFromPrecompiled(sanitize_mul)) { |     if (!LoadObjectFromPrecompiled(sanitize_mul)) { | ||||||
|         return {}; |         return std::nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     u32 code_size{}; |     u32 code_size{}; | ||||||
|     if (!LoadObjectFromPrecompiled(code_size)) { |     if (!LoadObjectFromPrecompiled(code_size)) { | ||||||
|         return {}; |         return std::nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::string code(code_size, '\0'); |     std::string code(code_size, '\0'); | ||||||
|     if (!LoadArrayFromPrecompiled(code.data(), code.size())) { |     if (!LoadArrayFromPrecompiled(code.data(), code.size())) { | ||||||
|         return {}; |         return std::nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ShaderDiskCacheDecompiled entry; |     ShaderDiskCacheDecompiled entry; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue