diff options
| author | 2019-09-24 23:34:18 -0300 | |
|---|---|---|
| committer | 2019-10-25 09:01:31 -0400 | |
| commit | 7b81ba4d8a9805f808fcc60a0905ac74d293b2ee (patch) | |
| tree | 7bf80df3851e7d0e25746d241cbb0e09ba5c6b33 /src/video_core/shader | |
| parent | Shader_IR: Implement Fast BRX and allow multi-branches in the CFG. (diff) | |
| download | yuzu-7b81ba4d8a9805f808fcc60a0905ac74d293b2ee.tar.gz yuzu-7b81ba4d8a9805f808fcc60a0905ac74d293b2ee.tar.xz yuzu-7b81ba4d8a9805f808fcc60a0905ac74d293b2ee.zip | |
gl_shader_decompiler: Move entries to a separate function
Diffstat (limited to 'src/video_core/shader')
| -rw-r--r-- | src/video_core/shader/const_buffer_locker.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/shader/const_buffer_locker.h | 4 | ||||
| -rw-r--r-- | src/video_core/shader/control_flow.cpp | 18 | ||||
| -rw-r--r-- | src/video_core/shader/control_flow.h | 3 | ||||
| -rw-r--r-- | src/video_core/shader/decode.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 12 |
7 files changed, 29 insertions, 32 deletions
diff --git a/src/video_core/shader/const_buffer_locker.cpp b/src/video_core/shader/const_buffer_locker.cpp index 9d23bcecf..37a0968a1 100644 --- a/src/video_core/shader/const_buffer_locker.cpp +++ b/src/video_core/shader/const_buffer_locker.cpp | |||
| @@ -15,15 +15,15 @@ ConstBufferLocker::ConstBufferLocker(Tegra::Engines::ShaderType shader_stage) | |||
| 15 | : engine{nullptr}, shader_stage{shader_stage} {} | 15 | : engine{nullptr}, shader_stage{shader_stage} {} |
| 16 | 16 | ||
| 17 | ConstBufferLocker::ConstBufferLocker(Tegra::Engines::ShaderType shader_stage, | 17 | ConstBufferLocker::ConstBufferLocker(Tegra::Engines::ShaderType shader_stage, |
| 18 | Tegra::Engines::ConstBufferEngineInterface* engine) | 18 | Tegra::Engines::ConstBufferEngineInterface& engine) |
| 19 | : engine{engine}, shader_stage{shader_stage} {} | 19 | : engine{&engine}, shader_stage{shader_stage} {} |
| 20 | 20 | ||
| 21 | bool ConstBufferLocker::IsEngineSet() const { | 21 | bool ConstBufferLocker::IsEngineSet() const { |
| 22 | return engine != nullptr; | 22 | return engine != nullptr; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | void ConstBufferLocker::SetEngine(Tegra::Engines::ConstBufferEngineInterface* engine_) { | 25 | void ConstBufferLocker::SetEngine(Tegra::Engines::ConstBufferEngineInterface& engine_) { |
| 26 | engine = engine_; | 26 | engine = &engine_; |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | std::optional<u32> ConstBufferLocker::ObtainKey(u32 buffer, u32 offset) { | 29 | std::optional<u32> ConstBufferLocker::ObtainKey(u32 buffer, u32 offset) { |
diff --git a/src/video_core/shader/const_buffer_locker.h b/src/video_core/shader/const_buffer_locker.h index 13eeba320..54459977f 100644 --- a/src/video_core/shader/const_buffer_locker.h +++ b/src/video_core/shader/const_buffer_locker.h | |||
| @@ -21,14 +21,14 @@ public: | |||
| 21 | explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage); | 21 | explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage); |
| 22 | 22 | ||
| 23 | explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage, | 23 | explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage, |
| 24 | Tegra::Engines::ConstBufferEngineInterface* engine); | 24 | Tegra::Engines::ConstBufferEngineInterface& engine); |
| 25 | 25 | ||
| 26 | // Checks if an engine is setup, it may be possible that during disk shader | 26 | // Checks if an engine is setup, it may be possible that during disk shader |
| 27 | // cache run, the engines have not been created yet. | 27 | // cache run, the engines have not been created yet. |
| 28 | bool IsEngineSet() const; | 28 | bool IsEngineSet() const; |
| 29 | 29 | ||
| 30 | // Use this to set/change the engine used for this shader. | 30 | // Use this to set/change the engine used for this shader. |
| 31 | void SetEngine(Tegra::Engines::ConstBufferEngineInterface* engine); | 31 | void SetEngine(Tegra::Engines::ConstBufferEngineInterface& engine); |
| 32 | 32 | ||
| 33 | // Retrieves a key from the locker, if it's registered, it will give the | 33 | // Retrieves a key from the locker, if it's registered, it will give the |
| 34 | // registered value, if not it will obtain it from maxwell3d and register it. | 34 | // registered value, if not it will obtain it from maxwell3d and register it. |
diff --git a/src/video_core/shader/control_flow.cpp b/src/video_core/shader/control_flow.cpp index d1c269ea7..6c698bcff 100644 --- a/src/video_core/shader/control_flow.cpp +++ b/src/video_core/shader/control_flow.cpp | |||
| @@ -66,10 +66,11 @@ struct BlockInfo { | |||
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | struct CFGRebuildState { | 68 | struct CFGRebuildState { |
| 69 | explicit CFGRebuildState(const ProgramCode& program_code, const std::size_t program_size, | 69 | explicit CFGRebuildState(const ProgramCode& program_code, u32 start, ConstBufferLocker& locker) |
| 70 | const u32 start, ConstBufferLocker& locker) | 70 | : program_code{program_code}, start{start}, locker{locker} {} |
| 71 | : start{start}, program_code{program_code}, program_size{program_size}, locker{locker} {} | ||
| 72 | 71 | ||
| 72 | const ProgramCode& program_code; | ||
| 73 | ConstBufferLocker& locker; | ||
| 73 | u32 start{}; | 74 | u32 start{}; |
| 74 | std::vector<BlockInfo> block_info{}; | 75 | std::vector<BlockInfo> block_info{}; |
| 75 | std::list<u32> inspect_queries{}; | 76 | std::list<u32> inspect_queries{}; |
| @@ -79,10 +80,7 @@ struct CFGRebuildState { | |||
| 79 | std::map<u32, u32> ssy_labels{}; | 80 | std::map<u32, u32> ssy_labels{}; |
| 80 | std::map<u32, u32> pbk_labels{}; | 81 | std::map<u32, u32> pbk_labels{}; |
| 81 | std::unordered_map<u32, BlockStack> stacks{}; | 82 | std::unordered_map<u32, BlockStack> stacks{}; |
| 82 | const ProgramCode& program_code; | ||
| 83 | const std::size_t program_size; | ||
| 84 | ASTManager* manager; | 83 | ASTManager* manager; |
| 85 | ConstBufferLocker& locker; | ||
| 86 | }; | 84 | }; |
| 87 | 85 | ||
| 88 | enum class BlockCollision : u32 { None, Found, Inside }; | 86 | enum class BlockCollision : u32 { None, Found, Inside }; |
| @@ -242,7 +240,7 @@ std::optional<BranchIndirectInfo> TrackBranchIndirectInfo(const CFGRebuildState& | |||
| 242 | 240 | ||
| 243 | std::pair<ParseResult, ParseInfo> ParseCode(CFGRebuildState& state, u32 address) { | 241 | std::pair<ParseResult, ParseInfo> ParseCode(CFGRebuildState& state, u32 address) { |
| 244 | u32 offset = static_cast<u32>(address); | 242 | u32 offset = static_cast<u32>(address); |
| 245 | const u32 end_address = static_cast<u32>(state.program_size / sizeof(Instruction)); | 243 | const u32 end_address = static_cast<u32>(state.program_code.size()); |
| 246 | ParseInfo parse_info{}; | 244 | ParseInfo parse_info{}; |
| 247 | SingleBranch single_branch{}; | 245 | SingleBranch single_branch{}; |
| 248 | 246 | ||
| @@ -583,6 +581,7 @@ bool TryQuery(CFGRebuildState& state) { | |||
| 583 | } | 581 | } |
| 584 | return true; | 582 | return true; |
| 585 | } | 583 | } |
| 584 | |||
| 586 | } // Anonymous namespace | 585 | } // Anonymous namespace |
| 587 | 586 | ||
| 588 | void InsertBranch(ASTManager& mm, const BlockBranchInfo& branch_info) { | 587 | void InsertBranch(ASTManager& mm, const BlockBranchInfo& branch_info) { |
| @@ -651,8 +650,7 @@ void DecompileShader(CFGRebuildState& state) { | |||
| 651 | state.manager->Decompile(); | 650 | state.manager->Decompile(); |
| 652 | } | 651 | } |
| 653 | 652 | ||
| 654 | std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, | 653 | std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 start_address, |
| 655 | std::size_t program_size, u32 start_address, | ||
| 656 | const CompilerSettings& settings, | 654 | const CompilerSettings& settings, |
| 657 | ConstBufferLocker& locker) { | 655 | ConstBufferLocker& locker) { |
| 658 | auto result_out = std::make_unique<ShaderCharacteristics>(); | 656 | auto result_out = std::make_unique<ShaderCharacteristics>(); |
| @@ -661,7 +659,7 @@ std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, | |||
| 661 | return result_out; | 659 | return result_out; |
| 662 | } | 660 | } |
| 663 | 661 | ||
| 664 | CFGRebuildState state{program_code, program_size, start_address, locker}; | 662 | CFGRebuildState state{program_code, start_address, locker}; |
| 665 | // Inspect Code and generate blocks | 663 | // Inspect Code and generate blocks |
| 666 | state.labels.clear(); | 664 | state.labels.clear(); |
| 667 | state.labels.emplace(start_address); | 665 | state.labels.emplace(start_address); |
diff --git a/src/video_core/shader/control_flow.h b/src/video_core/shader/control_flow.h index 369ca255b..288ee68af 100644 --- a/src/video_core/shader/control_flow.h +++ b/src/video_core/shader/control_flow.h | |||
| @@ -105,8 +105,7 @@ struct ShaderCharacteristics { | |||
| 105 | CompilerSettings settings{}; | 105 | CompilerSettings settings{}; |
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, | 108 | std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 start_address, |
| 109 | std::size_t program_size, u32 start_address, | ||
| 110 | const CompilerSettings& settings, | 109 | const CompilerSettings& settings, |
| 111 | ConstBufferLocker& locker); | 110 | ConstBufferLocker& locker); |
| 112 | 111 | ||
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp index 053241128..e1afa4582 100644 --- a/src/video_core/shader/decode.cpp +++ b/src/video_core/shader/decode.cpp | |||
| @@ -33,7 +33,7 @@ constexpr bool IsSchedInstruction(u32 offset, u32 main_offset) { | |||
| 33 | return (absolute_offset % SchedPeriod) == 0; | 33 | return (absolute_offset % SchedPeriod) == 0; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | } // namespace | 36 | } // Anonymous namespace |
| 37 | 37 | ||
| 38 | class ASTDecoder { | 38 | class ASTDecoder { |
| 39 | public: | 39 | public: |
| @@ -102,7 +102,7 @@ void ShaderIR::Decode() { | |||
| 102 | std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); | 102 | std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); |
| 103 | 103 | ||
| 104 | decompiled = false; | 104 | decompiled = false; |
| 105 | auto info = ScanFlow(program_code, program_size, main_offset, settings, locker); | 105 | auto info = ScanFlow(program_code, main_offset, settings, locker); |
| 106 | auto& shader_info = *info; | 106 | auto& shader_info = *info; |
| 107 | coverage_begin = shader_info.start; | 107 | coverage_begin = shader_info.start; |
| 108 | coverage_end = shader_info.end; | 108 | coverage_end = shader_info.end; |
| @@ -155,7 +155,7 @@ void ShaderIR::Decode() { | |||
| 155 | [[fallthrough]]; | 155 | [[fallthrough]]; |
| 156 | case CompileDepth::BruteForce: { | 156 | case CompileDepth::BruteForce: { |
| 157 | coverage_begin = main_offset; | 157 | coverage_begin = main_offset; |
| 158 | const u32 shader_end = static_cast<u32>(program_size / sizeof(u64)); | 158 | const u32 shader_end = program_code.size(); |
| 159 | coverage_end = shader_end; | 159 | coverage_end = shader_end; |
| 160 | for (u32 label = main_offset; label < shader_end; label++) { | 160 | for (u32 label = main_offset; label < shader_end; label++) { |
| 161 | basic_blocks.insert({label, DecodeRange(label, label + 1)}); | 161 | basic_blocks.insert({label, DecodeRange(label, label + 1)}); |
| @@ -225,7 +225,8 @@ void ShaderIR::InsertControlFlow(NodeBlock& bb, const ShaderBlock& block) { | |||
| 225 | for (auto& branch_case : multi_branch->branches) { | 225 | for (auto& branch_case : multi_branch->branches) { |
| 226 | Node n = Operation(OperationCode::Branch, Immediate(branch_case.address)); | 226 | Node n = Operation(OperationCode::Branch, Immediate(branch_case.address)); |
| 227 | Node op_b = Immediate(branch_case.cmp_value); | 227 | Node op_b = Immediate(branch_case.cmp_value); |
| 228 | Node condition = GetPredicateComparisonInteger(Tegra::Shader::PredCondition::Equal, false, op_a, op_b); | 228 | Node condition = |
| 229 | GetPredicateComparisonInteger(Tegra::Shader::PredCondition::Equal, false, op_a, op_b); | ||
| 229 | auto result = Conditional(condition, {n}); | 230 | auto result = Conditional(condition, {n}); |
| 230 | bb.push_back(result); | 231 | bb.push_back(result); |
| 231 | global_code.push_back(result); | 232 | global_code.push_back(result); |
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index 6430575ec..1d718ccc6 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp | |||
| @@ -22,10 +22,9 @@ 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, const std::size_t size, | 25 | ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset, CompilerSettings settings, |
| 26 | CompilerSettings settings, ConstBufferLocker& locker) | 26 | ConstBufferLocker& locker) |
| 27 | : program_code{program_code}, main_offset{main_offset}, program_size{size}, basic_blocks{}, | 27 | : program_code{program_code}, main_offset{main_offset}, settings{settings}, locker{locker} { |
| 28 | program_manager{true, true}, settings{settings}, locker{locker} { | ||
| 29 | Decode(); | 28 | Decode(); |
| 30 | } | 29 | } |
| 31 | 30 | ||
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 3a3e381d2..3ebea91b9 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -67,8 +67,8 @@ struct GlobalMemoryUsage { | |||
| 67 | 67 | ||
| 68 | class ShaderIR final { | 68 | class ShaderIR final { |
| 69 | public: | 69 | public: |
| 70 | explicit ShaderIR(const ProgramCode& program_code, u32 main_offset, std::size_t size, | 70 | explicit ShaderIR(const ProgramCode& program_code, u32 main_offset, CompilerSettings settings, |
| 71 | CompilerSettings settings, ConstBufferLocker& locker); | 71 | ConstBufferLocker& locker); |
| 72 | ~ShaderIR(); | 72 | ~ShaderIR(); |
| 73 | 73 | ||
| 74 | const std::map<u32, NodeBlock>& GetBasicBlocks() const { | 74 | const std::map<u32, NodeBlock>& GetBasicBlocks() const { |
| @@ -384,7 +384,9 @@ private: | |||
| 384 | 384 | ||
| 385 | const ProgramCode& program_code; | 385 | const ProgramCode& program_code; |
| 386 | const u32 main_offset; | 386 | const u32 main_offset; |
| 387 | const std::size_t program_size; | 387 | const CompilerSettings settings; |
| 388 | ConstBufferLocker& locker; | ||
| 389 | |||
| 388 | bool decompiled{}; | 390 | bool decompiled{}; |
| 389 | bool disable_flow_stack{}; | 391 | bool disable_flow_stack{}; |
| 390 | 392 | ||
| @@ -393,9 +395,7 @@ private: | |||
| 393 | 395 | ||
| 394 | std::map<u32, NodeBlock> basic_blocks; | 396 | std::map<u32, NodeBlock> basic_blocks; |
| 395 | NodeBlock global_code; | 397 | NodeBlock global_code; |
| 396 | ASTManager program_manager; | 398 | ASTManager program_manager{true, true}; |
| 397 | CompilerSettings settings{}; | ||
| 398 | ConstBufferLocker& locker; | ||
| 399 | 399 | ||
| 400 | std::set<u32> used_registers; | 400 | std::set<u32> used_registers; |
| 401 | std::set<Tegra::Shader::Pred> used_predicates; | 401 | std::set<Tegra::Shader::Pred> used_predicates; |