mirror of
https://github.com/ARMSX2/ARMSX3.git
synced 2026-08-24 16:58:52 -07:00
Make the redundant vertex program check actually compare
The two-point probe read the incoming words as be_t<u64>, an eight byte swap,
and compared that against a destination written by copy_data_swap_u32, which
swaps each word on its own. The wide swap also exchanges the two words, so the
comparison was (w0,w1) against (w1,w0) and could only match when w0 equalled w1.
It never reported a match.
Every upload therefore set vertex_program_ucode_dirty. That forces a full vertex
program re-analysis per draw clause, drops the program cache hint, nulls the
bound program so load_program runs again, and re-uploads the transform constants
unconditionally. Sonic '06 issues 8088 of these a frame against 3429 draws, and
a corrected profile puts 24.7ms of a 36.4ms frame in draw setup, which is what
all of that lands in.
Rotating the source back by 32 bits puts both sides in the same word order. The
change can only remove spurious invalidations: a clean verdict from the probe is
still confirmed word for word by the full compare below it, so a false clean is
not reachable.
Upstream inherited, introduced in ae39c5b8cb.
This commit is contained in:
@@ -193,8 +193,15 @@ namespace rsx
|
||||
const usz first_index_off = 0;
|
||||
const usz second_index_off = (((rcount / 4) - 1) / 2) * 4;
|
||||
|
||||
const u64 src_op1_2 = read_from_ptr<be_t<u64>>(fifo_span, first_index_off);
|
||||
const u64 src_op2_2 = read_from_ptr<be_t<u64>>(fifo_span, second_index_off);
|
||||
// Rotated by 32: the destination holds each word already byte-swapped
|
||||
// individually (copy_data_swap_u32), but be_t<u64> swaps all eight bytes,
|
||||
// which additionally EXCHANGES the two words. Without the rotate this
|
||||
// compares (w0,w1) against (w1,w0) and can only match when w0 == w1, so the
|
||||
// redundant-upload check never fired: every upload set the ucode dirty,
|
||||
// forcing a vertex program re-analysis, a program cache hint drop and a full
|
||||
// transform constant re-upload on every draw.
|
||||
const u64 src_op1_2 = std::rotl<u64>(read_from_ptr<be_t<u64>>(fifo_span, first_index_off), 32);
|
||||
const u64 src_op2_2 = std::rotl<u64>(read_from_ptr<be_t<u64>>(fifo_span, second_index_off), 32);
|
||||
|
||||
// Fast comparison
|
||||
if (src_op1_2 != read_from_ptr_unsafe<u64>(out_ptr, first_index_off) || src_op2_2 != read_from_ptr_unsafe<u64>(out_ptr, second_index_off))
|
||||
|
||||
Reference in New Issue
Block a user