From d4b6965db07ac5b07fbb1d31d534a0f286edbf2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 31 Aug 2026 15:37:33 +0200 Subject: [PATCH] TestBoundingBox: bail out when the indices reach past the scratch space corners and verts are carved out of decoded_ at fixed offsets 6*65536 bytes apart, and NormalizeVertices fills corners with indexUpperBound - indexLowerBound + 1 SimpleVertex. The vertexCount > 1024 guard doesn't bound that: the index values come from the game, so 1024 indices can span the full 16-bit range and run corners into verts, making the cull decision from overwritten data. Bail on an index over 1024 and report visible - a bbox test that large isn't worth doing anyway. --- GPU/Common/DrawEngineCommon.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index 4ddcf8d326..8c0a6d3bcc 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -228,6 +228,13 @@ bool DrawEngineCommon::TestBoundingBox(const void *vdata, const void *inds, int if (vertexCount > 0 && inds) { GetIndexBounds(inds, vertexCount, vertType, &indexLowerBound, &indexUpperBound); + if (indexUpperBound > 1024) { + // NormalizeVertices below writes indexUpperBound - indexLowerBound + 1 vertices + // into corners, which only has room until the verts region above it. The index + // values are the game's, so the vertexCount cap doesn't bound them. A bbox test + // over this many verts is counter-productive anyway - say it's visible. + return true; + } } // TODO: Avoid normalization if just plain skinning. const u32 vertTypeID = GetVertTypeID(vertType, gstate.getUVGenMode());