summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/ir_opt/constant_propagation_pass.cpp')
-rw-r--r--src/shader_recompiler/ir_opt/constant_propagation_pass.cpp76
1 files changed, 73 insertions, 3 deletions
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
index 826f9a54a..4d81e9336 100644
--- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
+++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
@@ -7,6 +7,7 @@
7#include <type_traits> 7#include <type_traits>
8 8
9#include "common/bit_cast.h" 9#include "common/bit_cast.h"
10#include "shader_recompiler/environment.h"
10#include "shader_recompiler/exception.h" 11#include "shader_recompiler/exception.h"
11#include "shader_recompiler/frontend/ir/ir_emitter.h" 12#include "shader_recompiler/frontend/ir/ir_emitter.h"
12#include "shader_recompiler/frontend/ir/value.h" 13#include "shader_recompiler/frontend/ir/value.h"
@@ -515,6 +516,9 @@ void FoldBitCast(IR::Inst& inst, IR::Opcode reverse) {
515 case IR::Attribute::PrimitiveId: 516 case IR::Attribute::PrimitiveId:
516 case IR::Attribute::InstanceId: 517 case IR::Attribute::InstanceId:
517 case IR::Attribute::VertexId: 518 case IR::Attribute::VertexId:
519 case IR::Attribute::BaseVertex:
520 case IR::Attribute::BaseInstance:
521 case IR::Attribute::DrawID:
518 break; 522 break;
519 default: 523 default:
520 return; 524 return;
@@ -644,7 +648,63 @@ void FoldFSwizzleAdd(IR::Block& block, IR::Inst& inst) {
644 } 648 }
645} 649}
646 650
647void ConstantPropagation(IR::Block& block, IR::Inst& inst) { 651void FoldConstBuffer(Environment& env, IR::Block& block, IR::Inst& inst) {
652 const IR::Value bank{inst.Arg(0)};
653 const IR::Value offset{inst.Arg(1)};
654 if (!bank.IsImmediate() || !offset.IsImmediate()) {
655 return;
656 }
657 const auto bank_value = bank.U32();
658 const auto offset_value = offset.U32();
659 auto replacement = env.GetReplaceConstBuffer(bank_value, offset_value);
660 if (!replacement) {
661 return;
662 }
663 const auto new_attribute = [replacement]() {
664 switch (*replacement) {
665 case ReplaceConstant::BaseInstance:
666 return IR::Attribute::BaseInstance;
667 case ReplaceConstant::BaseVertex:
668 return IR::Attribute::BaseVertex;
669 case ReplaceConstant::DrawID:
670 return IR::Attribute::DrawID;
671 default:
672 throw NotImplementedException("Not implemented replacement variable {}", *replacement);
673 }
674 }();
675 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
676 if (inst.GetOpcode() == IR::Opcode::GetCbufU32) {
677 inst.ReplaceUsesWith(ir.GetAttributeU32(new_attribute));
678 } else {
679 inst.ReplaceUsesWith(ir.GetAttribute(new_attribute));
680 }
681}
682
683void FoldDriverConstBuffer(Environment& env, IR::Block& block, IR::Inst& inst, u32 which_bank,
684 u32 offset_start = 0, u32 offset_end = std::numeric_limits<u16>::max()) {
685 const IR::Value bank{inst.Arg(0)};
686 const IR::Value offset{inst.Arg(1)};
687 if (!bank.IsImmediate() || !offset.IsImmediate()) {
688 return;
689 }
690 const auto bank_value = bank.U32();
691 if (bank_value != which_bank) {
692 return;
693 }
694 const auto offset_value = offset.U32();
695 if (offset_value < offset_start || offset_value >= offset_end) {
696 return;
697 }
698 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
699 if (inst.GetOpcode() == IR::Opcode::GetCbufU32) {
700 inst.ReplaceUsesWith(IR::Value{env.ReadCbufValue(bank_value, offset_value)});
701 } else {
702 inst.ReplaceUsesWith(
703 IR::Value{Common::BitCast<f32>(env.ReadCbufValue(bank_value, offset_value))});
704 }
705}
706
707void ConstantPropagation(Environment& env, IR::Block& block, IR::Inst& inst) {
648 switch (inst.GetOpcode()) { 708 switch (inst.GetOpcode()) {
649 case IR::Opcode::GetRegister: 709 case IR::Opcode::GetRegister:
650 return FoldGetRegister(inst); 710 return FoldGetRegister(inst);
@@ -789,18 +849,28 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) {
789 IR::Opcode::CompositeInsertF16x4); 849 IR::Opcode::CompositeInsertF16x4);
790 case IR::Opcode::FSwizzleAdd: 850 case IR::Opcode::FSwizzleAdd:
791 return FoldFSwizzleAdd(block, inst); 851 return FoldFSwizzleAdd(block, inst);
852 case IR::Opcode::GetCbufF32:
853 case IR::Opcode::GetCbufU32:
854 if (env.HasHLEMacroState()) {
855 FoldConstBuffer(env, block, inst);
856 }
857 if (env.IsPropietaryDriver()) {
858 FoldDriverConstBuffer(env, block, inst, 1);
859 }
860 break;
792 default: 861 default:
793 break; 862 break;
794 } 863 }
795} 864}
865
796} // Anonymous namespace 866} // Anonymous namespace
797 867
798void ConstantPropagationPass(IR::Program& program) { 868void ConstantPropagationPass(Environment& env, IR::Program& program) {
799 const auto end{program.post_order_blocks.rend()}; 869 const auto end{program.post_order_blocks.rend()};
800 for (auto it = program.post_order_blocks.rbegin(); it != end; ++it) { 870 for (auto it = program.post_order_blocks.rbegin(); it != end; ++it) {
801 IR::Block* const block{*it}; 871 IR::Block* const block{*it};
802 for (IR::Inst& inst : block->Instructions()) { 872 for (IR::Inst& inst : block->Instructions()) {
803 ConstantPropagation(*block, inst); 873 ConstantPropagation(env, *block, inst);
804 } 874 }
805 } 875 }
806} 876}