summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-03-14 02:44:23 -0300
committerGravatar ReinUsesLisp2019-04-10 14:20:25 -0300
commit676172e20d0a0c2f92ace94ca7cfb37a862fd8dc (patch)
tree342bcc869f6bfa009634bc8876b3147ee7c50113 /src
parentvk_shader_decompiler: Implement non-OperationCode visits (diff)
downloadyuzu-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.cpp66
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