mirror of
https://git.suyu.dev/suyu/suyu
synced 2024-11-01 12:57:52 +00:00
vk_shader_decompiler: Implement Assign and LogicalAssign
This commit is contained in:
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 {};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue