rsx: Implement pixel_center_origin decorator for WPOS
Some checks are pending
Generate Translation Template / Generate Translation Template (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux-aarch64.sh, gcc, rpcs3/rpcs3-ci-jammy-aarch64:1.7, ubuntu-24.04-arm) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux.sh, gcc, rpcs3/rpcs3-ci-jammy:1.7, ubuntu-24.04) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (a1d35836e8d45bfc6f63c26f0a3e5d46ef622fe1, rpcs3/rpcs3-binaries-linux-arm64, /rpcs3/.ci/build-linux-aarch64.sh, clang, rpcs3/rpcs3-ci-jammy-aarch64:1.7, ubuntu-24.04-arm) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (d812f1254a1157c80fd402f94446310560f54e5f, rpcs3/rpcs3-binaries-linux, /rpcs3/.ci/build-linux.sh, clang, rpcs3/rpcs3-ci-jammy:1.7, ubuntu-24.04) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (51ae32f468089a8169aaf1567de355ff4a3e0842, rpcs3/rpcs3-binaries-mac, .ci/build-mac.sh, Intel) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (8e21bdbc40711a3fccd18fbf17b742348b0f4281, rpcs3/rpcs3-binaries-mac-arm64, .ci/build-mac-arm64.sh, Apple Silicon) (push) Waiting to run
Build RPCS3 / RPCS3 Windows (push) Waiting to run
Build RPCS3 / RPCS3 Windows Clang (win64, clang, clang64) (push) Waiting to run
Build RPCS3 / RPCS3 FreeBSD (push) Waiting to run

This commit is contained in:
kd-11 2025-11-05 01:50:43 +03:00 committed by kd-11
parent 5d906e1da4
commit 8984c2b316
7 changed files with 53 additions and 24 deletions

View File

@ -40,10 +40,15 @@ namespace utils
/**
* Stream a 128 bits vector from src to dst.
*/
static inline
void stream_vector_from_memory(void* dst, void* src)
template <int Count = 1>
void stream_vector_from_memory(void* dst, void* src)
{
const __m128i vector = _mm_loadu_si128(reinterpret_cast<__m128i*>(src));
_mm_stream_si128(reinterpret_cast<__m128i*>(dst), vector);
auto _src = reinterpret_cast<__m128i*>(src);
auto _dst = reinterpret_cast<__m128i*>(dst);
for (int i = 0; i < Count; ++i, ++_src, ++_dst)
{
const __m128i vector = _mm_loadu_si128(_src);
_mm_stream_si128(_dst, vector);
}
}
}

View File

