diff options
| author | 2019-03-14 02:44:23 -0300 | |
|---|---|---|
| committer | 2019-04-10 14:20:25 -0300 | |
| commit | 676172e20d0a0c2f92ace94ca7cfb37a862fd8dc (patch) | |
| tree | 342bcc869f6bfa009634bc8876b3147ee7c50113 /src | |
| parent | vk_shader_decompiler: Implement non-OperationCode visits (diff) | |
| download | yuzu-676172e20d0a0c2f92ace94ca7cfb37a862fd8dc.tar.gz yuzu-676172e20d0a0c2f92ace94ca7cfb37a862fd8dc.tar.xz yuzu-676172e20d0a0c2f92ace94ca7cfb37a862fd8dc.zip | |
vk_shader_decompiler: Implement Assign and LogicalAssign
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 5060dbba9..9f717b836 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -693,7 +693,49 @@ private: | |||
| 693 | } | 693 | } |
| 694 | 694 | ||
| 695 | Id Assign(Operation operation) { | 695 | Id Assign(Operation operation) { |
| 696 | UNIMPLEMENTED(); | 696 | const Node dest = operation[0]; |
| 697 | const Node src = operation[1]; | ||
| 698 | |||
| 699 | Id target{}; | ||
| 700 | if (const auto gpr = std::get_if<GprNode>(dest)) { | ||
| 701 | if (gpr->GetIndex() == Register::ZeroIndex) { | ||
| 702 | // Writing to Register::ZeroIndex is a no op | ||
| 703 | return {}; | ||
| 704 | } | ||
| 705 | target = registers.at(gpr->GetIndex()); | ||
| 706 | |||
| 707 | } else if (const auto abuf = std::get_if<AbufNode>(dest)) { | ||
| 708 | target = [&]() -> Id { | ||
| 709 | switch (const auto attribute = abuf->GetIndex(); attribute) { | ||
| 710 | case Attribute::Index::Position: | ||
| 711 | return AccessElement(t_out_float, per_vertex, position_index, | ||
| 712 | abuf->GetElement()); | ||
| 713 | case Attribute::Index::PointSize: | ||
| 714 | return AccessElement(t_out_float, per_vertex, point_size_index); | ||
| 715 | case Attribute::Index::ClipDistances0123: | ||
| 716 | return AccessElement(t_out_float, per_vertex, clip_distances_index, | ||
| 717 | abuf->GetElement()); | ||
| 718 | case Attribute::Index::ClipDistances4567: | ||
| 719 | return AccessElement(t_out_float, per_vertex, clip_distances_index, | ||
| 720 | abuf->GetElement() + 4); | ||
| 721 | default: | ||
| 722 | if (IsGenericAttribute(attribute)) { | ||
| 723 | return AccessElement(t_out_float, output_attributes.at(attribute), | ||
| 724 | abuf->GetElement()); | ||
| 725 | } | ||
| 726 | UNIMPLEMENTED_MSG("Unhandled output attribute: {}", | ||
| 727 | static_cast<u32>(attribute)); | ||
| 728 | return {}; | ||
| 729 | } | ||
| 730 | }(); | ||
| 731 | |||
| 732 | } else if (const auto lmem = std::get_if<LmemNode>(dest)) { | ||
| 733 | Id address = BitcastTo<Type::Uint>(Visit(lmem->GetAddress())); | ||
| 734 | address = Emit(OpUDiv(t_uint, address, Constant(t_uint, 4))); | ||
| 735 | target = Emit(OpAccessChain(t_prv_float, local_memory, {address})); | ||
| 736 | } | ||
| 737 | |||
| 738 | Emit(OpStore(target, Visit(src))); | ||
| 697 | return {}; | 739 | return {}; |
| 698 | } | 740 | } |
| 699 | 741 | ||
| @@ -723,7 +765,27 @@ private: | |||
| 723 | } | 765 | } |
| 724 | 766 | ||
| 725 | Id LogicalAssign(Operation operation) { | 767 | Id LogicalAssign(Operation operation) { |
| 726 | UNIMPLEMENTED(); | 768 | const Node dest = operation[0]; |
| 769 | const Node src = operation[1]; | ||
| 770 | |||
| 771 | Id target{}; | ||
| 772 | if (const auto pred = std::get_if<PredicateNode>(dest)) { | ||
| 773 | ASSERT_MSG(!pred->IsNegated(), "Negating logical assignment"); | ||
| 774 | |||
| 775 | const auto index = pred->GetIndex(); | ||
| 776 | switch (index) { | ||
| 777 | case Tegra::Shader::Pred::NeverExecute: | ||
| 778 | case Tegra::Shader::Pred::UnusedIndex: | ||
| 779 | // Writing to these predicates is a no-op | ||
| 780 | return {}; | ||
| 781 | } | ||
| 782 | target = predicates.at(index); | ||
| 783 | |||
| 784 | } else if (const auto flag = std::get_if<InternalFlagNode>(dest)) { | ||
| 785 | target = internal_flags.at(static_cast<u32>(flag->GetFlag())); | ||
| 786 | } | ||
| 787 | |||
| 788 | Emit(OpStore(target, Visit(src))); | ||
| 727 | return {}; | 789 | return {}; |
| 728 | } | 790 | } |
| 729 | 791 | ||