mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	shader: avoid recomputing hash for the same program
This commit is contained in:
		
							parent
							
								
									3cc460ab34
								
							
						
					
					
						commit
						d52ddd0ec4
					
				
					 3 changed files with 39 additions and 3 deletions
				
			
		|  | @ -451,6 +451,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|             LOG_ERROR(HW_GPU, "Invalid GS program offset %u", offset); |             LOG_ERROR(HW_GPU, "Invalid GS program offset %u", offset); | ||||||
|         } else { |         } else { | ||||||
|             g_state.gs.program_code[offset] = value; |             g_state.gs.program_code[offset] = value; | ||||||
|  |             g_state.gs.MarkProgramCodeDirty(); | ||||||
|             offset++; |             offset++; | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|  | @ -469,6 +470,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|             LOG_ERROR(HW_GPU, "Invalid GS swizzle pattern offset %u", offset); |             LOG_ERROR(HW_GPU, "Invalid GS swizzle pattern offset %u", offset); | ||||||
|         } else { |         } else { | ||||||
|             g_state.gs.swizzle_data[offset] = value; |             g_state.gs.swizzle_data[offset] = value; | ||||||
|  |             g_state.gs.MarkSwizzleDataDirty(); | ||||||
|             offset++; |             offset++; | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|  | @ -518,8 +520,10 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|             LOG_ERROR(HW_GPU, "Invalid VS program offset %u", offset); |             LOG_ERROR(HW_GPU, "Invalid VS program offset %u", offset); | ||||||
|         } else { |         } else { | ||||||
|             g_state.vs.program_code[offset] = value; |             g_state.vs.program_code[offset] = value; | ||||||
|  |             g_state.vs.MarkProgramCodeDirty(); | ||||||
|             if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) { |             if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) { | ||||||
|                 g_state.gs.program_code[offset] = value; |                 g_state.gs.program_code[offset] = value; | ||||||
|  |                 g_state.gs.MarkProgramCodeDirty(); | ||||||
|             } |             } | ||||||
|             offset++; |             offset++; | ||||||
|         } |         } | ||||||
|  | @ -539,8 +543,10 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|             LOG_ERROR(HW_GPU, "Invalid VS swizzle pattern offset %u", offset); |             LOG_ERROR(HW_GPU, "Invalid VS swizzle pattern offset %u", offset); | ||||||
|         } else { |         } else { | ||||||
|             g_state.vs.swizzle_data[offset] = value; |             g_state.vs.swizzle_data[offset] = value; | ||||||
|  |             g_state.vs.MarkSwizzleDataDirty(); | ||||||
|             if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) { |             if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) { | ||||||
|                 g_state.gs.swizzle_data[offset] = value; |                 g_state.gs.swizzle_data[offset] = value; | ||||||
|  |                 g_state.gs.MarkSwizzleDataDirty(); | ||||||
|             } |             } | ||||||
|             offset++; |             offset++; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ | ||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
| #include "common/common_funcs.h" | #include "common/common_funcs.h" | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
|  | #include "common/hash.h" | ||||||
| #include "common/vector_math.h" | #include "common/vector_math.h" | ||||||
| #include "video_core/pica_types.h" | #include "video_core/pica_types.h" | ||||||
| #include "video_core/regs_rasterizer.h" | #include "video_core/regs_rasterizer.h" | ||||||
|  | @ -206,6 +207,36 @@ struct ShaderSetup { | ||||||
|         /// Used by the JIT, points to a compiled shader object.
 |         /// Used by the JIT, points to a compiled shader object.
 | ||||||
|         const void* cached_shader = nullptr; |         const void* cached_shader = nullptr; | ||||||
|     } engine_data; |     } engine_data; | ||||||
|  | 
 | ||||||
|  |     void MarkProgramCodeDirty() { | ||||||
|  |         program_code_hash_dirty = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void MarkSwizzleDataDirty() { | ||||||
|  |         swizzle_data_hash_dirty = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     u64 GetProgramCodeHash() { | ||||||
|  |         if (program_code_hash_dirty) { | ||||||
|  |             program_code_hash = Common::ComputeHash64(&program_code, sizeof(program_code)); | ||||||
|  |             program_code_hash_dirty = false; | ||||||
|  |         } | ||||||
|  |         return program_code_hash; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     u64 GetSwizzleDataHash() { | ||||||
|  |         if (swizzle_data_hash_dirty) { | ||||||
|  |             swizzle_data_hash = Common::ComputeHash64(&swizzle_data, sizeof(swizzle_data)); | ||||||
|  |             swizzle_data_hash_dirty = false; | ||||||
|  |         } | ||||||
|  |         return swizzle_data_hash; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     bool program_code_hash_dirty = true; | ||||||
|  |     bool swizzle_data_hash_dirty = true; | ||||||
|  |     u64 program_code_hash = 0xDEADC0DE; | ||||||
|  |     u64 swizzle_data_hash = 0xDEADC0DE; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class ShaderEngine { | class ShaderEngine { | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
| // Licensed under GPLv2 or any later version
 | // Licensed under GPLv2 or any later version
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include "common/hash.h" |  | ||||||
| #include "common/microprofile.h" | #include "common/microprofile.h" | ||||||
| #include "video_core/shader/shader.h" | #include "video_core/shader/shader.h" | ||||||
| #include "video_core/shader/shader_jit_x64.h" | #include "video_core/shader/shader_jit_x64.h" | ||||||
|  | @ -18,8 +17,8 @@ void JitX64Engine::SetupBatch(ShaderSetup& setup, unsigned int entry_point) { | ||||||
|     ASSERT(entry_point < MAX_PROGRAM_CODE_LENGTH); |     ASSERT(entry_point < MAX_PROGRAM_CODE_LENGTH); | ||||||
|     setup.engine_data.entry_point = entry_point; |     setup.engine_data.entry_point = entry_point; | ||||||
| 
 | 
 | ||||||
|     u64 code_hash = Common::ComputeHash64(&setup.program_code, sizeof(setup.program_code)); |     u64 code_hash = setup.GetProgramCodeHash(); | ||||||
|     u64 swizzle_hash = Common::ComputeHash64(&setup.swizzle_data, sizeof(setup.swizzle_data)); |     u64 swizzle_hash = setup.GetSwizzleDataHash(); | ||||||
| 
 | 
 | ||||||
|     u64 cache_key = code_hash ^ swizzle_hash; |     u64 cache_key = code_hash ^ swizzle_hash; | ||||||
|     auto iter = cache.find(cache_key); |     auto iter = cache.find(cache_key); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue