vk_shader_decompiler: Implement Assign and LogicalAssign

master
ReinUsesLisp 2019-03-14 02:44:23 +07:00
parent d316d248ab
commit 676172e20d
1 changed files with 64 additions and 2 deletions

@ -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 {};
}