summaryrefslogtreecommitdiff
path: root/src/video_core/shader/ast.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/shader/ast.cpp')
-rw-r--r--src/video_core/shader/ast.cpp139
1 files changed, 136 insertions, 3 deletions
diff --git a/src/video_core/shader/ast.cpp b/src/video_core/shader/ast.cpp
index d521a7b52..0bf289f98 100644
--- a/src/video_core/shader/ast.cpp
+++ b/src/video_core/shader/ast.cpp
@@ -363,6 +363,71 @@ std::string ASTManager::Print() {
363 return printer.GetResult(); 363 return printer.GetResult();
364} 364}
365 365
366ASTManager::ASTManager() = default;
367
368ASTManager::~ASTManager() {
369 Clear();
370}
371
372void ASTManager::Init() {
373 main_node = ASTBase::Make<ASTProgram>(ASTNode{});
374 program = std::get_if<ASTProgram>(main_node->GetInnerData());
375 true_condition = MakeExpr<ExprBoolean>(true);
376}
377
378ASTManager::ASTManager(ASTManager&& other)
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},
381 program{other.program}, main_node{other.main_node}, true_condition{other.true_condition} {
382 other.main_node.reset();
383}
384
385ASTManager& ASTManager::operator=(ASTManager&& other) {
386 labels_map = std::move(other.labels_map);
387 labels_count = other.labels_count;
388 gotos = std::move(other.gotos);
389 labels = std::move(other.labels);
390 variables = other.variables;
391 program = other.program;
392 main_node = other.main_node;
393 true_condition = other.true_condition;
394
395 other.main_node.reset();
396 return *this;
397}
398
399void ASTManager::DeclareLabel(u32 address) {
400 const auto pair = labels_map.emplace(address, labels_count);
401 if (pair.second) {
402 labels_count++;
403 labels.resize(labels_count);
404 }
405}
406
407void ASTManager::InsertLabel(u32 address) {
408 u32 index = labels_map[address];
409 ASTNode label = ASTBase::Make<ASTLabel>(main_node, index);
410 labels[index] = label;
411 program->nodes.PushBack(label);
412}
413
414void ASTManager::InsertGoto(Expr condition, u32 address) {
415 u32 index = labels_map[address];
416 ASTNode goto_node = ASTBase::Make<ASTGoto>(main_node, condition, index);
417 gotos.push_back(goto_node);
418 program->nodes.PushBack(goto_node);
419}
420
421void ASTManager::InsertBlock(u32 start_address, u32 end_address) {
422 ASTNode block = ASTBase::Make<ASTBlockEncoded>(main_node, start_address, end_address);
423 program->nodes.PushBack(block);
424}
425
426void ASTManager::InsertReturn(Expr condition, bool kills) {
427 ASTNode node = ASTBase::Make<ASTReturn>(main_node, condition, kills);
428 program->nodes.PushBack(node);
429}
430
366void ASTManager::Decompile() { 431void ASTManager::Decompile() {
367 auto it = gotos.begin(); 432 auto it = gotos.begin();
368 while (it != gotos.end()) { 433 while (it != gotos.end()) {
@@ -460,7 +525,6 @@ void ASTManager::SanityCheck() {
460 525
461void ASTManager::EncloseDoWhile(ASTNode goto_node, ASTNode label) { 526void ASTManager::EncloseDoWhile(ASTNode goto_node, ASTNode label) {
462 // ShowCurrentState("Before DoWhile Enclose"); 527 // ShowCurrentState("Before DoWhile Enclose");
463 enclose_count++;
464 ASTZipper& zipper = goto_node->GetManager(); 528 ASTZipper& zipper = goto_node->GetManager();
465 ASTNode loop_start = label->GetNext(); 529 ASTNode loop_start = label->GetNext();
466 if (loop_start == goto_node) { 530 if (loop_start == goto_node) {
@@ -481,7 +545,6 @@ void ASTManager::EncloseDoWhile(ASTNode goto_node, ASTNode label) {
481 545
482void ASTManager::EncloseIfThen(ASTNode goto_node, ASTNode label) { 546void ASTManager::EncloseIfThen(ASTNode goto_node, ASTNode label) {
483 // ShowCurrentState("Before IfThen Enclose"); 547 // ShowCurrentState("Before IfThen Enclose");
484 enclose_count++;
485 ASTZipper& zipper = goto_node->GetManager(); 548 ASTZipper& zipper = goto_node->GetManager();
486 ASTNode if_end = label->GetPrevious(); 549 ASTNode if_end = label->GetPrevious();
487 if (if_end == goto_node) { 550 if (if_end == goto_node) {
@@ -514,7 +577,6 @@ void ASTManager::EncloseIfThen(ASTNode goto_node, ASTNode label) {
514 577
515void ASTManager::MoveOutward(ASTNode goto_node) { 578void ASTManager::MoveOutward(ASTNode goto_node) {
516 // ShowCurrentState("Before MoveOutward"); 579 // ShowCurrentState("Before MoveOutward");
517 outward_count++;
518 ASTZipper& zipper = goto_node->GetManager(); 580 ASTZipper& zipper = goto_node->GetManager();
519 ASTNode parent = goto_node->GetParent(); 581 ASTNode parent = goto_node->GetParent();
520 ASTZipper& zipper2 = parent->GetManager(); 582 ASTZipper& zipper2 = parent->GetManager();
@@ -582,4 +644,75 @@ void ASTManager::MoveOutward(ASTNode goto_node) {
582 // ShowCurrentState("After MoveOutward"); 644 // ShowCurrentState("After MoveOutward");
583} 645}
584 646
647class ASTClearer {
648public:
649 ASTClearer() = default;
650
651 void operator()(ASTProgram& ast) {
652 ASTNode current = ast.nodes.GetFirst();
653 while (current) {
654 Visit(current);
655 current = current->GetNext();
656 }
657 }
658
659 void operator()(ASTIfThen& ast) {
660 ASTNode current = ast.nodes.GetFirst();
661 while (current) {
662 Visit(current);
663 current = current->GetNext();
664 }
665 }
666
667 void operator()(ASTIfElse& ast) {
668 ASTNode current = ast.nodes.GetFirst();
669 while (current) {
670 Visit(current);
671 current = current->GetNext();
672 }
673 }
674
675 void operator()(ASTBlockEncoded& ast) {}
676
677 void operator()(ASTBlockDecoded& ast) {
678 ast.nodes.clear();
679 }
680
681 void operator()(ASTVarSet& ast) {}
682
683 void operator()(ASTLabel& ast) {}
684
685 void operator()(ASTGoto& ast) {}
686
687 void operator()(ASTDoWhile& ast) {
688 ASTNode current = ast.nodes.GetFirst();
689 while (current) {
690 Visit(current);
691 current = current->GetNext();
692 }
693 }
694
695 void operator()(ASTReturn& ast) {}
696
697 void operator()(ASTBreak& ast) {}
698
699 void Visit(ASTNode& node) {
700 std::visit(*this, *node->GetInnerData());
701 node->Clear();
702 }
703};
704
705void ASTManager::Clear() {
706 if (!main_node) {
707 return;
708 }
709 ASTClearer clearer{};
710 clearer.Visit(main_node);
711 main_node.reset();
712 program = nullptr;
713 labels_map.clear();
714 labels.clear();
715 gotos.clear();
716}
717
585} // namespace VideoCommon::Shader 718} // namespace VideoCommon::Shader