mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 13:20:03 +00:00 
			
		
		
		
	vk_pipeline_cache: Make pipeline cache reads more robust (#7194)
This commit is contained in:
		
							parent
							
								
									85bd1be852
								
							
						
					
					
						commit
						1dc0fa7bb5
					
				
					 1 changed files with 39 additions and 29 deletions
				
			
		|  | @ -8,6 +8,7 @@ | ||||||
| #include "common/file_util.h" | #include "common/file_util.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "common/microprofile.h" | #include "common/microprofile.h" | ||||||
|  | #include "common/scope_exit.h" | ||||||
| #include "common/settings.h" | #include "common/settings.h" | ||||||
| #include "video_core/renderer_vulkan/pica_to_vk.h" | #include "video_core/renderer_vulkan/pica_to_vk.h" | ||||||
| #include "video_core/renderer_vulkan/vk_instance.h" | #include "video_core/renderer_vulkan/vk_instance.h" | ||||||
|  | @ -128,34 +129,42 @@ void PipelineCache::LoadDiskCache() { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const std::string cache_file_path = fmt::format("{}{:x}{:x}.bin", GetPipelineCacheDir(), |     const auto cache_dir = GetPipelineCacheDir(); | ||||||
|                                                     instance.GetVendorID(), instance.GetDeviceID()); |     const u32 vendor_id = instance.GetVendorID(); | ||||||
|     vk::PipelineCacheCreateInfo cache_info = { |     const u32 device_id = instance.GetDeviceID(); | ||||||
|         .initialDataSize = 0, |     const auto cache_file_path = fmt::format("{}{:x}{:x}.bin", cache_dir, vendor_id, device_id); | ||||||
|         .pInitialData = nullptr, |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|  |     vk::PipelineCacheCreateInfo cache_info{}; | ||||||
|     std::vector<u8> cache_data; |     std::vector<u8> cache_data; | ||||||
|     FileUtil::IOFile cache_file{cache_file_path, "r"}; |  | ||||||
|     if (cache_file.IsOpen()) { |  | ||||||
|         LOG_INFO(Render_Vulkan, "Loading pipeline cache"); |  | ||||||
| 
 | 
 | ||||||
|         const u64 cache_file_size = cache_file.GetSize(); |     SCOPE_EXIT({ | ||||||
|         cache_data.resize(cache_file_size); |         const vk::Device device = instance.GetDevice(); | ||||||
|         if (cache_file.ReadBytes(cache_data.data(), cache_file_size)) { |         pipeline_cache = device.createPipelineCacheUnique(cache_info); | ||||||
|             if (!IsCacheValid(cache_data)) { |     }); | ||||||
|                 LOG_WARNING(Render_Vulkan, "Pipeline cache provided invalid, ignoring"); |  | ||||||
|             } else { |  | ||||||
|                 cache_info.initialDataSize = cache_file_size; |  | ||||||
|                 cache_info.pInitialData = cache_data.data(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         cache_file.Close(); |     FileUtil::IOFile cache_file{cache_file_path, "rb"}; | ||||||
|  |     if (!cache_file.IsOpen()) { | ||||||
|  |         LOG_INFO(Render_Vulkan, "No pipeline cache found for device"); | ||||||
|  |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     vk::Device device = instance.GetDevice(); |     const u64 cache_file_size = cache_file.GetSize(); | ||||||
|     pipeline_cache = device.createPipelineCacheUnique(cache_info); |     cache_data.resize(cache_file_size); | ||||||
|  |     if (cache_file.ReadBytes(cache_data.data(), cache_file_size) != cache_file_size) { | ||||||
|  |         LOG_ERROR(Render_Vulkan, "Error during pipeline cache read"); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!IsCacheValid(cache_data)) { | ||||||
|  |         LOG_WARNING(Render_Vulkan, "Pipeline cache provided invalid, removing"); | ||||||
|  |         cache_file.Close(); | ||||||
|  |         FileUtil::Delete(cache_file_path); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     LOG_INFO(Render_Vulkan, "Loading pipeline cache with size {} KB", cache_file_size / 1024); | ||||||
|  |     cache_info.initialDataSize = cache_file_size; | ||||||
|  |     cache_info.pInitialData = cache_data.data(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PipelineCache::SaveDiskCache() { | void PipelineCache::SaveDiskCache() { | ||||||
|  | @ -163,22 +172,23 @@ void PipelineCache::SaveDiskCache() { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const std::string cache_file_path = fmt::format("{}{:x}{:x}.bin", GetPipelineCacheDir(), |     const auto cache_dir = GetPipelineCacheDir(); | ||||||
|                                                     instance.GetVendorID(), instance.GetDeviceID()); |     const u32 vendor_id = instance.GetVendorID(); | ||||||
|  |     const u32 device_id = instance.GetDeviceID(); | ||||||
|  |     const auto cache_file_path = fmt::format("{}{:x}{:x}.bin", cache_dir, vendor_id, device_id); | ||||||
|  | 
 | ||||||
|     FileUtil::IOFile cache_file{cache_file_path, "wb"}; |     FileUtil::IOFile cache_file{cache_file_path, "wb"}; | ||||||
|     if (!cache_file.IsOpen()) { |     if (!cache_file.IsOpen()) { | ||||||
|         LOG_ERROR(Render_Vulkan, "Unable to open pipeline cache for writing"); |         LOG_ERROR(Render_Vulkan, "Unable to open pipeline cache for writing"); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     vk::Device device = instance.GetDevice(); |     const vk::Device device = instance.GetDevice(); | ||||||
|     auto cache_data = device.getPipelineCacheData(*pipeline_cache); |     const auto cache_data = device.getPipelineCacheData(*pipeline_cache); | ||||||
|     if (!cache_file.WriteBytes(cache_data.data(), cache_data.size())) { |     if (cache_file.WriteBytes(cache_data.data(), cache_data.size()) != cache_data.size()) { | ||||||
|         LOG_ERROR(Render_Vulkan, "Error during pipeline cache write"); |         LOG_ERROR(Render_Vulkan, "Error during pipeline cache write"); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     cache_file.Close(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool PipelineCache::BindPipeline(const PipelineInfo& info, bool wait_built) { | bool PipelineCache::BindPipeline(const PipelineInfo& info, bool wait_built) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue