mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
rsx: Implement point sprite coordinate generation
- When the point sprite flag is set, overrides the input similar to the 2D mask. The returned X and Y values are always the gl_PointCoord values for the fragment. - Stacks with the 2D mask to override the z and w coordinates.
This commit is contained in:
parent
81c61e230f
commit
7072489a6e
@ -579,10 +579,24 @@ template<typename T> std::string FragmentProgramDecompiler::GetSRC(T src)
|
||||
case 0xD:
|
||||
{
|
||||
// TEX0 - TEX9
|
||||
// Texcoord mask seems to reset the last 2 arguments to 0 and 1 if set
|
||||
if (m_prog.texcoord_is_2d(dst.src_attr_reg_num - 4))
|
||||
// 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;
|
||||
if (m_prog.texcoord_is_point_coord(texcoord))
|
||||
{
|
||||
ret += getFloatTypeName(4) + "(" + reg_var + ".x, " + reg_var + ".y, 0., in_w)";
|
||||
// Point sprite coord generation. Stacks with the 2D override mask.
|
||||
if (m_prog.texcoord_is_2d(texcoord))
|
||||
{
|
||||
ret += getFloatTypeName(4) + "(gl_PointCoord, 0., in_w)";
|
||||
properties.has_w_access = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += getFloatTypeName(4) + "(gl_PointCoord, 1., 0.)";
|
||||
}
|
||||
}
|
||||
else if (m_prog.texcoord_is_2d(texcoord))
|
||||
{
|
||||
ret += getFloatTypeName(4) + "(" + reg_var + ".xy, 0., in_w)";
|
||||
properties.has_w_access = true;
|
||||
}
|
||||
else
|
||||
|
@ -251,7 +251,13 @@ struct RSXFragmentProgram
|
||||
|
||||
bool texcoord_is_2d(u8 index) const
|
||||
{
|
||||
return !!(texcoord_control_mask & (1u << index));
|
||||
return bool(texcoord_control_mask & (1u << index));
|
||||
}
|
||||
|
||||
bool texcoord_is_point_coord(u8 index) const
|
||||
{
|
||||
index += 16;
|
||||
return bool(texcoord_control_mask & (1u << index));
|
||||
}
|
||||
|
||||
RSXFragmentProgram()
|
||||
|
@ -1698,6 +1698,13 @@ namespace rsx
|
||||
result.redirected_textures = 0;
|
||||
result.shadow_textures = 0;
|
||||
|
||||
if (method_registers.current_draw_clause.primitive == primitive_type::points &&
|
||||
method_registers.point_sprite_enabled())
|
||||
{
|
||||
// Set high word of the control mask to store point sprite control
|
||||
result.texcoord_control_mask |= u32(method_registers.point_sprite_control_mask()) << 16;
|
||||
}
|
||||
|
||||
const auto resolution_scale = rsx::get_resolution_scale();
|
||||
|
||||
for (u32 i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
||||
|
@ -3256,6 +3256,35 @@ struct registers_decoder<NV4097_SET_POINT_SIZE>
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct registers_decoder<NV4097_SET_POINT_SPRITE_CONTROL>
|
||||
{
|
||||
struct decoded_type
|
||||
{
|
||||
private:
|
||||
u32 value;
|
||||
|
||||
public:
|
||||
decoded_type(u32 value) : value(value) {}
|
||||
|
||||
bool enabled() const
|
||||
{
|
||||
return bf_decoder<0, 1, bool>(value);
|
||||
}
|
||||
|
||||
u16 texcoord_mask() const
|
||||
{
|
||||
return bf_decoder<8, 10>(value);
|
||||
}
|
||||
};
|
||||
|
||||
static std::string dump(decoded_type &&decoded_values)
|
||||
{
|
||||
return "Point sprite: enabled = " + print_boolean(decoded_values.enabled()) +
|
||||
"override mask = " + fmt::format("0x%x", decoded_values.texcoord_mask());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct registers_decoder<NV4097_SET_SURFACE_FORMAT>
|
||||
{
|
||||
|
@ -1102,6 +1102,11 @@ namespace rsx
|
||||
return decode<NV4097_SET_POINT_SIZE>().point_size();
|
||||
}
|
||||
|
||||
bool point_sprite_enabled() const
|
||||
{
|
||||
return decode<NV4097_SET_POINT_SPRITE_CONTROL>().enabled();
|
||||
}
|
||||
|
||||
u8 alpha_ref() const
|
||||
{
|
||||
return decode<NV4097_SET_ALPHA_REF>().alpha_ref();
|
||||
@ -1677,10 +1682,10 @@ namespace rsx
|
||||
return decode<NV4097_SET_CONTROL0>().depth_float();
|
||||
}
|
||||
|
||||
u32 texcoord_control_mask()
|
||||
u16 texcoord_control_mask() const
|
||||
{
|
||||
// Only 10 texture coords exist [0-9]
|
||||
u32 control_mask = 0;
|
||||
u16 control_mask = 0;
|
||||
for (u8 index = 0; index < 10; ++index)
|
||||
{
|
||||
control_mask |= ((registers[NV4097_SET_TEX_COORD_CONTROL + index] & 1) << index);
|
||||
@ -1688,6 +1693,11 @@ namespace rsx
|
||||
|
||||
return control_mask;
|
||||
}
|
||||
|
||||
u16 point_sprite_control_mask() const
|
||||
{
|
||||
return decode<NV4097_SET_POINT_SPRITE_CONTROL>().texcoord_mask();
|
||||
}
|
||||
};
|
||||
|
||||
extern rsx_state method_registers;
|
||||
|
Loading…
Reference in New Issue
Block a user