rsx/fp: Fix indexed TEX[n] loads

This commit is contained in:
kd-11 2021-08-19 00:12:46 +03:00 committed by kd-11
parent fcfeac818f
commit 3eb37344cd
1 changed files with 18 additions and 24 deletions

View File

@ -547,10 +547,20 @@ template<typename T> std::string FragmentProgramDecompiler::GetSRC(T src)
// 1. Reading from registers 1 and 2 (COL0 and COL1) is clamped to (0, 1) // 1. Reading from registers 1 and 2 (COL0 and COL1) is clamped to (0, 1)
// 2. Reading from registers 4-12 (inclusive) is not clamped, but.. // 2. Reading from registers 4-12 (inclusive) is not clamped, but..
// 3. If the texcoord control mask is enabled, the last 2 values are always 0 and hpos.w! // 3. If the texcoord control mask is enabled, the last 2 values are always 0 and hpos.w!
const std::string reg_var = (dst.src_attr_reg_num < std::size(reg_table))? reg_table[dst.src_attr_reg_num] : "unk"; // 4. [A0 + N] addressing can be applied to dynamically sample texture coordinates.
// - This is explained in NV_fragment_program2 specification page, Fragment Attributes section.
// - There is no instruction that writes to the address register directly, it is supposed to be the loop counter!
const u32 register_id = src2.use_index_reg ? (src2.addr_reg + 4) : dst.src_attr_reg_num;
const std::string reg_var = (register_id < std::size(reg_table))? reg_table[register_id] : "unk";
bool insert = true; bool insert = true;
switch (dst.src_attr_reg_num) if (src2.use_index_reg && m_loop_count)
{
// TODO: Actually implement dynamic register indexing (kd-11)
rsx_log.error("Dynamic register indexing is unimplemented. Report this to developers!");
}
switch (register_id)
{ {
case 0x00: case 0x00:
{ {
@ -563,30 +573,14 @@ template<typename T> std::string FragmentProgramDecompiler::GetSRC(T src)
case 0x02: case 0x02:
{ {
// COL0, COL1 // COL0, COL1
if (!src2.use_index_reg) ret += "_saturate(" + reg_var + ")";
{ precision_modifier = RSX_FP_PRECISION_REAL;
ret += "_saturate(" + reg_var + ")";
precision_modifier = RSX_FP_PRECISION_REAL;
}
else
{
// Raw access
ret += reg_var;
}
break; break;
} }
case 0x03: case 0x03:
{ {
// FOGC // FOGC
if (!src2.use_index_reg) ret += reg_var;
{
ret += reg_var;
}
else
{
// Raw access
ret += "fog_c";
}
break; break;
} }
case 0x4: case 0x4:
@ -602,7 +596,7 @@ template<typename T> std::string FragmentProgramDecompiler::GetSRC(T src)
{ {
// TEX0 - TEX9 // TEX0 - TEX9
// Texcoord 2d mask seems to reset the last 2 arguments to 0 and w if set // Texcoord 2d mask seems to reset the last 2 arguments to 0 and w if set
const u8 texcoord = u8(dst.src_attr_reg_num) - 4; const u8 texcoord = u8(register_id) - 4;
if (m_prog.texcoord_is_point_coord(texcoord)) if (m_prog.texcoord_is_point_coord(texcoord))
{ {
// Point sprite coord generation. Stacks with the 2D override mask. // Point sprite coord generation. Stacks with the 2D override mask.
@ -633,7 +627,7 @@ template<typename T> std::string FragmentProgramDecompiler::GetSRC(T src)
// UNK // UNK
if (reg_var == "unk") if (reg_var == "unk")
{ {
rsx_log.error("Bad src reg num: %d", u32{ dst.src_attr_reg_num }); rsx_log.error("Bad src reg num: %d", u32{ register_id });
} }
ret += reg_var; ret += reg_var;
@ -647,7 +641,7 @@ template<typename T> std::string FragmentProgramDecompiler::GetSRC(T src)
m_parr.AddParam(PF_PARAM_IN, getFloatTypeName(4), reg_var); m_parr.AddParam(PF_PARAM_IN, getFloatTypeName(4), reg_var);
} }
properties.in_register_mask |= (1 << dst.src_attr_reg_num); properties.in_register_mask |= (1 << register_id);
} }
break; break;