diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-03-14 06:44:23 +0100 |
---|---|---|
committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-04-10 19:20:25 +0200 |
commit | 676172e20d0a0c2f92ace94ca7cfb37a862fd8dc (patch) | |
tree | 342bcc869f6bfa009634bc8876b3147ee7c50113 /src | |
parent | vk_shader_decompiler: Implement non-OperationCode visits (diff) | |
download | yuzu-676172e20d0a0c2f92ace94ca7cfb37a862fd8dc.tar yuzu-676172e20d0a0c2f92ace94ca7cfb37a862fd8dc.tar.gz yuzu-676172e20d0a0c2f92ace94ca7cfb37a862fd8dc.tar.bz2 yuzu-676172e20d0a0c2f92ace94ca7cfb37a862fd8dc.tar.lz yuzu-676172e20d0a0c2f92ace94ca7cfb37a862fd8dc.tar.xz yuzu-676172e20d0a0c2f92ace94ca7cfb37a862fd8dc.tar.zst yuzu-676172e20d0a0c2f92ace94ca7cfb37a862fd8dc.zip |
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: } Id Assign(Operation operation) { - UNIMPLEMENTED(); + const Node dest = operation[0]; + const Node src = operation[1]; + + Id target{}; + if (const auto gpr = std::get_if<GprNode>(dest)) { + if (gpr->GetIndex() == Register::ZeroIndex) { + // Writing to Register::ZeroIndex is a no op + return {}; + } + target = registers.at(gpr->GetIndex()); + + } else if (const auto abuf = std::get_if<AbufNode>(dest)) { + target = [&]() -> Id { + switch (const auto attribute = abuf->GetIndex(); attribute) { + case Attribute::Index::Position: + return AccessElement(t_out_float, per_vertex, position_index, + abuf->GetElement()); + case Attribute::Index::PointSize: + return AccessElement(t_out_float, per_vertex, point_size_index); + case Attribute::Index::ClipDistances0123: + return AccessElement(t_out_float, per_vertex, clip_distances_index, + abuf->GetElement()); + case Attribute::Index::ClipDistances4567: + return AccessElement(t_out_float, per_vertex, clip_distances_index, + abuf->GetElement() + 4); + default: + if (IsGenericAttribute(attribute)) { + return AccessElement(t_out_float, output_attributes.at(attribute), + abuf->GetElement()); + } + UNIMPLEMENTED_MSG("Unhandled output attribute: {}", + static_cast<u32>(attribute)); + return {}; + } + }(); + + } else if (const auto lmem = std::get_if<LmemNode>(dest)) { + Id address = BitcastTo<Type::Uint>(Visit(lmem->GetAddress())); + address = Emit(OpUDiv(t_uint, address, Constant(t_uint, 4))); + target = Emit(OpAccessChain(t_prv_float, local_memory, {address})); + } + + Emit(OpStore(target, Visit(src))); return {}; } @@ -723,7 +765,27 @@ private: } Id LogicalAssign(Operation operation) { - UNIMPLEMENTED(); + const Node dest = operation[0]; + const Node src = operation[1]; + + Id target{}; + if (const auto pred = std::get_if<PredicateNode>(dest)) { + ASSERT_MSG(!pred->IsNegated(), "Negating logical assignment"); + + const auto index = pred->GetIndex(); + switch (index) { + case Tegra::Shader::Pred::NeverExecute: + case Tegra::Shader::Pred::UnusedIndex: + // Writing to these predicates is a no-op + return {}; + } + target = predicates.at(index); + + } else if (const auto flag = std::get_if<InternalFlagNode>(dest)) { + target = internal_flags.at(static_cast<u32>(flag->GetFlag())); + } + + Emit(OpStore(target, Visit(src))); return {}; } |