26 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Opus 5.5 e8c39ed1a7 Unit tests: Share the benchmark timing loop
Four tests had their own copy of "call this until N seconds have passed,
then divide". CallsPerSecond in UnitTest.h does it; each keeps its old
duration and batch size.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-30 11:11:22 -06:00
Henrik RydgårdandClaude Opus 5 66b59c73a9 Vertex decoder: bring the riscv64 and loongarch64 JITs in line
Enables TestVertexJitMatchesSteps on both. riscv64 now passes all 216000
jitted formats and loongarch64 all 204000, against 28906 on arm64.

riscv64:
- Jit_PosFloat didn't clean NaN or infinity at all, it just copied the
  three words. Clamp to +-FLT_MAX like the x86 JIT does.
- Jit_PosFloatThrough was missing the truncation of Z to an integer.
- The morph helpers started the sum from the first product rather than
  from +0.0, which rounds differently and lets a -0 term through, and
  rounded that first product towards zero where the steps round to
  nearest. The rest of the sum stays fused, since the compiler contracts
  the steps into fused multiply-adds.
- The texcoord prescale and 5551 color morph paths read morph weights
  from tables that GetMorphValueUsage never asked to be filled in, so
  they used whatever an earlier vertex type had left there.
- The non-Zbb bounds update compared the wrong way around, so through
  mode texcoord bounds came out inverted.

loongarch64:
- Jit_PosFloat had a TODO to clean NaN and infinity, and didn't.
- Jit_PosFloatThrough was missing the same Z truncation.
- Jit_WriteMorphColor narrowed with the logical saturating shifts, so a
  negative channel became a huge unsigned value and saturated to 255
  instead of clamping to 0, and it rounded where the steps truncate. It
  also read the packed color back sign-extended, so any alpha above 0x7F
  compared as larger than 0xFF000000 and claimed full alpha.
- The three packed color morph formats are rewritten. The LSX versions
  built each channel with a chain of inserts, shifts and shuffles that
  didn't survive being run; 4444 also broadcast its scale from the mask
  register. They now follow the steps channel by channel. Note the
  accumulator has to be an LSX scratch register - F4-F7 alias V4-V7,
  which hold the skin matrix for the whole vertex.
- The vertex bounds were loaded with a signed halfword load, so the
  0xFFFF they start at became -1 and no texcoord was ever below it.

PrescaleUV now fuses on these two as well - both JITs fuse it, and the
compiler would have contracted the plain expression there anyway.

The test tolerates a small relative difference on decoded floats, scaled
by the morph count since each term rounds once. Every bug above was
orders of magnitude larger than that.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-09-21 13:48:56 -06:00
Henrik RydgårdandClaude Opus 5 c58baedd75 Vertex decoder: fix the jit-match test on MSVC
The test didn't compile: VERTS is captured by reference into testFormat, and
MSVC won't use a captured constexpr as an array bound. Make it static.

On arm64 it then failed on the UV prescale steps, by one ULP. The arm64 JIT and
the NEON handwritten decoders fuse the multiply-add, and the steps only match
that when the compiler contracts a * b + c - which clang does and MSVC doesn't,
in Debug or Release. Spell out which one happens instead of relying on it.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-09-21 12:13:09 -06:00
Henrik RydgårdandClaude Opus 5 a1ed24ae2d Vertex decoder: fix the handwritten decoders, and test them too
The two handwritten SIMD decoders are used with or without the JIT, and had
drifted from the step functions:
- The God of War one ignored g_DoubleTextureCoordinates, giving HD Remaster
  games the wrong UVs, and passed NaN and infinite positions through. Those
  now come out finite like everywhere else.
- The GTA one expanded 5551 colors wrongly on NEON (a left shift where the
  SSE version shifts right).
- On ARM64, both now fuse the UV scale and offset, like the JIT and the steps
  as the compiler builds them.

Both are back in the unit test, which now also feeds NaN and infinity to plain
float positions and checks they come out finite, and runs only on x86-64 and
arm64 for now.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-09-21 11:29:40 -06:00
Henrik RydgårdandClaude Opus 5 63a6c11214 Vertex decoder: make the JIT match the step functions
Add a unit test that decodes every vertex format through both the step
functions and the JIT and requires identical output, side effects included.
Only skinning may differ by rounding, since arm64 accumulates the bone
matrices with fused multiply-adds.