@ -664,7 +664,21 @@ namespace rsx
void draw_command_processor::fill_fragment_state_buffer(void* buffer, const RSXFragmentProgram& /*fragment_program*/) const
{
#pragma pack(push, 1)
struct fragment_context_t
{
f32 fog_param0;
f32 fog_param1;
u32 rop_control;
f32 alpha_ref;
u32 fog_mode;
f32 wpos_scale;
f32 wpos_bias[2];
};
#pragma pack(pop)
ROP_control_t rop_control{};
alignas(16) fragment_context_t payload{};
if (REGS(m_ctx)->alpha_test_enabled())
{
@ -720,10 +734,6 @@ namespace rsx
}
}
const f32 fog0 = REGS(m_ctx)->fog_params_0();
const f32 fog1 = REGS(m_ctx)->fog_params_1();
const u32 fog_mode = static_cast<u32>(REGS(m_ctx)->fog_equation());
// Check if framebuffer is actually an XRGB format and not a WZYX format
switch (REGS(m_ctx)->surface_color())
{
@ -745,21 +755,37 @@ namespace rsx
}
// Generate wpos coefficients
// wpos equation is now as follows:
// wpos equation is now as follows (ignoring pixel center offset):
// wpos.y = (frag_coord / resolution_scale) * ((window_origin!=top)?-1.: 1.) + ((window_origin!=top)? window_height : 0)
// wpos.x = (frag_coord / resolution_scale)
// wpos.zw = frag_coord.zw
payload.fog_param0 = REGS(m_ctx)->fog_params_0();
payload.fog_param1 = REGS(m_ctx)->fog_params_1();
payload.fog_mode = static_cast<u32>(REGS(m_ctx)->fog_equation());
payload.rop_control = rop_control.value;
payload.alpha_ref = REGS(m_ctx)->alpha_ref();
const auto window_origin = REGS(m_ctx)->shader_window_origin();
const u32 window_height = REGS(m_ctx)->shader_window_height();
const auto pixel_center = REGS(m_ctx)->pixel_center();
const f32 resolution_scale = (window_height <= static_cast<u32>(g_cfg.video.min_scalable_dimension)) ? 1.f : rsx::get_resolution_scale();
const f32 wpos_scale = (window_origin == rsx::window_origin::top) ? (1.f / resolution_scale) : (-1.f / resolution_scale);
const f32 wpos_bias = (window_origin == rsx::window_origin::top) ? 0.f : window_height;
const f32 alpha_ref = REGS(m_ctx)->alpha_ref();
u32* dst = static_cast<u32*>(buffer);
utils::stream_vector(dst, std::bit_cast<u32>(fog0), std::bit_cast<u32>(fog1), rop_control.value, std::bit_cast<u32>(alpha_ref));
utils::stream_vector(dst + 4, 0u, fog_mode, std::bit_cast<u32>(wpos_scale), std::bit_cast<u32>(wpos_bias));
payload.wpos_scale = (window_origin == rsx::window_origin::top) ? (1.f / resolution_scale) : (-1.f / resolution_scale);
payload.wpos_bias[0] = 0.f;
payload.wpos_bias[1] = (window_origin == rsx::window_origin::top) ? 0.f : window_height;
if (pixel_center == window_pixel_center::integer)
{
// We could technically fix this shader side, but...
// 1. We have full control over gl_FragCoord consumption, so fix it using our own pipeline as it is an emulated input.
// 2. Vulkan does not support pixel_center_integer decoration. SPIR-V modules only permit pixel center at half offset.
payload.wpos_bias[0] -= 0.5f;
payload.wpos_bias[1] -= 0.5f;
}
utils::stream_vector_from_memory<2>(buffer, &payload);
}
void draw_command_processor::fill_constants_instancing_buffer(rsx::io_buffer& indirection_table_buf, rsx::io_buffer& constants_data_array_buffer, const VertexProgramBase* prog) const

View File

@ -175,10 +175,9 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS)
" float fog_param1;\n"
" uint rop_control;\n"
" float alpha_ref;\n"
" uint reserved;\n"
" uint fog_mode;\n"
" float wpos_scale;\n"
" float wpos_bias;\n"
" vec2 wpos_bias;\n"
"};\n\n"
"layout(std140, binding = " << GL_FRAGMENT_TEXTURE_PARAMS_BIND_SLOT << ") uniform TextureParametersBuffer\n"

View File

@ -43,10 +43,9 @@ struct fragment_context_t
float fog_param1;
uint rop_control;
float alpha_ref;
uint reserved;
uint fog_mode;
float wpos_scale;
float wpos_bias;
vec2 wpos_bias;
};
)"

View File

@ -38,7 +38,7 @@ bool _fragment_discard = false;
vec4 get_wpos()
{
float abs_scale = abs(wpos_scale);
return (gl_FragCoord * vec4(abs_scale, wpos_scale, 1., 1.)) + vec4(0., wpos_bias, 0., 0.);
return (gl_FragCoord * vec4(abs_scale, wpos_scale, 1., 1.)) + vec4(wpos_bias, 0., 0.);
}
#endif

View File

@ -3132,7 +3132,7 @@ struct registers_decoder<NV4097_SET_SHADER_WINDOW>
return to_window_origin(window_shader_origin_raw());
}
auto window_shader_pixel_center() const
auto pixel_center() const
{
return to_window_pixel_center(window_shader_pixel_center_raw());
}
@ -3146,7 +3146,7 @@ struct registers_decoder<NV4097_SET_SHADER_WINDOW>
static void dump(std::string& out, const decoded_type& decoded)
{
fmt::append(out, "Viewport: height: %u origin: %s pixel center: %s", decoded.window_shader_height()
, decoded.window_shader_origin(), decoded.window_shader_pixel_center());
, decoded.window_shader_origin(), decoded.pixel_center());
}
};

View File

@ -226,9 +226,9 @@ namespace rsx
return decode<NV4097_SET_SHADER_WINDOW>().window_shader_origin();
}
window_pixel_center shader_window_pixel() const
window_pixel_center pixel_center() const
{
return decode<NV4097_SET_SHADER_WINDOW>().window_shader_pixel_center();
return decode<NV4097_SET_SHADER_WINDOW>().pixel_center();
}
u16 shader_window_height() const