mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-17 00:10:31 +02:00
Vertex decoder: Use the handwritten decoders with every UV generation mode
They were only used for UV from texture coordinates. With the texture matrix or environment map, UV isn't prescaled, which is the same as a scale of 1 and no offset, so NoPrescale versions pass that. God of War draws 5 million of its vertices per 10 seconds this way, which without the vertex JIT took 9.6 ns each through the steps and now 2.4. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
253029c083
commit
253aba2a60
3 files changed
+25
-6
No files matched your search
@@ -1363,14 +1363,17 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options,
|
||||
|
||||
// Only use the handwritten decoders if we have SSE or NEON. Don't want to use these on RISC-V, probably?
|
||||
#if PPSSPP_ARCH(ARM_NEON) || PPSSPP_ARCH(SSE2)
|
||||
// See GetVertTypeID
|
||||
uint32_t fmtWithoutSkinFlag = (fmt_ & ~0x04000000);
|
||||
if (fmtWithoutSkinFlag == (GE_VTYPE_TC_8BIT | GE_VTYPE_COL_5551 | GE_VTYPE_POS_16BIT)) {
|
||||
// See GetVertTypeID. The UV generation modes that don't prescale UV convert it the same way with a
|
||||
// scale of 1 and no offset, which the NoPrescale versions pass.
|
||||
const uint32_t vtype = fmt_ & 0x00FFFFFF;
|
||||
const GETexMapMode uvGenMode = VertTypeIDUVGenMode(fmt_);
|
||||
const bool prescale = uvGenMode == GE_TEXMAP_TEXTURE_COORDS || uvGenMode == GE_TEXMAP_UNKNOWN;
|
||||
if (vtype == (GE_VTYPE_TC_8BIT | GE_VTYPE_COL_5551 | GE_VTYPE_POS_16BIT)) {
|
||||
// Can skip looking up in the JIT.
|
||||
jitted_ = &VtxDec_Tu8_C5551_Ps16;
|
||||
jitted_ = prescale ? &VtxDec_Tu8_C5551_Ps16 : &VtxDec_Tu8_C5551_Ps16_NoPrescale;
|
||||
return;
|
||||
} else if (!options.expand8BitNormalsToFloat && fmtWithoutSkinFlag == (GE_VTYPE_TC_16BIT | GE_VTYPE_NRM_8BIT | GE_VTYPE_COL_8888 | GE_VTYPE_POS_FLOAT)) {
|
||||
jitted_ = &VtxDec_Tu16_C8888_Pfloat;
|
||||
} else if (!options.expand8BitNormalsToFloat && vtype == (GE_VTYPE_TC_16BIT | GE_VTYPE_NRM_8BIT | GE_VTYPE_COL_8888 | GE_VTYPE_POS_FLOAT)) {
|
||||
jitted_ = prescale ? &VtxDec_Tu16_C8888_Pfloat : &VtxDec_Tu16_C8888_Pfloat_NoPrescale;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -324,3 +324,15 @@ void VtxDec_Tu8_C5551_Ps16(const u8 *srcp, u8 *dstp, int numVerts, const UVScale
|
||||
|
||||
gstate_c.vertexFullAlpha = (alpha >> 15) & 1;
|
||||
}
|
||||
|
||||
// Converting UV without a prescale is the same as with a scale of 1 and no offset: the division by a power
|
||||
// of two in the scale is exact either way.
|
||||
static const UVScale identityUVScale = { 1.0f, 1.0f, 0.0f, 0.0f };
|
||||
|
||||
void VtxDec_Tu16_C8888_Pfloat_NoPrescale(const u8 *srcp, u8 *dstp, int count, const UVScale *uvScaleOffset) {
|
||||
VtxDec_Tu16_C8888_Pfloat(srcp, dstp, count, &identityUVScale);
|
||||
}
|
||||
|
||||
void VtxDec_Tu8_C5551_Ps16_NoPrescale(const u8 *srcp, u8 *dstp, int count, const UVScale *uvScaleOffset) {
|
||||
VtxDec_Tu8_C5551_Ps16(srcp, dstp, count, &identityUVScale);
|
||||
}
|
||||
@@ -5,3 +5,7 @@
|
||||
|
||||
void VtxDec_Tu16_C8888_Pfloat(const u8 *srcp, u8 *dstp, int count, const UVScale *uvScaleOffset);
|
||||
void VtxDec_Tu8_C5551_Ps16(const u8 *srcp, u8 *dstp, int count, const UVScale *uvScaleOffset);
|
||||
|
||||
// For the UV generation modes that don't prescale.
|
||||
void VtxDec_Tu16_C8888_Pfloat_NoPrescale(const u8 *srcp, u8 *dstp, int count, const UVScale *uvScaleOffset);
|
||||
void VtxDec_Tu8_C5551_Ps16_NoPrescale(const u8 *srcp, u8 *dstp, int count, const UVScale *uvScaleOffset);
|
||||
Reference in new issue
Block a user