mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-12-06 07:12:28 +01:00
rsx: Implement register lane gathering for operations other than UPX
This commit is contained in:
parent
7e209a7275
commit
c00eeb5b10
|
|
@ -4,6 +4,7 @@
|
||||||
#include "ProgramStateCache.h"
|
#include "ProgramStateCache.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace rsx
|
namespace rsx
|
||||||
{
|
{
|
||||||
|
|
@ -527,21 +528,48 @@ template<typename T> std::string FragmentProgramDecompiler::GetSRC(T src)
|
||||||
|
|
||||||
if (!src.fp16)
|
if (!src.fp16)
|
||||||
{
|
{
|
||||||
|
// We may need to perform gather on all the f32 lanes.
|
||||||
|
// First, confirm that we're actually reading all the lanes
|
||||||
|
// TODO: GetSRC should take a lane count argument
|
||||||
|
std::unordered_set<u8> to_gather;
|
||||||
|
|
||||||
|
// Unpack instructions always read the whole vector
|
||||||
if (dst.opcode == RSX_FP_OPCODE_UP16 ||
|
if (dst.opcode == RSX_FP_OPCODE_UP16 ||
|
||||||
dst.opcode == RSX_FP_OPCODE_UP2 ||
|
dst.opcode == RSX_FP_OPCODE_UP2 ||
|
||||||
dst.opcode == RSX_FP_OPCODE_UP4 ||
|
dst.opcode == RSX_FP_OPCODE_UP4 ||
|
||||||
dst.opcode == RSX_FP_OPCODE_UPB ||
|
dst.opcode == RSX_FP_OPCODE_UPB ||
|
||||||
dst.opcode == RSX_FP_OPCODE_UPG)
|
dst.opcode == RSX_FP_OPCODE_UPG)
|
||||||
{
|
{
|
||||||
auto ® = temp_registers[src.tmp_reg_index];
|
to_gather.insert(src.swizzle_x);
|
||||||
if (reg.requires_gather(src.swizzle_x))
|
}
|
||||||
|
else if (!dst.no_dest)
|
||||||
|
{
|
||||||
|
// FIXME: No_DST inputs also require lane gather. A regalloc pre-pass will solve this.
|
||||||
|
// We try to guess which channels will be read. Since there is no lane count, mask input on output mask
|
||||||
|
if (dst.mask_x) to_gather.insert(src.swizzle_x);
|
||||||
|
if (dst.mask_y) to_gather.insert(src.swizzle_y);
|
||||||
|
if (dst.mask_z) to_gather.insert(src.swizzle_z);
|
||||||
|
if (dst.mask_w) to_gather.insert(src.swizzle_w);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& reg = temp_registers[src.tmp_reg_index];
|
||||||
|
bool skip_reg_assign = false;
|
||||||
|
for (const auto& ch : to_gather)
|
||||||
|
{
|
||||||
|
if (reg.requires_gather(ch))
|
||||||
{
|
{
|
||||||
properties.has_gather_op = true;
|
properties.has_gather_op = true;
|
||||||
AddReg(src.tmp_reg_index, src.fp16);
|
AddReg(src.tmp_reg_index, src.fp16);
|
||||||
ret = getFloatTypeName(4) + reg.gather_r();
|
ret = getFloatTypeName(4) + reg.gather_r();
|
||||||
|
skip_reg_assign = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (skip_reg_assign)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (precision_modifier == RSX_FP_PRECISION_HALF)
|
else if (precision_modifier == RSX_FP_PRECISION_HALF)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue