diff options
| author | 2019-06-29 01:44:07 -0400 | |
|---|---|---|
| committer | 2019-10-04 18:52:50 -0400 | |
| commit | 38fc995f6cc2c2af29abc976ddb45b72873b2cc4 (patch) | |
| tree | a73839d510c79a5e296e54a6768868f788abd45d /src/video_core/shader | |
| parent | shader_ir: Declare Manager and pass it to appropiate programs. (diff) | |
| download | yuzu-38fc995f6cc2c2af29abc976ddb45b72873b2cc4.tar.gz yuzu-38fc995f6cc2c2af29abc976ddb45b72873b2cc4.tar.xz yuzu-38fc995f6cc2c2af29abc976ddb45b72873b2cc4.zip | |
gl_shader_decompiler: Implement AST decompiling
Diffstat (limited to 'src/video_core/shader')
| -rw-r--r-- | src/video_core/shader/ast.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/shader/ast.h | 18 | ||||
| -rw-r--r-- | src/video_core/shader/control_flow.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/shader/control_flow.h | 2 | ||||
| -rw-r--r-- | src/video_core/shader/decode.cpp | 70 | ||||
| -rw-r--r-- | src/video_core/shader/decode/other.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/shader/expr.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/shader/expr.h | 2 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 25 |
10 files changed, 116 insertions, 34 deletions
diff --git a/src/video_core/shader/ast.cpp b/src/video_core/shader/ast.cpp index 0bf289f98..68a96cc79 100644 --- a/src/video_core/shader/ast.cpp +++ b/src/video_core/shader/ast.cpp | |||
| @@ -372,13 +372,13 @@ ASTManager::~ASTManager() { | |||
| 372 | void ASTManager::Init() { | 372 | void ASTManager::Init() { |
| 373 | main_node = ASTBase::Make<ASTProgram>(ASTNode{}); | 373 | main_node = ASTBase::Make<ASTProgram>(ASTNode{}); |
| 374 | program = std::get_if<ASTProgram>(main_node->GetInnerData()); | 374 | program = std::get_if<ASTProgram>(main_node->GetInnerData()); |
| 375 | true_condition = MakeExpr<ExprBoolean>(true); | 375 | false_condition = MakeExpr<ExprBoolean>(false); |
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | ASTManager::ASTManager(ASTManager&& other) | 378 | ASTManager::ASTManager(ASTManager&& other) |
| 379 | : labels_map(std::move(other.labels_map)), labels_count{other.labels_count}, | 379 | : labels_map(std::move(other.labels_map)), labels_count{other.labels_count}, |
| 380 | gotos(std::move(other.gotos)), labels(std::move(other.labels)), variables{other.variables}, | 380 | gotos(std::move(other.gotos)), labels(std::move(other.labels)), variables{other.variables}, |
| 381 | program{other.program}, main_node{other.main_node}, true_condition{other.true_condition} { | 381 | program{other.program}, main_node{other.main_node}, false_condition{other.false_condition} { |
| 382 | other.main_node.reset(); | 382 | other.main_node.reset(); |
| 383 | } | 383 | } |
| 384 | 384 | ||
| @@ -390,7 +390,7 @@ ASTManager& ASTManager::operator=(ASTManager&& other) { | |||
| 390 | variables = other.variables; | 390 | variables = other.variables; |
| 391 | program = other.program; | 391 | program = other.program; |
| 392 | main_node = other.main_node; | 392 | main_node = other.main_node; |
| 393 | true_condition = other.true_condition; | 393 | false_condition = other.false_condition; |
| 394 | 394 | ||
| 395 | other.main_node.reset(); | 395 | other.main_node.reset(); |
| 396 | return *this; | 396 | return *this; |
| @@ -594,7 +594,7 @@ void ASTManager::MoveOutward(ASTNode goto_node) { | |||
| 594 | u32 var_index = NewVariable(); | 594 | u32 var_index = NewVariable(); |
| 595 | Expr var_condition = MakeExpr<ExprVar>(var_index); | 595 | Expr var_condition = MakeExpr<ExprVar>(var_index); |
| 596 | ASTNode var_node = ASTBase::Make<ASTVarSet>(parent, var_index, condition); | 596 | ASTNode var_node = ASTBase::Make<ASTVarSet>(parent, var_index, condition); |
| 597 | ASTNode var_node_init = ASTBase::Make<ASTVarSet>(parent, var_index, true_condition); | 597 | ASTNode var_node_init = ASTBase::Make<ASTVarSet>(parent, var_index, false_condition); |
| 598 | zipper2.InsertBefore(var_node_init, parent); | 598 | zipper2.InsertBefore(var_node_init, parent); |
| 599 | zipper.InsertAfter(var_node, prev); | 599 | zipper.InsertAfter(var_node, prev); |
| 600 | goto_node->SetGotoCondition(var_condition); | 600 | goto_node->SetGotoCondition(var_condition); |
| @@ -605,7 +605,7 @@ void ASTManager::MoveOutward(ASTNode goto_node) { | |||
| 605 | u32 var_index = NewVariable(); | 605 | u32 var_index = NewVariable(); |
| 606 | Expr var_condition = MakeExpr<ExprVar>(var_index); | 606 | Expr var_condition = MakeExpr<ExprVar>(var_index); |
| 607 | ASTNode var_node = ASTBase::Make<ASTVarSet>(parent, var_index, condition); | 607 | ASTNode var_node = ASTBase::Make<ASTVarSet>(parent, var_index, condition); |
| 608 | ASTNode var_node_init = ASTBase::Make<ASTVarSet>(parent, var_index, true_condition); | 608 | ASTNode var_node_init = ASTBase::Make<ASTVarSet>(parent, var_index, false_condition); |
| 609 | if (is_if) { | 609 | if (is_if) { |
| 610 | zipper2.InsertBefore(var_node_init, parent); | 610 | zipper2.InsertBefore(var_node_init, parent); |
| 611 | } else { | 611 | } else { |
diff --git a/src/video_core/shader/ast.h b/src/video_core/shader/ast.h index 958989bcd..06ab20cc5 100644 --- a/src/video_core/shader/ast.h +++ b/src/video_core/shader/ast.h | |||
| @@ -141,8 +141,6 @@ public: | |||
| 141 | Expr condition; | 141 | Expr condition; |
| 142 | }; | 142 | }; |
| 143 | 143 | ||
| 144 | using TransformCallback = std::function<NodeBlock(u32 start, u32 end)>; | ||
| 145 | |||
| 146 | class ASTBase { | 144 | class ASTBase { |
| 147 | public: | 145 | public: |
| 148 | explicit ASTBase(ASTNode parent, ASTData data) : parent{parent}, data{data} {} | 146 | explicit ASTBase(ASTNode parent, ASTData data) : parent{parent}, data{data} {} |
| @@ -233,11 +231,7 @@ public: | |||
| 233 | return std::holds_alternative<ASTBlockEncoded>(data); | 231 | return std::holds_alternative<ASTBlockEncoded>(data); |
| 234 | } | 232 | } |
| 235 | 233 | ||
| 236 | void TransformBlockEncoded(TransformCallback& callback) { | 234 | void TransformBlockEncoded(NodeBlock& nodes) { |
| 237 | auto block = std::get_if<ASTBlockEncoded>(&data); | ||
| 238 | const u32 start = block->start; | ||
| 239 | const u32 end = block->end; | ||
| 240 | NodeBlock nodes = callback(start, end); | ||
| 241 | data = ASTBlockDecoded(nodes); | 235 | data = ASTBlockDecoded(nodes); |
| 242 | } | 236 | } |
| 243 | 237 | ||
| @@ -309,16 +303,20 @@ public: | |||
| 309 | 303 | ||
| 310 | void SanityCheck(); | 304 | void SanityCheck(); |
| 311 | 305 | ||
| 312 | bool IsFullyDecompiled() { | 306 | bool IsFullyDecompiled() const { |
| 313 | return gotos.size() == 0; | 307 | return gotos.size() == 0; |
| 314 | } | 308 | } |
| 315 | 309 | ||
| 316 | ASTNode GetProgram() { | 310 | ASTNode GetProgram() const { |
| 317 | return main_node; | 311 | return main_node; |
| 318 | } | 312 | } |
| 319 | 313 | ||
| 320 | void Clear(); | 314 | void Clear(); |
| 321 | 315 | ||
| 316 | u32 GetVariables() const { | ||
| 317 | return variables; | ||
| 318 | } | ||
| 319 | |||
| 322 | private: | 320 | private: |
| 323 | bool IndirectlyRelated(ASTNode first, ASTNode second); | 321 | bool IndirectlyRelated(ASTNode first, ASTNode second); |
| 324 | 322 | ||
| @@ -343,7 +341,7 @@ private: | |||
| 343 | u32 variables{}; | 341 | u32 variables{}; |
| 344 | ASTProgram* program{}; | 342 | ASTProgram* program{}; |
| 345 | ASTNode main_node{}; | 343 | ASTNode main_node{}; |
| 346 | Expr true_condition{}; | 344 | Expr false_condition{}; |
| 347 | }; | 345 | }; |
| 348 | 346 | ||
| 349 | } // namespace VideoCommon::Shader | 347 | } // namespace VideoCommon::Shader |
diff --git a/src/video_core/shader/control_flow.cpp b/src/video_core/shader/control_flow.cpp index deb3d3ebd..a29922815 100644 --- a/src/video_core/shader/control_flow.cpp +++ b/src/video_core/shader/control_flow.cpp | |||
| @@ -425,7 +425,7 @@ void InsertBranch(ASTManager& mm, const BlockBranchInfo& branch) { | |||
| 425 | } | 425 | } |
| 426 | if (cond.predicate != Pred::UnusedIndex) { | 426 | if (cond.predicate != Pred::UnusedIndex) { |
| 427 | u32 pred = static_cast<u32>(cond.predicate); | 427 | u32 pred = static_cast<u32>(cond.predicate); |
| 428 | bool negate; | 428 | bool negate = false; |
| 429 | if (pred > 7) { | 429 | if (pred > 7) { |
| 430 | negate = true; | 430 | negate = true; |
| 431 | pred -= 8; | 431 | pred -= 8; |
diff --git a/src/video_core/shader/control_flow.h b/src/video_core/shader/control_flow.h index 2805d975c..347a35dcf 100644 --- a/src/video_core/shader/control_flow.h +++ b/src/video_core/shader/control_flow.h | |||
| @@ -74,6 +74,6 @@ struct ShaderCharacteristics { | |||
| 74 | }; | 74 | }; |
| 75 | 75 | ||
| 76 | std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 program_size, | 76 | std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 program_size, |
| 77 | u32 start_address, ASTManager& manager); | 77 | u32 start_address, ASTManager& manager); |
| 78 | 78 | ||
| 79 | } // namespace VideoCommon::Shader | 79 | } // namespace VideoCommon::Shader |
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp index 381e87415..e7e0903f6 100644 --- a/src/video_core/shader/decode.cpp +++ b/src/video_core/shader/decode.cpp | |||
| @@ -35,10 +35,73 @@ constexpr bool IsSchedInstruction(u32 offset, u32 main_offset) { | |||
| 35 | 35 | ||
| 36 | } // namespace | 36 | } // namespace |
| 37 | 37 | ||
| 38 | class ASTDecoder { | ||
| 39 | public: | ||
| 40 | ASTDecoder(ShaderIR& ir) : ir(ir) {} | ||
| 41 | |||
| 42 | void operator()(ASTProgram& ast) { | ||
| 43 | ASTNode current = ast.nodes.GetFirst(); | ||
| 44 | while (current) { | ||
| 45 | Visit(current); | ||
| 46 | current = current->GetNext(); | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | void operator()(ASTIfThen& ast) { | ||
| 51 | ASTNode current = ast.nodes.GetFirst(); | ||
| 52 | while (current) { | ||
| 53 | Visit(current); | ||
| 54 | current = current->GetNext(); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | void operator()(ASTIfElse& ast) { | ||
| 59 | ASTNode current = ast.nodes.GetFirst(); | ||
| 60 | while (current) { | ||
| 61 | Visit(current); | ||
| 62 | current = current->GetNext(); | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | void operator()(ASTBlockEncoded& ast) {} | ||
| 67 | |||
| 68 | void operator()(ASTBlockDecoded& ast) {} | ||
| 69 | |||
| 70 | void operator()(ASTVarSet& ast) {} | ||
| 71 | |||
| 72 | void operator()(ASTLabel& ast) {} | ||
| 73 | |||
| 74 | void operator()(ASTGoto& ast) {} | ||
| 75 | |||
| 76 | void operator()(ASTDoWhile& ast) { | ||
| 77 | ASTNode current = ast.nodes.GetFirst(); | ||
| 78 | while (current) { | ||
| 79 | Visit(current); | ||
| 80 | current = current->GetNext(); | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 84 | void operator()(ASTReturn& ast) {} | ||
| 85 | |||
| 86 | void operator()(ASTBreak& ast) {} | ||
| 87 | |||
| 88 | void Visit(ASTNode& node) { | ||
| 89 | std::visit(*this, *node->GetInnerData()); | ||
| 90 | if (node->IsBlockEncoded()) { | ||
| 91 | auto block = std::get_if<ASTBlockEncoded>(node->GetInnerData()); | ||
| 92 | NodeBlock bb = ir.DecodeRange(block->start, block->end); | ||
| 93 | node->TransformBlockEncoded(bb); | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | private: | ||
| 98 | ShaderIR& ir; | ||
| 99 | }; | ||
| 100 | |||
| 38 | void ShaderIR::Decode() { | 101 | void ShaderIR::Decode() { |
| 39 | std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); | 102 | std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); |
| 40 | 103 | ||
| 41 | disable_flow_stack = false; | 104 | decompiled = false; |
| 42 | const auto info = | 105 | const auto info = |
| 43 | ScanFlow(program_code, program_size, main_offset, program_manager); | 106 | ScanFlow(program_code, program_size, main_offset, program_manager); |
| 44 | if (info) { | 107 | if (info) { |
| @@ -46,7 +109,10 @@ void ShaderIR::Decode() { | |||
| 46 | coverage_begin = shader_info.start; | 109 | coverage_begin = shader_info.start; |
| 47 | coverage_end = shader_info.end; | 110 | coverage_end = shader_info.end; |
| 48 | if (shader_info.decompiled) { | 111 | if (shader_info.decompiled) { |
| 49 | disable_flow_stack = true; | 112 | decompiled = true; |
| 113 | ASTDecoder decoder{*this}; | ||
| 114 | ASTNode program = GetASTProgram(); | ||
| 115 | decoder.Visit(program); | ||
| 50 | return; | 116 | return; |
| 51 | } | 117 | } |
| 52 | LOG_WARNING(HW_GPU, "Flow Stack Removing Failed! Falling back to old method"); | 118 | LOG_WARNING(HW_GPU, "Flow Stack Removing Failed! Falling back to old method"); |
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp index d46e0f823..6f678003c 100644 --- a/src/video_core/shader/decode/other.cpp +++ b/src/video_core/shader/decode/other.cpp | |||
| @@ -157,7 +157,7 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { | |||
| 157 | UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, | 157 | UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, |
| 158 | "Constant buffer flow is not supported"); | 158 | "Constant buffer flow is not supported"); |
| 159 | 159 | ||
| 160 | if (disable_flow_stack) { | 160 | if (decompiled) { |
| 161 | break; | 161 | break; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| @@ -171,7 +171,7 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { | |||
| 171 | UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, | 171 | UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, |
| 172 | "Constant buffer PBK is not supported"); | 172 | "Constant buffer PBK is not supported"); |
| 173 | 173 | ||
| 174 | if (disable_flow_stack) { | 174 | if (decompiled) { |
| 175 | break; | 175 | break; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| @@ -186,7 +186,7 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { | |||
| 186 | UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, "SYNC condition code used: {}", | 186 | UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, "SYNC condition code used: {}", |
| 187 | static_cast<u32>(cc)); | 187 | static_cast<u32>(cc)); |
| 188 | 188 | ||
| 189 | if (disable_flow_stack) { | 189 | if (decompiled) { |
| 190 | break; | 190 | break; |
| 191 | } | 191 | } |
| 192 | 192 | ||
| @@ -198,7 +198,7 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { | |||
| 198 | const Tegra::Shader::ConditionCode cc = instr.flow_condition_code; | 198 | const Tegra::Shader::ConditionCode cc = instr.flow_condition_code; |
| 199 | UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, "BRK condition code used: {}", | 199 | UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, "BRK condition code used: {}", |
| 200 | static_cast<u32>(cc)); | 200 | static_cast<u32>(cc)); |
| 201 | if (disable_flow_stack) { | 201 | if (decompiled) { |
| 202 | break; | 202 | break; |
| 203 | } | 203 | } |
| 204 | 204 | ||
diff --git a/src/video_core/shader/expr.cpp b/src/video_core/shader/expr.cpp index ebce6339b..ca633ffb1 100644 --- a/src/video_core/shader/expr.cpp +++ b/src/video_core/shader/expr.cpp | |||
| @@ -72,4 +72,11 @@ bool ExprAreOpposite(Expr first, Expr second) { | |||
| 72 | return false; | 72 | return false; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | bool ExprIsTrue(Expr first) { | ||
| 76 | if (ExprIsBoolean(first)) { | ||
| 77 | return ExprBooleanGet(first); | ||
| 78 | } | ||
| 79 | return false; | ||
| 80 | } | ||
| 81 | |||
| 75 | } // namespace VideoCommon::Shader | 82 | } // namespace VideoCommon::Shader |
diff --git a/src/video_core/shader/expr.h b/src/video_core/shader/expr.h index f012f6fcf..b954cffb0 100644 --- a/src/video_core/shader/expr.h +++ b/src/video_core/shader/expr.h | |||
| @@ -115,4 +115,6 @@ Expr MakeExprAnd(Expr first, Expr second); | |||
| 115 | 115 | ||
| 116 | Expr MakeExprOr(Expr first, Expr second); | 116 | Expr MakeExprOr(Expr first, Expr second); |
| 117 | 117 | ||
| 118 | bool ExprIsTrue(Expr first); | ||
| 119 | |||
| 118 | } // namespace VideoCommon::Shader | 120 | } // namespace VideoCommon::Shader |
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index c79f80e04..004b1e16f 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp | |||
| @@ -137,7 +137,7 @@ Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buff | |||
| 137 | return MakeNode<AbufNode>(index, static_cast<u32>(element), std::move(buffer)); | 137 | return MakeNode<AbufNode>(index, static_cast<u32>(element), std::move(buffer)); |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | Node ShaderIR::GetInternalFlag(InternalFlag flag, bool negated) { | 140 | Node ShaderIR::GetInternalFlag(InternalFlag flag, bool negated) const { |
| 141 | const Node node = MakeNode<InternalFlagNode>(flag); | 141 | const Node node = MakeNode<InternalFlagNode>(flag); |
| 142 | if (negated) { | 142 | if (negated) { |
| 143 | return Operation(OperationCode::LogicalNegate, node); | 143 | return Operation(OperationCode::LogicalNegate, node); |
| @@ -367,13 +367,13 @@ OperationCode ShaderIR::GetPredicateCombiner(PredOperation operation) { | |||
| 367 | return op->second; | 367 | return op->second; |
| 368 | } | 368 | } |
| 369 | 369 | ||
| 370 | Node ShaderIR::GetConditionCode(Tegra::Shader::ConditionCode cc) { | 370 | Node ShaderIR::GetConditionCode(Tegra::Shader::ConditionCode cc) const { |
| 371 | switch (cc) { | 371 | switch (cc) { |
| 372 | case Tegra::Shader::ConditionCode::NEU: | 372 | case Tegra::Shader::ConditionCode::NEU: |
| 373 | return GetInternalFlag(InternalFlag::Zero, true); | 373 | return GetInternalFlag(InternalFlag::Zero, true); |
| 374 | default: | 374 | default: |
| 375 | UNIMPLEMENTED_MSG("Unimplemented condition code: {}", static_cast<u32>(cc)); | 375 | UNIMPLEMENTED_MSG("Unimplemented condition code: {}", static_cast<u32>(cc)); |
| 376 | return GetPredicate(static_cast<u64>(Pred::NeverExecute)); | 376 | return MakeNode<PredicateNode>(Pred::NeverExecute, false); |
| 377 | } | 377 | } |
| 378 | } | 378 | } |
| 379 | 379 | ||
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index a91cd7d67..48c7b722e 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -15,8 +15,8 @@ | |||
| 15 | #include "video_core/engines/maxwell_3d.h" | 15 | #include "video_core/engines/maxwell_3d.h" |
| 16 | #include "video_core/engines/shader_bytecode.h" | 16 | #include "video_core/engines/shader_bytecode.h" |
| 17 | #include "video_core/engines/shader_header.h" | 17 | #include "video_core/engines/shader_header.h" |
| 18 | #include "video_core/shader/node.h" | ||
| 19 | #include "video_core/shader/ast.h" | 18 | #include "video_core/shader/ast.h" |
| 19 | #include "video_core/shader/node.h" | ||
| 20 | 20 | ||
| 21 | namespace VideoCommon::Shader { | 21 | namespace VideoCommon::Shader { |
| 22 | 22 | ||
| @@ -141,15 +141,27 @@ public: | |||
| 141 | return header; | 141 | return header; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | bool IsFlowStackDisabled() const { | 144 | bool IsDecompiled() const { |
| 145 | return disable_flow_stack; | 145 | return decompiled; |
| 146 | } | ||
| 147 | |||
| 148 | ASTNode GetASTProgram() const { | ||
| 149 | return program_manager.GetProgram(); | ||
| 150 | } | ||
| 151 | |||
| 152 | u32 GetASTNumVariables() const { | ||
| 153 | return program_manager.GetVariables(); | ||
| 146 | } | 154 | } |
| 147 | 155 | ||
| 148 | u32 ConvertAddressToNvidiaSpace(const u32 address) const { | 156 | u32 ConvertAddressToNvidiaSpace(const u32 address) const { |
| 149 | return (address - main_offset) * sizeof(Tegra::Shader::Instruction); | 157 | return (address - main_offset) * sizeof(Tegra::Shader::Instruction); |
| 150 | } | 158 | } |
| 151 | 159 | ||
| 160 | /// Returns a condition code evaluated from internal flags | ||
| 161 | Node GetConditionCode(Tegra::Shader::ConditionCode cc) const; | ||
| 162 | |||
| 152 | private: | 163 | private: |
| 164 | friend class ASTDecoder; | ||
| 153 | void Decode(); | 165 | void Decode(); |
| 154 | 166 | ||
| 155 | NodeBlock DecodeRange(u32 begin, u32 end); | 167 | NodeBlock DecodeRange(u32 begin, u32 end); |
| @@ -214,7 +226,7 @@ private: | |||
| 214 | /// Generates a node representing an output attribute. Keeps track of used attributes. | 226 | /// Generates a node representing an output attribute. Keeps track of used attributes. |
| 215 | Node GetOutputAttribute(Tegra::Shader::Attribute::Index index, u64 element, Node buffer); | 227 | Node GetOutputAttribute(Tegra::Shader::Attribute::Index index, u64 element, Node buffer); |
| 216 | /// Generates a node representing an internal flag | 228 | /// Generates a node representing an internal flag |
| 217 | Node GetInternalFlag(InternalFlag flag, bool negated = false); | 229 | Node GetInternalFlag(InternalFlag flag, bool negated = false) const; |
| 218 | /// Generates a node representing a local memory address | 230 | /// Generates a node representing a local memory address |
| 219 | Node GetLocalMemory(Node address); | 231 | Node GetLocalMemory(Node address); |
| 220 | /// Generates a node representing a shared memory address | 232 | /// Generates a node representing a shared memory address |
| @@ -272,9 +284,6 @@ private: | |||
| 272 | /// Returns a predicate combiner operation | 284 | /// Returns a predicate combiner operation |
| 273 | OperationCode GetPredicateCombiner(Tegra::Shader::PredOperation operation); | 285 | OperationCode GetPredicateCombiner(Tegra::Shader::PredOperation operation); |
| 274 | 286 | ||
| 275 | /// Returns a condition code evaluated from internal flags | ||
| 276 | Node GetConditionCode(Tegra::Shader::ConditionCode cc); | ||
| 277 | |||
| 278 | /// Accesses a texture sampler | 287 | /// Accesses a texture sampler |
| 279 | const Sampler& GetSampler(const Tegra::Shader::Sampler& sampler, | 288 | const Sampler& GetSampler(const Tegra::Shader::Sampler& sampler, |
| 280 | Tegra::Shader::TextureType type, bool is_array, bool is_shadow); | 289 | Tegra::Shader::TextureType type, bool is_array, bool is_shadow); |
| @@ -358,7 +367,7 @@ private: | |||
| 358 | const ProgramCode& program_code; | 367 | const ProgramCode& program_code; |
| 359 | const u32 main_offset; | 368 | const u32 main_offset; |
| 360 | const std::size_t program_size; | 369 | const std::size_t program_size; |
| 361 | bool disable_flow_stack{}; | 370 | bool decompiled{}; |
| 362 | 371 | ||
| 363 | u32 coverage_begin{}; | 372 | u32 coverage_begin{}; |
| 364 | u32 coverage_end{}; | 373 | u32 coverage_end{}; |