diff options
| author | 2019-06-25 07:57:32 -0400 | |
|---|---|---|
| committer | 2019-07-09 08:14:37 -0400 | |
| commit | 459fce3a8f26241ff2a68c323e75fb70e7e1ba79 (patch) | |
| tree | 4b653d7dd8fd7e6d325ca69cdd1384187cbd73ac /src | |
| parent | shader_ir: Implement BRX & BRA.CC (diff) | |
| download | yuzu-459fce3a8f26241ff2a68c323e75fb70e7e1ba79.tar.gz yuzu-459fce3a8f26241ff2a68c323e75fb70e7e1ba79.tar.xz yuzu-459fce3a8f26241ff2a68c323e75fb70e7e1ba79.zip | |
shader_ir: propagate shader size to the IR
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.h | 2 | ||||
| -rw-r--r-- | src/video_core/shader/decode.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 3 |
6 files changed, 28 insertions, 17 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index f9b2b03a0..5d76ee12d 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -129,9 +129,11 @@ std::size_t CalculateProgramSize(const GLShader::ProgramCode& program) { | |||
| 129 | 129 | ||
| 130 | /// Hashes one (or two) program streams | 130 | /// Hashes one (or two) program streams |
| 131 | u64 GetUniqueIdentifier(Maxwell::ShaderProgram program_type, const ProgramCode& code, | 131 | u64 GetUniqueIdentifier(Maxwell::ShaderProgram program_type, const ProgramCode& code, |
| 132 | const ProgramCode& code_b) { | 132 | const ProgramCode& code_b, std::size_t size_a = 0, std::size_t size_b = 0) { |
| 133 | u64 unique_identifier = | 133 | if (size_a == 0) { |
| 134 | Common::CityHash64(reinterpret_cast<const char*>(code.data()), CalculateProgramSize(code)); | 134 | size_a = CalculateProgramSize(code); |
| 135 | } | ||
| 136 | u64 unique_identifier = Common::CityHash64(reinterpret_cast<const char*>(code.data()), size_a); | ||
| 135 | if (program_type != Maxwell::ShaderProgram::VertexA) { | 137 | if (program_type != Maxwell::ShaderProgram::VertexA) { |
| 136 | return unique_identifier; | 138 | return unique_identifier; |
| 137 | } | 139 | } |
| @@ -140,8 +142,11 @@ u64 GetUniqueIdentifier(Maxwell::ShaderProgram program_type, const ProgramCode& | |||
| 140 | std::size_t seed = 0; | 142 | std::size_t seed = 0; |
| 141 | boost::hash_combine(seed, unique_identifier); | 143 | boost::hash_combine(seed, unique_identifier); |
| 142 | 144 | ||
| 143 | const u64 identifier_b = Common::CityHash64(reinterpret_cast<const char*>(code_b.data()), | 145 | if (size_b == 0) { |
| 144 | CalculateProgramSize(code_b)); | 146 | size_b = CalculateProgramSize(code_b); |
| 147 | } | ||
| 148 | const u64 identifier_b = | ||
| 149 | Common::CityHash64(reinterpret_cast<const char*>(code_b.data()), size_b); | ||
| 145 | boost::hash_combine(seed, identifier_b); | 150 | boost::hash_combine(seed, identifier_b); |
| 146 | return static_cast<u64>(seed); | 151 | return static_cast<u64>(seed); |
| 147 | } | 152 | } |
| @@ -150,14 +155,17 @@ u64 GetUniqueIdentifier(Maxwell::ShaderProgram program_type, const ProgramCode& | |||
| 150 | GLShader::ProgramResult CreateProgram(const Device& device, Maxwell::ShaderProgram program_type, | 155 | GLShader::ProgramResult CreateProgram(const Device& device, Maxwell::ShaderProgram program_type, |
| 151 | ProgramCode program_code, ProgramCode program_code_b) { | 156 | ProgramCode program_code, ProgramCode program_code_b) { |
| 152 | GLShader::ShaderSetup setup(program_code); | 157 | GLShader::ShaderSetup setup(program_code); |
| 158 | setup.program.size_a = CalculateProgramSize(program_code); | ||
| 159 | setup.program.size_b = 0; | ||
| 153 | if (program_type == Maxwell::ShaderProgram::VertexA) { | 160 | if (program_type == Maxwell::ShaderProgram::VertexA) { |
| 154 | // VertexB is always enabled, so when VertexA is enabled, we have two vertex shaders. | 161 | // VertexB is always enabled, so when VertexA is enabled, we have two vertex shaders. |
| 155 | // Conventional HW does not support this, so we combine VertexA and VertexB into one | 162 | // Conventional HW does not support this, so we combine VertexA and VertexB into one |
| 156 | // stage here. | 163 | // stage here. |
| 157 | setup.SetProgramB(program_code_b); | 164 | setup.SetProgramB(program_code_b); |
| 165 | setup.program.size_b = CalculateProgramSize(program_code_b); | ||
| 158 | } | 166 | } |
| 159 | setup.program.unique_identifier = | 167 | setup.program.unique_identifier = GetUniqueIdentifier( |
| 160 | GetUniqueIdentifier(program_type, program_code, program_code_b); | 168 | program_type, program_code, program_code_b, setup.program.size_a, setup.program.size_b); |
| 161 | 169 | ||
| 162 | switch (program_type) { | 170 | switch (program_type) { |
| 163 | case Maxwell::ShaderProgram::VertexA: | 171 | case Maxwell::ShaderProgram::VertexA: |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 9148629ec..f9ee8429e 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -29,14 +29,14 @@ layout (std140, binding = EMULATION_UBO_BINDING) uniform vs_config { | |||
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | )"; | 31 | )"; |
| 32 | const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); | 32 | const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET, setup.program.size_a); |
| 33 | ProgramResult program = | 33 | ProgramResult program = |
| 34 | Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Vertex, "vertex"); | 34 | Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Vertex, "vertex"); |
| 35 | 35 | ||
| 36 | out += program.first; | 36 | out += program.first; |
| 37 | 37 | ||
| 38 | if (setup.IsDualProgram()) { | 38 | if (setup.IsDualProgram()) { |
| 39 | const ShaderIR program_ir_b(setup.program.code_b, PROGRAM_OFFSET); | 39 | const ShaderIR program_ir_b(setup.program.code_b, PROGRAM_OFFSET, setup.program.size_b); |
| 40 | ProgramResult program_b = | 40 | ProgramResult program_b = |
| 41 | Decompile(device, program_ir_b, Maxwell3D::Regs::ShaderStage::Vertex, "vertex_b"); | 41 | Decompile(device, program_ir_b, Maxwell3D::Regs::ShaderStage::Vertex, "vertex_b"); |
| 42 | 42 | ||
| @@ -80,7 +80,7 @@ layout (std140, binding = EMULATION_UBO_BINDING) uniform gs_config { | |||
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | )"; | 82 | )"; |
| 83 | const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); | 83 | const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET, setup.program.size_a); |
| 84 | ProgramResult program = | 84 | ProgramResult program = |
| 85 | Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Geometry, "geometry"); | 85 | Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Geometry, "geometry"); |
| 86 | out += program.first; | 86 | out += program.first; |
| @@ -115,7 +115,7 @@ layout (std140, binding = EMULATION_UBO_BINDING) uniform fs_config { | |||
| 115 | }; | 115 | }; |
| 116 | 116 | ||
| 117 | )"; | 117 | )"; |
| 118 | const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); | 118 | const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET, setup.program.size_a); |
| 119 | ProgramResult program = | 119 | ProgramResult program = |
| 120 | Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Fragment, "fragment"); | 120 | Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Fragment, "fragment"); |
| 121 | 121 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.h b/src/video_core/renderer_opengl/gl_shader_gen.h index 0536c8a03..7cbc590f8 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.h +++ b/src/video_core/renderer_opengl/gl_shader_gen.h | |||
| @@ -27,6 +27,8 @@ struct ShaderSetup { | |||
| 27 | ProgramCode code; | 27 | ProgramCode code; |
| 28 | ProgramCode code_b; // Used for dual vertex shaders | 28 | ProgramCode code_b; // Used for dual vertex shaders |
| 29 | u64 unique_identifier; | 29 | u64 unique_identifier; |
| 30 | std::size_t size_a; | ||
| 31 | std::size_t size_b; | ||
| 30 | } program; | 32 | } program; |
| 31 | 33 | ||
| 32 | /// Used in scenarios where we have a dual vertex shaders | 34 | /// Used in scenarios where we have a dual vertex shaders |
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp index 65029d35e..09f55bd21 100644 --- a/src/video_core/shader/decode.cpp +++ b/src/video_core/shader/decode.cpp | |||
| @@ -39,7 +39,7 @@ void ShaderIR::Decode() { | |||
| 39 | std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); | 39 | std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); |
| 40 | 40 | ||
| 41 | ShaderCharacteristics shader_info{}; | 41 | ShaderCharacteristics shader_info{}; |
| 42 | bool can_proceed = ScanFlow(program_code, MAX_PROGRAM_LENGTH, main_offset, shader_info); | 42 | bool can_proceed = ScanFlow(program_code, program_code.size(), main_offset, shader_info); |
| 43 | if (can_proceed) { | 43 | if (can_proceed) { |
| 44 | coverage_begin = shader_info.start; | 44 | coverage_begin = shader_info.start; |
| 45 | coverage_end = shader_info.end; | 45 | coverage_end = shader_info.end; |
| @@ -52,12 +52,12 @@ void ShaderIR::Decode() { | |||
| 52 | } | 52 | } |
| 53 | return; | 53 | return; |
| 54 | } | 54 | } |
| 55 | LOG_CRITICAL(HW_GPU, "Flow Analysis failed, falling back to brute force compiling"); | 55 | LOG_WARNING(HW_GPU, "Flow Analysis failed, falling back to brute force compiling"); |
| 56 | 56 | ||
| 57 | // Now we need to deal with an undecompilable shader. We need to brute force | 57 | // Now we need to deal with an undecompilable shader. We need to brute force |
| 58 | // a shader that captures every position. | 58 | // a shader that captures every position. |
| 59 | coverage_begin = shader_info.start; | 59 | coverage_begin = shader_info.start; |
| 60 | const u32 shader_end = static_cast<u32>(MAX_PROGRAM_LENGTH); | 60 | const u32 shader_end = static_cast<u32>(program_size / sizeof(u64)); |
| 61 | coverage_end = shader_end; | 61 | coverage_end = shader_end; |
| 62 | for (u32 label = main_offset; label < shader_end; label++) { | 62 | for (u32 label = main_offset; label < shader_end; label++) { |
| 63 | basic_blocks.insert({label, DecodeRange(label, label + 1)}); | 63 | basic_blocks.insert({label, DecodeRange(label, label + 1)}); |
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index 11b545cca..5994bfc4e 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp | |||
| @@ -22,8 +22,8 @@ using Tegra::Shader::PredCondition; | |||
| 22 | using Tegra::Shader::PredOperation; | 22 | using Tegra::Shader::PredOperation; |
| 23 | using Tegra::Shader::Register; | 23 | using Tegra::Shader::Register; |
| 24 | 24 | ||
| 25 | ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset) | 25 | ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset, const std::size_t size) |
| 26 | : program_code{program_code}, main_offset{main_offset} { | 26 | : program_code{program_code}, main_offset{main_offset}, program_size{size} { |
| 27 | Decode(); | 27 | Decode(); |
| 28 | } | 28 | } |
| 29 | 29 | ||
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index e71462e02..a67d4f390 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -65,7 +65,7 @@ struct GlobalMemoryUsage { | |||
| 65 | 65 | ||
| 66 | class ShaderIR final { | 66 | class ShaderIR final { |
| 67 | public: | 67 | public: |
| 68 | explicit ShaderIR(const ProgramCode& program_code, u32 main_offset); | 68 | explicit ShaderIR(const ProgramCode& program_code, u32 main_offset, std::size_t size); |
| 69 | ~ShaderIR(); | 69 | ~ShaderIR(); |
| 70 | 70 | ||
| 71 | const std::map<u32, NodeBlock>& GetBasicBlocks() const { | 71 | const std::map<u32, NodeBlock>& GetBasicBlocks() const { |
| @@ -316,6 +316,7 @@ private: | |||
| 316 | 316 | ||
| 317 | const ProgramCode& program_code; | 317 | const ProgramCode& program_code; |
| 318 | const u32 main_offset; | 318 | const u32 main_offset; |
| 319 | const std::size_t program_size; | ||
| 319 | 320 | ||
| 320 | u32 coverage_begin{}; | 321 | u32 coverage_begin{}; |
| 321 | u32 coverage_end{}; | 322 | u32 coverage_end{}; |