What it found, and fixed:
- x86 morph colors rounded to nearest where the steps truncate, and applied
  the scale before the weight, which rounds differently.
- x86 through-mode u16 UV bounds compared signed, so texcoords above 32767
  scrambled the bounds for everyone running the x86 JIT.
- x86 morph sums could produce -0 where the steps produce +0.
- Step_NormalS16Morph scaled by 1/32768 twice, giving near-zero normals.
- Step_PosFloatThrough lost the truncation of Z to an integer that the JITs
  and the vertex reader did before it moved into the decoder.
- SetVertexType never reset skinInDecode.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-09-21 11:29:40 -06:00
Henrik Rydgård 61e1ef8f7a Remove the "Software skinning" option. Now always on. 2026-07-14 17:02:57 +02:00
Henrik Rydgård 6d2948a09b Remove the cached UVScale in gstate_c. Conversion is cheap enough to do directly from gstate, no point in caching. 2026-07-03 13:17:35 +02:00
Henrik Rydgård 991d7bdfab VertexDecoder: Refactor away lowerbound/upperbound parameters 2026-02-05 13:26:17 +01:00
Henrik Rydgård e74101a2fb applySkinInDecode belongs in the VertexTypeID, not in the options. 2024-12-17 18:24:18 +01:00
Henrik Rydgård 01cea7f088 Pass uvScale in as an argument to the vertex decoder
Cleaner than overwriting/restoring gstate_c.uvScale in the decoder
loop. A small cleanup I've been wanting to do for ages.

Expecting a negligble perf boost if any.
2023-06-12 20:25:18 +02:00
Unknown W. Brackets 9c21184352 vertexjit: Simplify CPU core check.
This also avoids allocating the memory we won't use if it's off.
2023-02-28 07:03:12 -08:00
Unknown W. Brackets 66472c39ce GPU: Use skinned position always in bounding check.
Meanwhile, move to a flag on decoder options instead of global check.
2022-11-06 08:23:31 -08:00
Henrik Rydgård dc86970098 Merge pull request #15947 from unknownbrackets/unittest-cleanup
unitest: Correct wrong free, initialize data
2022-09-03 07:03:17 +02:00
Unknown W. Brackets 2dbd9d8c70 unitest: Correct wrong free, initialize data.
Prevents valgrind warnings in unittest.
2022-09-02 20:04:25 -07:00
Unknown W. Brackets e9880d39be vertexjit: Update unit test, oops. 2022-09-02 18:09:47 -07:00
Unknown W. Brackets 2479d52202 Global: Reduce includes of common headers.
In many places, string, map, or Common.h were included but not needed.
2022-01-30 16:35:33 -08:00
Sean McGovern e9dbc925ea TestVertexJit: fmodf() definition requires math.h 2021-02-17 22:25:26 -05:00
Henrik Rydgård 054acf768c Don't cache time in a variable.
A little weirdness in the code that has stuck around for a long, long
time. It's really not necessary and mostly just confusing.
2020-09-24 23:52:43 +02:00
Henrik Rydgård ccc0331279 Move timeutil to Common. (Experiment to see how much work it is to move these). 2020-08-15 20:53:08 +02:00
Unknown W. Brackets b4496f1975 Core: Move config enums to separate file.
These are a bit strewn about and there are constants that aren't
consistently used, which just adds confusion.
2018-06-23 10:59:18 -07:00
Henrik Rydgård 36fd2711d6 Revert "Remove further remains of hardware skinning."
This reverts commit 40db61a680.
2018-04-10 12:22:41 +02:00
Henrik Rydgård 40db61a680 Remove further remains of hardware skinning. Fixes #10661 2018-03-05 00:03:47 +01:00
Unknown W. Brackets 6b3944d329 UnitTest: Correct vertex and jit tests.
We now convert texcoords to floats.
2017-05-06 18:45:04 -07:00
Unknown W. Brackets 683b3eb082 Add tests for various vertex formats. 2015-07-04 18:08:31 -07:00
Unknown W. Brackets 14885182b9 Add some timing ability. 2015-07-03 15:44:41 -07:00
Unknown W. Brackets 808db2482a Initial structure for vertexjit tests. 2015-07-03 15:25:40 -07:00