mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-10-31 14:56:40 +08:00 
			
		
		
		
	Merge pull request #1744 from degasus/shader_cache
shader_cache: Only lock covered instructions.
This commit is contained in:
		
						commit
						69b3f98d3a
					
				| @ -84,6 +84,7 @@ CachedShader::CachedShader(VAddr addr, Maxwell::ShaderProgram program_type) | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     entries = program_result.second; |     entries = program_result.second; | ||||||
|  |     shader_length = entries.shader_length; | ||||||
| 
 | 
 | ||||||
|     if (program_type != Maxwell::ShaderProgram::Geometry) { |     if (program_type != Maxwell::ShaderProgram::Geometry) { | ||||||
|         OGLShader shader; |         OGLShader shader; | ||||||
|  | |||||||
| @ -30,7 +30,7 @@ public: | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::size_t GetSizeInBytes() const override { |     std::size_t GetSizeInBytes() const override { | ||||||
|         return GLShader::MAX_PROGRAM_CODE_LENGTH * sizeof(u64); |         return shader_length; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // We do not have to flush this cache as things in it are never modified by us.
 |     // We do not have to flush this cache as things in it are never modified by us.
 | ||||||
| @ -82,6 +82,7 @@ private: | |||||||
|                                u32 max_vertices, const std::string& debug_name); |                                u32 max_vertices, const std::string& debug_name); | ||||||
| 
 | 
 | ||||||
|     VAddr addr; |     VAddr addr; | ||||||
|  |     std::size_t shader_length; | ||||||
|     Maxwell::ShaderProgram program_type; |     Maxwell::ShaderProgram program_type; | ||||||
|     GLShader::ShaderSetup setup; |     GLShader::ShaderSetup setup; | ||||||
|     GLShader::ShaderEntries entries; |     GLShader::ShaderEntries entries; | ||||||
|  | |||||||
| @ -84,7 +84,8 @@ struct Subroutine { | |||||||
| class ControlFlowAnalyzer { | class ControlFlowAnalyzer { | ||||||
| public: | public: | ||||||
|     ControlFlowAnalyzer(const ProgramCode& program_code, u32 main_offset, const std::string& suffix) |     ControlFlowAnalyzer(const ProgramCode& program_code, u32 main_offset, const std::string& suffix) | ||||||
|         : program_code(program_code) { |         : program_code(program_code), shader_coverage_begin(main_offset), | ||||||
|  |           shader_coverage_end(main_offset + 1) { | ||||||
| 
 | 
 | ||||||
|         // Recursively finds all subroutines.
 |         // Recursively finds all subroutines.
 | ||||||
|         const Subroutine& program_main = AddSubroutine(main_offset, PROGRAM_END, suffix); |         const Subroutine& program_main = AddSubroutine(main_offset, PROGRAM_END, suffix); | ||||||
| @ -96,10 +97,16 @@ public: | |||||||
|         return std::move(subroutines); |         return std::move(subroutines); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     std::size_t GetShaderLength() const { | ||||||
|  |         return shader_coverage_end * sizeof(u64); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     const ProgramCode& program_code; |     const ProgramCode& program_code; | ||||||
|     std::set<Subroutine> subroutines; |     std::set<Subroutine> subroutines; | ||||||
|     std::map<std::pair<u32, u32>, ExitMethod> exit_method_map; |     std::map<std::pair<u32, u32>, ExitMethod> exit_method_map; | ||||||
|  |     u32 shader_coverage_begin; | ||||||
|  |     u32 shader_coverage_end; | ||||||
| 
 | 
 | ||||||
|     /// Adds and analyzes a new subroutine if it is not added yet.
 |     /// Adds and analyzes a new subroutine if it is not added yet.
 | ||||||
|     const Subroutine& AddSubroutine(u32 begin, u32 end, const std::string& suffix) { |     const Subroutine& AddSubroutine(u32 begin, u32 end, const std::string& suffix) { | ||||||
| @ -141,6 +148,9 @@ private: | |||||||
|             return exit_method; |             return exit_method; | ||||||
| 
 | 
 | ||||||
|         for (u32 offset = begin; offset != end && offset != PROGRAM_END; ++offset) { |         for (u32 offset = begin; offset != end && offset != PROGRAM_END; ++offset) { | ||||||
|  |             shader_coverage_begin = std::min(shader_coverage_begin, offset); | ||||||
|  |             shader_coverage_end = std::max(shader_coverage_end, offset + 1); | ||||||
|  | 
 | ||||||
|             const Instruction instr = {program_code[offset]}; |             const Instruction instr = {program_code[offset]}; | ||||||
|             if (const auto opcode = OpCode::Decode(instr)) { |             if (const auto opcode = OpCode::Decode(instr)) { | ||||||
|                 switch (opcode->get().GetId()) { |                 switch (opcode->get().GetId()) { | ||||||
| @ -939,9 +949,10 @@ private: | |||||||
| class GLSLGenerator { | class GLSLGenerator { | ||||||
| public: | public: | ||||||
|     GLSLGenerator(const std::set<Subroutine>& subroutines, const ProgramCode& program_code, |     GLSLGenerator(const std::set<Subroutine>& subroutines, const ProgramCode& program_code, | ||||||
|                   u32 main_offset, Maxwell3D::Regs::ShaderStage stage, const std::string& suffix) |                   u32 main_offset, Maxwell3D::Regs::ShaderStage stage, const std::string& suffix, | ||||||
|  |                   std::size_t shader_length) | ||||||
|         : subroutines(subroutines), program_code(program_code), main_offset(main_offset), |         : subroutines(subroutines), program_code(program_code), main_offset(main_offset), | ||||||
|           stage(stage), suffix(suffix) { |           stage(stage), suffix(suffix), shader_length(shader_length) { | ||||||
|         std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); |         std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); | ||||||
|         local_memory_size = header.GetLocalMemorySize(); |         local_memory_size = header.GetLocalMemorySize(); | ||||||
|         regs.SetLocalMemory(local_memory_size); |         regs.SetLocalMemory(local_memory_size); | ||||||
| @ -954,7 +965,7 @@ public: | |||||||
| 
 | 
 | ||||||
|     /// Returns entries in the shader that are useful for external functions
 |     /// Returns entries in the shader that are useful for external functions
 | ||||||
|     ShaderEntries GetEntries() const { |     ShaderEntries GetEntries() const { | ||||||
|         return {regs.GetConstBuffersDeclarations(), regs.GetSamplers()}; |         return {regs.GetConstBuffersDeclarations(), regs.GetSamplers(), shader_length}; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| @ -3748,6 +3759,7 @@ private: | |||||||
|     Maxwell3D::Regs::ShaderStage stage; |     Maxwell3D::Regs::ShaderStage stage; | ||||||
|     const std::string& suffix; |     const std::string& suffix; | ||||||
|     u64 local_memory_size; |     u64 local_memory_size; | ||||||
|  |     std::size_t shader_length; | ||||||
| 
 | 
 | ||||||
|     ShaderWriter shader; |     ShaderWriter shader; | ||||||
|     ShaderWriter declarations; |     ShaderWriter declarations; | ||||||
| @ -3766,9 +3778,10 @@ std::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u | |||||||
|                                               Maxwell3D::Regs::ShaderStage stage, |                                               Maxwell3D::Regs::ShaderStage stage, | ||||||
|                                               const std::string& suffix) { |                                               const std::string& suffix) { | ||||||
|     try { |     try { | ||||||
|         const auto subroutines = |         ControlFlowAnalyzer analyzer(program_code, main_offset, suffix); | ||||||
|             ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines(); |         const auto subroutines = analyzer.GetSubroutines(); | ||||||
|         GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix); |         GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix, | ||||||
|  |                                 analyzer.GetShaderLength()); | ||||||
|         return ProgramResult{generator.GetShaderCode(), generator.GetEntries()}; |         return ProgramResult{generator.GetShaderCode(), generator.GetEntries()}; | ||||||
|     } catch (const DecompileFail& exception) { |     } catch (const DecompileFail& exception) { | ||||||
|         LOG_ERROR(HW_GPU, "Shader decompilation failed: {}", exception.what()); |         LOG_ERROR(HW_GPU, "Shader decompilation failed: {}", exception.what()); | ||||||
|  | |||||||
| @ -163,6 +163,7 @@ private: | |||||||
| struct ShaderEntries { | struct ShaderEntries { | ||||||
|     std::vector<ConstBufferEntry> const_buffer_entries; |     std::vector<ConstBufferEntry> const_buffer_entries; | ||||||
|     std::vector<SamplerEntry> texture_samplers; |     std::vector<SamplerEntry> texture_samplers; | ||||||
|  |     std::size_t shader_length; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| using ProgramResult = std::pair<std::string, ShaderEntries>; | using ProgramResult = std::pair<std::string, ShaderEntries>; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user