mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-23 03:02:53 +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:
|
case 0xD:
|
||||||
{
|
{
|
||||||
// TEX0 - TEX9
|
// TEX0 - TEX9
|
||||||
// Texcoord mask seems to reset the last 2 arguments to 0 and 1 if set
|
// Texcoord 2d mask seems to reset the last 2 arguments to 0 and w if set
|
||||||
if (m_prog.texcoord_is_2d(dst.src_attr_reg_num - 4))
|
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;
|
properties.has_w_access = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -251,7 +251,13 @@ struct RSXFragmentProgram
|
|||||||
|
|
||||||
bool texcoord_is_2d(u8 index) const
|
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()
|
RSXFragmentProgram()
|
||||||
|
@ -1698,6 +1698,13 @@ namespace rsx
|
|||||||
result.redirected_textures = 0;
|
result.redirected_textures = 0;
|
||||||
result.shadow_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();
|
const auto resolution_scale = rsx::get_resolution_scale();
|
||||||
|
|
||||||
for (u32 i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
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<>
|
template<>
|
||||||
struct registers_decoder<NV4097_SET_SURFACE_FORMAT>
|
struct registers_decoder<NV4097_SET_SURFACE_FORMAT>
|
||||||
{
|
{
|
||||||
|
@ -1102,6 +1102,11 @@ namespace rsx
|
|||||||
return decode<NV4097_SET_POINT_SIZE>().point_size();
|
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
|
u8 alpha_ref() const
|
||||||
{
|
{
|
||||||
return decode<NV4097_SET_ALPHA_REF>().alpha_ref();
|
return decode<NV4097_SET_ALPHA_REF>().alpha_ref();
|
||||||
@ -1677,10 +1682,10 @@ namespace rsx
|
|||||||
return decode<NV4097_SET_CONTROL0>().depth_float();
|
return decode<NV4097_SET_CONTROL0>().depth_float();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 texcoord_control_mask()
|
u16 texcoord_control_mask() const
|
||||||
{
|
{
|
||||||
// Only 10 texture coords exist [0-9]
|
// Only 10 texture coords exist [0-9]
|
||||||
u32 control_mask = 0;
|
u16 control_mask = 0;
|
||||||
for (u8 index = 0; index < 10; ++index)
|
for (u8 index = 0; index < 10; ++index)
|
||||||
{
|
{
|
||||||
control_mask |= ((registers[NV4097_SET_TEX_COORD_CONTROL + index] & 1) << index);
|
control_mask |= ((registers[NV4097_SET_TEX_COORD_CONTROL + index] & 1) << index);
|
||||||
@ -1688,6 +1693,11 @@ namespace rsx
|
|||||||
|
|
||||||
return control_mask;
|
return control_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16 point_sprite_control_mask() const
|
||||||
|
{
|
||||||
|
return decode<NV4097_SET_POINT_SPRITE_CONTROL>().texcoord_mask();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern rsx_state method_registers;
|
extern rsx_state method_registers;
|
||||||
|
Loading…
Reference in New Issue
Block a user