From 6c58ba353caced302f1e4e23eee0de6d59a527a2 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 2 Jan 2023 18:56:25 -0800 Subject: IndexGenerator: Add assertion for overflow in GetRemainingIndices This assertion is currently triggered by Pocoyo Racing (https://bugs.dolphin-emu.org/issues/13136). --- Source/Core/VideoCommon/IndexGenerator.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'Source/Core/VideoCommon/IndexGenerator.cpp') diff --git a/Source/Core/VideoCommon/IndexGenerator.cpp b/Source/Core/VideoCommon/IndexGenerator.cpp index 5d86561ffd..04068e88ec 100644 --- a/Source/Core/VideoCommon/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/IndexGenerator.cpp @@ -334,6 +334,15 @@ u32 IndexGenerator::GetRemainingIndices(OpcodeDecoder::Primitive primitive) cons max_index >>= 2; // -1 is reserved for primitive restart + max_index = max_index - 1; - return max_index - m_base_index - 1; + if (m_base_index > max_index) [[unlikely]] + { + PanicAlertFmt("GetRemainingIndices would overflow; we've already written too many indices? " + "base index {} > max index {}", + m_base_index, max_index); + return 0; + } + + return max_index - m_base_index; } -- cgit v1.2.3 From cefcd9c93c2d76074c3be7a6cb96812dad082e9c Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 2 Jan 2023 19:23:31 -0800 Subject: IndexGenerator: Fix off-by-one in GetRemainingIndices Fixes https://bugs.dolphin-emu.org/issues/13136. --- Source/Core/VideoCommon/IndexGenerator.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'Source/Core/VideoCommon/IndexGenerator.cpp') diff --git a/Source/Core/VideoCommon/IndexGenerator.cpp b/Source/Core/VideoCommon/IndexGenerator.cpp index 04068e88ec..03d0815a13 100644 --- a/Source/Core/VideoCommon/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/IndexGenerator.cpp @@ -328,13 +328,21 @@ void IndexGenerator::AddExternalIndices(const u16* indices, u32 num_indices, u32 u32 IndexGenerator::GetRemainingIndices(OpcodeDecoder::Primitive primitive) const { - u32 max_index = USHRT_MAX; + u32 max_index = UINT16_MAX; if (g_Config.UseVSForLinePointExpand() && primitive >= OpcodeDecoder::Primitive::GX_DRAW_LINES) max_index >>= 2; - // -1 is reserved for primitive restart - max_index = max_index - 1; + // Although we reserve UINT16_MAX for primitive restart, we aren't allowed to use that as an + // actual index. But, the maximum number of vertices a game can send is UINT16_MAX, so up to + // 0xffff indices will be used by the game. These indices would be 0x0000 through 0xfffe, + // and since m_base_index gets incremented for each index used, after that m_base_index + // would be 0xffff and no indices remain. If a game uses 0xfffe vertices, assuming m_base_index + // started at 0 it would end at 0xfffe and one more index could be used. So, we do not need to + // subtract 1 from max_index to correctly reserve one index for primitive restart. + // + // Pocoyo Racing uses a draw command with 0xffff vertices, which previously caused issues; see + // https://bugs.dolphin-emu.org/issues/13136 for details. if (m_base_index > max_index) [[unlikely]] { -- cgit v1.2.3