diff options
| author | 2021-03-09 17:14:57 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:23 -0400 | |
| commit | 3a63fa0477ea8297c80133d35494e1dfdc012f95 (patch) | |
| tree | 3cd8b9be6f91cb1628b0d47513b7adb88df5f7b2 /src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | |
| parent | shader: Initial support for textures and TEX (diff) | |
| download | yuzu-3a63fa0477ea8297c80133d35494e1dfdc012f95.tar.gz yuzu-3a63fa0477ea8297c80133d35494e1dfdc012f95.tar.xz yuzu-3a63fa0477ea8297c80133d35494e1dfdc012f95.zip | |
shader: Partial implementation of LDC
Diffstat (limited to 'src/shader_recompiler/ir_opt/constant_propagation_pass.cpp')
| -rw-r--r-- | src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp index ae3d5a7d6..7ba9ebe9b 100644 --- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp +++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | |||
| @@ -193,7 +193,7 @@ void FoldISub32(IR::Inst& inst) { | |||
| 193 | // ISub32 is generally used to subtract two constant buffers, compare and replace this with | 193 | // ISub32 is generally used to subtract two constant buffers, compare and replace this with |
| 194 | // zero if they equal. | 194 | // zero if they equal. |
| 195 | const auto equal_cbuf{[](IR::Inst* a, IR::Inst* b) { | 195 | const auto equal_cbuf{[](IR::Inst* a, IR::Inst* b) { |
| 196 | return a->Opcode() == IR::Opcode::GetCbuf && b->Opcode() == IR::Opcode::GetCbuf && | 196 | return a->Opcode() == IR::Opcode::GetCbufU32 && b->Opcode() == IR::Opcode::GetCbufU32 && |
| 197 | a->Arg(0) == b->Arg(0) && a->Arg(1) == b->Arg(1); | 197 | a->Arg(0) == b->Arg(0) && a->Arg(1) == b->Arg(1); |
| 198 | }}; | 198 | }}; |
| 199 | IR::Inst* op_a{inst.Arg(0).InstRecursive()}; | 199 | IR::Inst* op_a{inst.Arg(0).InstRecursive()}; |
| @@ -207,7 +207,7 @@ void FoldISub32(IR::Inst& inst) { | |||
| 207 | // Canonicalize local variables to simplify the following logic | 207 | // Canonicalize local variables to simplify the following logic |
| 208 | std::swap(op_a, op_b); | 208 | std::swap(op_a, op_b); |
| 209 | } | 209 | } |
| 210 | if (op_b->Opcode() != IR::Opcode::GetCbuf) { | 210 | if (op_b->Opcode() != IR::Opcode::GetCbufU32) { |
| 211 | return; | 211 | return; |
| 212 | } | 212 | } |
| 213 | IR::Inst* const inst_cbuf{op_b}; | 213 | IR::Inst* const inst_cbuf{op_b}; |
| @@ -277,7 +277,7 @@ void FoldLogicalNot(IR::Inst& inst) { | |||
| 277 | } | 277 | } |
| 278 | } | 278 | } |
| 279 | 279 | ||
| 280 | template <typename Dest, typename Source> | 280 | template <IR::Opcode op, typename Dest, typename Source> |
| 281 | void FoldBitCast(IR::Inst& inst, IR::Opcode reverse) { | 281 | void FoldBitCast(IR::Inst& inst, IR::Opcode reverse) { |
| 282 | const IR::Value value{inst.Arg(0)}; | 282 | const IR::Value value{inst.Arg(0)}; |
| 283 | if (value.IsImmediate()) { | 283 | if (value.IsImmediate()) { |
| @@ -285,8 +285,18 @@ void FoldBitCast(IR::Inst& inst, IR::Opcode reverse) { | |||
| 285 | return; | 285 | return; |
| 286 | } | 286 | } |
| 287 | IR::Inst* const arg_inst{value.InstRecursive()}; | 287 | IR::Inst* const arg_inst{value.InstRecursive()}; |
| 288 | if (value.InstRecursive()->Opcode() == reverse) { | 288 | if (arg_inst->Opcode() == reverse) { |
| 289 | inst.ReplaceUsesWith(arg_inst->Arg(0)); | 289 | inst.ReplaceUsesWith(arg_inst->Arg(0)); |
| 290 | return; | ||
| 291 | } | ||
| 292 | if constexpr (op == IR::Opcode::BitCastF32U32) { | ||
| 293 | if (arg_inst->Opcode() == IR::Opcode::GetCbufU32) { | ||
| 294 | // Replace the bitcast with a typed constant buffer read | ||
| 295 | inst.ReplaceOpcode(IR::Opcode::GetCbufF32); | ||
| 296 | inst.SetArg(0, arg_inst->Arg(0)); | ||
| 297 | inst.SetArg(1, arg_inst->Arg(1)); | ||
| 298 | return; | ||
| 299 | } | ||
| 290 | } | 300 | } |
| 291 | } | 301 | } |
| 292 | 302 | ||
| @@ -325,9 +335,9 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) { | |||
| 325 | case IR::Opcode::ISub32: | 335 | case IR::Opcode::ISub32: |
| 326 | return FoldISub32(inst); | 336 | return FoldISub32(inst); |
| 327 | case IR::Opcode::BitCastF32U32: | 337 | case IR::Opcode::BitCastF32U32: |
| 328 | return FoldBitCast<f32, u32>(inst, IR::Opcode::BitCastU32F32); | 338 | return FoldBitCast<IR::Opcode::BitCastF32U32, f32, u32>(inst, IR::Opcode::BitCastU32F32); |
| 329 | case IR::Opcode::BitCastU32F32: | 339 | case IR::Opcode::BitCastU32F32: |
| 330 | return FoldBitCast<u32, f32>(inst, IR::Opcode::BitCastF32U32); | 340 | return FoldBitCast<IR::Opcode::BitCastU32F32, u32, f32>(inst, IR::Opcode::BitCastF32U32); |
| 331 | case IR::Opcode::IAdd64: | 341 | case IR::Opcode::IAdd64: |
| 332 | return FoldAdd<u64>(block, inst); | 342 | return FoldAdd<u64>(block, inst); |
| 333 | case IR::Opcode::SelectU32: | 343 | case IR::Opcode::SelectU32: |