|
|
|
@ -1,3 +1,6 @@ |
|
|
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
|
|
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
|
|
@ -163,12 +166,24 @@ void TranslatorVisitor::IPA(u64 insn) { |
|
|
|
const IR::Attribute attribute{ipa.attribute}; |
|
|
|
IR::F32 value{is_indexed ? ir.GetAttributeIndexed(X(ipa.index_reg)) |
|
|
|
: ir.GetAttribute(attribute)}; |
|
|
|
if (IR::IsGeneric(attribute)) { |
|
|
|
const ProgramHeader& sph{env.SPH()}; |
|
|
|
const u32 attr_index{IR::GenericAttributeIndex(attribute)}; |
|
|
|
const u32 element{static_cast<u32>(attribute) % 4}; |
|
|
|
const std::array input_map{sph.ps.GenericInputMap(attr_index)}; |
|
|
|
const bool is_perspective{input_map[element] == Shader::PixelImap::Perspective}; |
|
|
|
const bool is_legacy{IR::IsLegacyAttribute(attribute)}; |
|
|
|
if (IR::IsGeneric(attribute) || is_legacy) { |
|
|
|
bool is_perspective{is_legacy && |
|
|
|
ipa.interpolation_mode != InterpolationMode::Sc}; |
|
|
|
if (!is_legacy) { |
|
|
|
const ProgramHeader& sph{env.SPH()}; |
|
|
|
const u32 attr_index{IR::GenericAttributeIndex(attribute)}; |
|
|
|
const std::array input_map{sph.ps.GenericInputMap(attr_index)}; |
|
|
|
Shader::PixelImap effective_imap{Shader::PixelImap::Unused}; |
|
|
|
for (const Shader::PixelImap component : input_map) { |
|
|
|
if (component != Shader::PixelImap::Unused) { |
|
|
|
effective_imap = component; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
is_perspective = effective_imap == Shader::PixelImap::Perspective || |
|
|
|
effective_imap == Shader::PixelImap::Unused; |
|
|
|
} |
|
|
|
if (is_perspective) { |
|
|
|
const IR::F32 position_w{ir.GetAttribute(IR::Attribute::PositionW)}; |
|
|
|
value = ir.FPMul(value, position_w); |
|
|
|
|