diff options
4 files changed, 24 insertions, 8 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index a85a7c0c5..038b25c75 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -84,6 +84,7 @@ CachedShader::CachedShader(VAddr addr, Maxwell::ShaderProgram program_type) | |||
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | entries = program_result.second; | 86 | entries = program_result.second; |
| 87 | shader_length = entries.shader_length; | ||
| 87 | 88 | ||
| 88 | if (program_type != Maxwell::ShaderProgram::Geometry) { | 89 | if (program_type != Maxwell::ShaderProgram::Geometry) { |
| 89 | OGLShader shader; | 90 | OGLShader shader; |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index ffbf21831..08f470de3 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h | |||
| @@ -30,7 +30,7 @@ public: | |||
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | std::size_t GetSizeInBytes() const override { | 32 | std::size_t GetSizeInBytes() const override { |
| 33 | return GLShader::MAX_PROGRAM_CODE_LENGTH * sizeof(u64); | 33 | return shader_length; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | // We do not have to flush this cache as things in it are never modified by us. | 36 | // We do not have to flush this cache as things in it are never modified by us. |
| @@ -82,6 +82,7 @@ private: | |||
| 82 | u32 max_vertices, const std::string& debug_name); | 82 | u32 max_vertices, const std::string& debug_name); |
| 83 | 83 | ||
| 84 | VAddr addr; | 84 | VAddr addr; |
| 85 | std::size_t shader_length; | ||
| 85 | Maxwell::ShaderProgram program_type; | 86 | Maxwell::ShaderProgram program_type; |
| 86 | GLShader::ShaderSetup setup; | 87 | GLShader::ShaderSetup setup; |
| 87 | GLShader::ShaderEntries entries; | 88 | GLShader::ShaderEntries entries; |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index ba80e5832..9cd95dadc 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -84,7 +84,8 @@ struct Subroutine { | |||
| 84 | class ControlFlowAnalyzer { | 84 | class ControlFlowAnalyzer { |
| 85 | public: | 85 | public: |
| 86 | ControlFlowAnalyzer(const ProgramCode& program_code, u32 main_offset, const std::string& suffix) | 86 | ControlFlowAnalyzer(const ProgramCode& program_code, u32 main_offset, const std::string& suffix) |
| 87 | : program_code(program_code) { | 87 | : program_code(program_code), shader_coverage_begin(main_offset), |
| 88 | shader_coverage_end(main_offset + 1) { | ||
| 88 | 89 | ||
| 89 | // Recursively finds all subroutines. | 90 | // Recursively finds all subroutines. |
| 90 | const Subroutine& program_main = AddSubroutine(main_offset, PROGRAM_END, suffix); | 91 | const Subroutine& program_main = AddSubroutine(main_offset, PROGRAM_END, suffix); |
| @@ -96,10 +97,16 @@ public: | |||
| 96 | return std::move(subroutines); | 97 | return std::move(subroutines); |
| 97 | } | 98 | } |
| 98 | 99 | ||
| 100 | std::size_t GetShaderLength() const { | ||
| 101 | return shader_coverage_end * sizeof(u64); | ||
| 102 | } | ||
| 103 | |||
| 99 | private: | 104 | private: |
| 100 | const ProgramCode& program_code; | 105 | const ProgramCode& program_code; |
| 101 | std::set<Subroutine> subroutines; | 106 | std::set<Subroutine> subroutines; |
| 102 | std::map<std::pair<u32, u32>, ExitMethod> exit_method_map; | 107 | std::map<std::pair<u32, u32>, ExitMethod> exit_method_map; |
| 108 | u32 shader_coverage_begin; | ||
| 109 | u32 shader_coverage_end; | ||
| 103 | 110 | ||
| 104 | /// Adds and analyzes a new subroutine if it is not added yet. | 111 | /// Adds and analyzes a new subroutine if it is not added yet. |
| 105 | const Subroutine& AddSubroutine(u32 begin, u32 end, const std::string& suffix) { | 112 | const Subroutine& AddSubroutine(u32 begin, u32 end, const std::string& suffix) { |
| @@ -141,6 +148,9 @@ private: | |||
| 141 | return exit_method; | 148 | return exit_method; |
| 142 | 149 | ||
| 143 | for (u32 offset = begin; offset != end && offset != PROGRAM_END; ++offset) { | 150 | for (u32 offset = begin; offset != end && offset != PROGRAM_END; ++offset) { |
| 151 | shader_coverage_begin = std::min(shader_coverage_begin, offset); | ||
| 152 | shader_coverage_end = std::max(shader_coverage_end, offset + 1); | ||
| 153 | |||
| 144 | const Instruction instr = {program_code[offset]}; | 154 | const Instruction instr = {program_code[offset]}; |
| 145 | if (const auto opcode = OpCode::Decode(instr)) { | 155 | if (const auto opcode = OpCode::Decode(instr)) { |
| 146 | switch (opcode->get().GetId()) { | 156 | switch (opcode->get().GetId()) { |
| @@ -939,9 +949,10 @@ private: | |||
| 939 | class GLSLGenerator { | 949 | class GLSLGenerator { |
| 940 | public: | 950 | public: |
| 941 | GLSLGenerator(const std::set<Subroutine>& subroutines, const ProgramCode& program_code, | 951 | GLSLGenerator(const std::set<Subroutine>& subroutines, const ProgramCode& program_code, |
| 942 | u32 main_offset, Maxwell3D::Regs::ShaderStage stage, const std::string& suffix) | 952 | u32 main_offset, Maxwell3D::Regs::ShaderStage stage, const std::string& suffix, |
| 953 | std::size_t shader_length) | ||
| 943 | : subroutines(subroutines), program_code(program_code), main_offset(main_offset), | 954 | : subroutines(subroutines), program_code(program_code), main_offset(main_offset), |
| 944 | stage(stage), suffix(suffix) { | 955 | stage(stage), suffix(suffix), shader_length(shader_length) { |
| 945 | std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); | 956 | std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); |
| 946 | local_memory_size = header.GetLocalMemorySize(); | 957 | local_memory_size = header.GetLocalMemorySize(); |
| 947 | regs.SetLocalMemory(local_memory_size); | 958 | regs.SetLocalMemory(local_memory_size); |
| @@ -954,7 +965,7 @@ public: | |||
| 954 | 965 | ||
| 955 | /// Returns entries in the shader that are useful for external functions | 966 | /// Returns entries in the shader that are useful for external functions |
| 956 | ShaderEntries GetEntries() const { | 967 | ShaderEntries GetEntries() const { |
| 957 | return {regs.GetConstBuffersDeclarations(), regs.GetSamplers()}; | 968 | return {regs.GetConstBuffersDeclarations(), regs.GetSamplers(), shader_length}; |
| 958 | } | 969 | } |
| 959 | 970 | ||
| 960 | private: | 971 | private: |
| @@ -3748,6 +3759,7 @@ private: | |||
| 3748 | Maxwell3D::Regs::ShaderStage stage; | 3759 | Maxwell3D::Regs::ShaderStage stage; |
| 3749 | const std::string& suffix; | 3760 | const std::string& suffix; |
| 3750 | u64 local_memory_size; | 3761 | u64 local_memory_size; |
| 3762 | std::size_t shader_length; | ||
| 3751 | 3763 | ||
| 3752 | ShaderWriter shader; | 3764 | ShaderWriter shader; |
| 3753 | ShaderWriter declarations; | 3765 | ShaderWriter declarations; |
| @@ -3766,9 +3778,10 @@ std::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u | |||
| 3766 | Maxwell3D::Regs::ShaderStage stage, | 3778 | Maxwell3D::Regs::ShaderStage stage, |
| 3767 | const std::string& suffix) { | 3779 | const std::string& suffix) { |
| 3768 | try { | 3780 | try { |
| 3769 | const auto subroutines = | 3781 | ControlFlowAnalyzer analyzer(program_code, main_offset, suffix); |
| 3770 | ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines(); | 3782 | const auto subroutines = analyzer.GetSubroutines(); |
| 3771 | GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix); | 3783 | GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix, |
| 3784 | analyzer.GetShaderLength()); | ||
| 3772 | return ProgramResult{generator.GetShaderCode(), generator.GetEntries()}; | 3785 | return ProgramResult{generator.GetShaderCode(), generator.GetEntries()}; |
| 3773 | } catch (const DecompileFail& exception) { | 3786 | } catch (const DecompileFail& exception) { |
| 3774 | LOG_ERROR(HW_GPU, "Shader decompilation failed: {}", exception.what()); | 3787 | LOG_ERROR(HW_GPU, "Shader decompilation failed: {}", exception.what()); |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.h b/src/video_core/renderer_opengl/gl_shader_gen.h index 520b9d4e3..b425d98ae 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.h +++ b/src/video_core/renderer_opengl/gl_shader_gen.h | |||
| @@ -163,6 +163,7 @@ private: | |||
| 163 | struct ShaderEntries { | 163 | struct ShaderEntries { |
| 164 | std::vector<ConstBufferEntry> const_buffer_entries; | 164 | std::vector<ConstBufferEntry> const_buffer_entries; |
| 165 | std::vector<SamplerEntry> texture_samplers; | 165 | std::vector<SamplerEntry> texture_samplers; |
| 166 | std::size_t shader_length; | ||
| 166 | }; | 167 | }; |
| 167 | 168 | ||
| 168 | using ProgramResult = std::pair<std::string, ShaderEntries>; | 169 | using ProgramResult = std::pair<std::string, ShaderEntries>; |