summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
diff options
context:
space:
mode:
authorGravatar FernandoS272021-04-17 11:56:45 +0200
committerGravatar ameerj2021-07-22 21:51:28 -0400
commit04c459fc8d99b41fa8a03c49523599e9bf797f9d (patch)
tree199934b3ef85a5affbe9ef115e9b0a1085851b36 /src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
parentshader: Implement SR_Y_DIRECTION (diff)
downloadyuzu-04c459fc8d99b41fa8a03c49523599e9bf797f9d.tar.gz
yuzu-04c459fc8d99b41fa8a03c49523599e9bf797f9d.tar.xz
yuzu-04c459fc8d99b41fa8a03c49523599e9bf797f9d.zip
shader: Implement fine derivates constant propagation
Diffstat (limited to 'src/shader_recompiler/ir_opt/constant_propagation_pass.cpp')
-rw-r--r--src/shader_recompiler/ir_opt/constant_propagation_pass.cpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
index ee73b5b60..983fb20ab 100644
--- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
+++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
@@ -412,6 +412,71 @@ void FoldCompositeExtract(IR::Inst& inst, IR::Opcode construct, IR::Opcode inser
412 inst.ReplaceUsesWith(*result); 412 inst.ReplaceUsesWith(*result);
413} 413}
414 414
415IR::Value GetThroughCast(IR::Value value, IR::Opcode expected_cast) {
416 if (value.IsImmediate()) {
417 return value;
418 }
419 IR::Inst* const inst{value.InstRecursive()};
420 if (inst->GetOpcode() == expected_cast) {
421 return inst->Arg(0).Resolve();
422 }
423 return value;
424}
425
426void FoldFSwizzleAdd(IR::Block& block, IR::Inst& inst) {
427 const IR::Value swizzle{inst.Arg(2)};
428 if (!swizzle.IsImmediate()) {
429 return;
430 }
431
432 const IR::Value value_1{GetThroughCast(inst.Arg(0).Resolve(), IR::Opcode::BitCastF32U32)};
433 const IR::Value value_2{GetThroughCast(inst.Arg(1).Resolve(), IR::Opcode::BitCastF32U32)};
434
435 if (value_1.IsImmediate()) {
436 return;
437 }
438
439 const u32 swizzle_value{swizzle.U32()};
440 if (swizzle_value != 0x99 && swizzle_value != 0xA5) {
441 return;
442 }
443
444 IR::Inst* const inst2{value_1.InstRecursive()};
445 if (inst2->GetOpcode() != IR::Opcode::ShuffleButterfly) {
446 return;
447 }
448 const IR::Value value_3{GetThroughCast(inst2->Arg(0).Resolve(), IR::Opcode::BitCastU32F32)};
449 if (value_2 != value_3) {
450 return;
451 }
452
453 const IR::Value index{inst2->Arg(1)};
454 const IR::Value clamp{inst2->Arg(2)};
455 const IR::Value segmentation_mask{inst2->Arg(3)};
456
457 if (!index.IsImmediate() || !clamp.IsImmediate() || !segmentation_mask.IsImmediate()) {
458 return;
459 }
460
461 if (clamp.U32() != 3 || segmentation_mask.U32() != 28) {
462 return;
463 }
464
465 if (swizzle_value == 0x99) {
466 // DPdxFine
467 if (index.U32() == 1) {
468 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
469 inst.ReplaceUsesWith(ir.DPdxFine(IR::F32{value_2}));
470 }
471 } else if (swizzle_value == 0xA5) {
472 // DPdyFine
473 if (index.U32() == 2) {
474 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
475 inst.ReplaceUsesWith(ir.DPdyFine(IR::F32{value_2}));
476 }
477 }
478}
479
415void ConstantPropagation(IR::Block& block, IR::Inst& inst) { 480void ConstantPropagation(IR::Block& block, IR::Inst& inst) {
416 switch (inst.GetOpcode()) { 481 switch (inst.GetOpcode()) {
417 case IR::Opcode::GetRegister: 482 case IR::Opcode::GetRegister:
@@ -532,6 +597,8 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) {
532 case IR::Opcode::CompositeExtractF16x4: 597 case IR::Opcode::CompositeExtractF16x4:
533 return FoldCompositeExtract(inst, IR::Opcode::CompositeConstructF16x4, 598 return FoldCompositeExtract(inst, IR::Opcode::CompositeConstructF16x4,
534 IR::Opcode::CompositeInsertF16x4); 599 IR::Opcode::CompositeInsertF16x4);
600 case IR::Opcode::FSwizzleAdd:
601 return FoldFSwizzleAdd(block, inst);
535 default: 602 default:
536 break; 603 break;
537 } 604 }