summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp1
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h3
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp27
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.h1
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 {
84class ControlFlowAnalyzer { 84class ControlFlowAnalyzer {
85public: 85public:
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
99private: 104private:
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:
939class GLSLGenerator { 949class GLSLGenerator {
940public: 950public:
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
960private: 971private:
@@ -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:
163struct ShaderEntries { 163struct 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
168using ProgramResult = std::pair<std::string, ShaderEntries>; 169using ProgramResult = std::pair<std::string, ShaderEntries>;