mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-10-31 06:46: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; | ||||
|     shader_length = entries.shader_length; | ||||
| 
 | ||||
|     if (program_type != Maxwell::ShaderProgram::Geometry) { | ||||
|         OGLShader shader; | ||||
|  | ||||
| @ -30,7 +30,7 @@ public: | ||||
|     } | ||||
| 
 | ||||
|     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.
 | ||||
| @ -82,6 +82,7 @@ private: | ||||
|                                u32 max_vertices, const std::string& debug_name); | ||||
| 
 | ||||
|     VAddr addr; | ||||
|     std::size_t shader_length; | ||||
|     Maxwell::ShaderProgram program_type; | ||||
|     GLShader::ShaderSetup setup; | ||||
|     GLShader::ShaderEntries entries; | ||||
|  | ||||
| @ -84,7 +84,8 @@ struct Subroutine { | ||||
| class ControlFlowAnalyzer { | ||||
| public: | ||||
|     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.
 | ||||
|         const Subroutine& program_main = AddSubroutine(main_offset, PROGRAM_END, suffix); | ||||
| @ -96,10 +97,16 @@ public: | ||||
|         return std::move(subroutines); | ||||
|     } | ||||
| 
 | ||||
|     std::size_t GetShaderLength() const { | ||||
|         return shader_coverage_end * sizeof(u64); | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     const ProgramCode& program_code; | ||||
|     std::set<Subroutine> subroutines; | ||||
|     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.
 | ||||
|     const Subroutine& AddSubroutine(u32 begin, u32 end, const std::string& suffix) { | ||||
| @ -141,6 +148,9 @@ private: | ||||
|             return exit_method; | ||||
| 
 | ||||
|         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]}; | ||||
|             if (const auto opcode = OpCode::Decode(instr)) { | ||||
|                 switch (opcode->get().GetId()) { | ||||
| @ -939,9 +949,10 @@ private: | ||||
| class GLSLGenerator { | ||||
| public: | ||||
|     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), | ||||
|           stage(stage), suffix(suffix) { | ||||
|           stage(stage), suffix(suffix), shader_length(shader_length) { | ||||
|         std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); | ||||
|         local_memory_size = header.GetLocalMemorySize(); | ||||
|         regs.SetLocalMemory(local_memory_size); | ||||
| @ -954,7 +965,7 @@ public: | ||||
| 
 | ||||
|     /// Returns entries in the shader that are useful for external functions
 | ||||
|     ShaderEntries GetEntries() const { | ||||
|         return {regs.GetConstBuffersDeclarations(), regs.GetSamplers()}; | ||||
|         return {regs.GetConstBuffersDeclarations(), regs.GetSamplers(), shader_length}; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
| @ -3748,6 +3759,7 @@ private: | ||||
|     Maxwell3D::Regs::ShaderStage stage; | ||||
|     const std::string& suffix; | ||||
|     u64 local_memory_size; | ||||
|     std::size_t shader_length; | ||||
| 
 | ||||
|     ShaderWriter shader; | ||||
|     ShaderWriter declarations; | ||||
| @ -3766,9 +3778,10 @@ std::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u | ||||
|                                               Maxwell3D::Regs::ShaderStage stage, | ||||
|                                               const std::string& suffix) { | ||||
|     try { | ||||
|         const auto subroutines = | ||||
|             ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines(); | ||||
|         GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix); | ||||
|         ControlFlowAnalyzer analyzer(program_code, main_offset, suffix); | ||||
|         const auto subroutines = analyzer.GetSubroutines(); | ||||
|         GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix, | ||||
|                                 analyzer.GetShaderLength()); | ||||
|         return ProgramResult{generator.GetShaderCode(), generator.GetEntries()}; | ||||
|     } catch (const DecompileFail& exception) { | ||||
|         LOG_ERROR(HW_GPU, "Shader decompilation failed: {}", exception.what()); | ||||
|  | ||||
| @ -163,6 +163,7 @@ private: | ||||
| struct ShaderEntries { | ||||
|     std::vector<ConstBufferEntry> const_buffer_entries; | ||||
|     std::vector<SamplerEntry> texture_samplers; | ||||
|     std::size_t shader_length; | ||||
| }; | ||||
| 
 | ||||
| using ProgramResult = std::pair<std::string, ShaderEntries>; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user