From 4716b53cd9581c8d300025b8994df43e0ba601bf Mon Sep 17 00:00:00 2001 From: Exzap <13877693+Exzap@users.noreply.github.com> Date: Mon, 26 Oct 2026 14:38:32 +0100 Subject: [PATCH] Latte+Vulkan+Metal: Improve support for little-endian indices --- .../HW/Latte/Core/LatteCommandProcessor.cpp | 5 +- src/Cafe/HW/Latte/Core/LatteIndices.cpp | 68 +++++++++++++------ 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/Cafe/HW/Latte/Core/LatteCommandProcessor.cpp b/src/Cafe/HW/Latte/Core/LatteCommandProcessor.cpp index dde243e3..a7167ba9 100644 --- a/src/Cafe/HW/Latte/Core/LatteCommandProcessor.cpp +++ b/src/Cafe/HW/Latte/Core/LatteCommandProcessor.cpp @@ -771,7 +771,7 @@ LatteCMDPtr LatteCP_itDrawImmediate(LatteCMDPtr cmd, uint32 nWords, DrawPassCont // calculate size of index data in packet and read indices uint32 numIndexU32s; auto indexType = LatteGPUState.contextNew.VGT_DMA_INDEX_TYPE.get_INDEX_TYPE(); - if (indexType == Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE::U16_BE) + if (indexType == Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE::U16_BE || indexType == Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE::U16_LE) { // 16bit indices numIndexU32s = (count + 1) / 2; @@ -786,10 +786,9 @@ LatteCMDPtr LatteCP_itDrawImmediate(LatteCMDPtr cmd, uint32 nWords, DrawPassCont } LatteIndices_invalidate(memory_getPointerFromVirtualOffset(_tempIndexArrayMPTR), numIndexU32s * sizeof(uint32)); } - else if (indexType == Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE::U32_BE) + else if (indexType == Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE::U32_BE || indexType == Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE::U32_LE) { // 32bit indices - cemu_assert_debug(false); // testing needed numIndexU32s = count; cemu_assert(numIndexU32s < 0x4000 && numIndexU32s <= nWords-2); memcpy(memory_getPointerFromVirtualOffset(_tempIndexArrayMPTR), cmd, numIndexU32s * sizeof(uint32)); diff --git a/src/Cafe/HW/Latte/Core/LatteIndices.cpp b/src/Cafe/HW/Latte/Core/LatteIndices.cpp index a2376443..aa64a70c 100644 --- a/src/Cafe/HW/Latte/Core/LatteIndices.cpp +++ b/src/Cafe/HW/Latte/Core/LatteIndices.cpp @@ -168,11 +168,11 @@ void LatteIndices_convertLE(const void* indexDataInput, void* indexDataOutput, u } } -template +template void LatteIndices_unpackQuadsAndConvert(const void* indexDataInput, void* indexDataOutput, uint32 count, uint32& indexMax) { sint32 numQuads = count / 4; - const betype* src = (betype*)indexDataInput; + const TInput* src = (const TInput*)indexDataInput; T* dst = (T*)indexDataOutput; for (sint32 i = 0; i < numQuads; i++) { @@ -219,13 +219,13 @@ void LatteIndices_generateAutoQuadIndices(const void* indexDataInput, void* inde indexMax = std::max(count, 1u) - 1; } -template +template void LatteIndices_unpackQuadStripAndConvert(const void* indexDataInput, void* indexDataOutput, uint32 count, uint32& indexMax) { if (count <= 3) return; sint32 numQuads = (count - 2) / 2; - const betype* src = (betype*)indexDataInput; + const TInput* src = (const TInput*)indexDataInput; T* dst = (T*)indexDataOutput; for (sint32 i = 0; i < numQuads; i++) { @@ -248,12 +248,12 @@ void LatteIndices_unpackQuadStripAndConvert(const void* indexDataInput, void* in } } -template +template void LatteIndices_unpackLineLoopAndConvert(const void* indexDataInput, void* indexDataOutput, uint32 count, uint32& indexMax) { if (count <= 0) return; - const betype* src = (betype*)indexDataInput; + const TInput* src = (const TInput*)indexDataInput; T firstIndex = *src; T* dst = (T*)indexDataOutput; for (sint32 i = 0; i < (sint32)count; i++) @@ -308,10 +308,10 @@ void LatteIndices_generateAutoLineLoopIndices(void* indexDataOutput, uint32 coun indexMax = std::max(count, 1u) - 1; } -template +template void LatteIndices_unpackTriangleFanAndConvert(const void* indexDataInput, void* indexDataOutput, uint32 count, uint32& indexMax) { - const betype* src = (betype*)indexDataInput; + const TInput* src = (const TInput*)indexDataInput; T* dst = (T*)indexDataOutput; // TODO: check this for (sint32 i = 0; i < count; i++) @@ -598,12 +598,12 @@ void LatteIndices_fastConvertU32_NEON(const void* indexDataInput, void* indexDat #endif -template +template void _LatteIndices_alternativeCalculateIndexMax(const void* indexData, uint32 count, uint32 primitiveRestartIndex, uint32& indexMax) { cemu_assert_debug(count != 0); - const betype* idxPtrT = (betype*)indexData; - T _indexMax = *idxPtrT; + const TInput* idxPtrT = (const TInput*)indexData; + T _indexMax = 0; cemu_assert_debug(primitiveRestartIndex <= std::numeric_limits::max()); T restartIndexT = (T)primitiveRestartIndex; while (count) @@ -632,11 +632,19 @@ void LatteIndices_alternativeCalculateIndexMax(const void* indexData, LatteIndex if (indexType == LatteIndexType::U16_BE) { - _LatteIndices_alternativeCalculateIndexMax(indexData, count, primitiveRestartIndex, indexMax); + _LatteIndices_alternativeCalculateIndexMax(indexData, count, primitiveRestartIndex, indexMax); } else if (indexType == LatteIndexType::U32_BE) { - _LatteIndices_alternativeCalculateIndexMax(indexData, count, primitiveRestartIndex, indexMax); + _LatteIndices_alternativeCalculateIndexMax(indexData, count, primitiveRestartIndex, indexMax); + } + else if (indexType == LatteIndexType::U16_LE) + { + _LatteIndices_alternativeCalculateIndexMax(indexData, count, primitiveRestartIndex, indexMax); + } + else if (indexType == LatteIndexType::U32_LE) + { + _LatteIndices_alternativeCalculateIndexMax(indexData, count, primitiveRestartIndex, indexMax); } else { @@ -673,7 +681,7 @@ void LatteIndices_decode(const void* indexData, LatteIndexType indexType, uint32 renderIndexType = Renderer::INDEX_TYPE::NONE; else if (indexType == LatteIndexType::U16_BE || indexType == LatteIndexType::U16_LE) renderIndexType = Renderer::INDEX_TYPE::U16; - else if (indexType == LatteIndexType::U32_BE) + else if (indexType == LatteIndexType::U32_BE || indexType == LatteIndexType::U32_LE) renderIndexType = Renderer::INDEX_TYPE::U32; else cemu_assert_debug(false); @@ -713,9 +721,13 @@ void LatteIndices_decode(const void* indexData, LatteIndexType indexType, uint32 } } else if (indexType == LatteIndexType::U16_BE) - LatteIndices_unpackQuadsAndConvert(indexData, indexOutputPtr, count, indexMax); + LatteIndices_unpackQuadsAndConvert(indexData, indexOutputPtr, count, indexMax); else if (indexType == LatteIndexType::U32_BE) - LatteIndices_unpackQuadsAndConvert(indexData, indexOutputPtr, count, indexMax); + LatteIndices_unpackQuadsAndConvert(indexData, indexOutputPtr, count, indexMax); + else if (indexType == LatteIndexType::U16_LE) + LatteIndices_unpackQuadsAndConvert(indexData, indexOutputPtr, count, indexMax); + else if (indexType == LatteIndexType::U32_LE) + LatteIndices_unpackQuadsAndConvert(indexData, indexOutputPtr, count, indexMax); else cemu_assert_debug(false); outputCount = count / 4 * 6; @@ -737,9 +749,13 @@ void LatteIndices_decode(const void* indexData, LatteIndexType indexType, uint32 } } else if (indexType == LatteIndexType::U16_BE) - LatteIndices_unpackQuadStripAndConvert(indexData, indexOutputPtr, count, indexMax); + LatteIndices_unpackQuadStripAndConvert(indexData, indexOutputPtr, count, indexMax); else if (indexType == LatteIndexType::U32_BE) - LatteIndices_unpackQuadStripAndConvert(indexData, indexOutputPtr, count, indexMax); + LatteIndices_unpackQuadStripAndConvert(indexData, indexOutputPtr, count, indexMax); + else if (indexType == LatteIndexType::U16_LE) + LatteIndices_unpackQuadStripAndConvert(indexData, indexOutputPtr, count, indexMax); + else if (indexType == LatteIndexType::U32_LE) + LatteIndices_unpackQuadStripAndConvert(indexData, indexOutputPtr, count, indexMax); else cemu_assert_debug(false); if (count >= 2) @@ -764,9 +780,13 @@ void LatteIndices_decode(const void* indexData, LatteIndexType indexType, uint32 } } else if (indexType == LatteIndexType::U16_BE) - LatteIndices_unpackLineLoopAndConvert(indexData, indexOutputPtr, count, indexMax); + LatteIndices_unpackLineLoopAndConvert(indexData, indexOutputPtr, count, indexMax); else if (indexType == LatteIndexType::U32_BE) - LatteIndices_unpackLineLoopAndConvert(indexData, indexOutputPtr, count, indexMax); + LatteIndices_unpackLineLoopAndConvert(indexData, indexOutputPtr, count, indexMax); + else if (indexType == LatteIndexType::U16_LE) + LatteIndices_unpackLineLoopAndConvert(indexData, indexOutputPtr, count, indexMax); + else if (indexType == LatteIndexType::U32_LE) + LatteIndices_unpackLineLoopAndConvert(indexData, indexOutputPtr, count, indexMax); else cemu_assert_debug(false); outputCount = count + 1; @@ -787,9 +807,13 @@ void LatteIndices_decode(const void* indexData, LatteIndexType indexType, uint32 } } else if (indexType == LatteIndexType::U16_BE) - LatteIndices_unpackTriangleFanAndConvert(indexData, indexOutputPtr, count, indexMax); + LatteIndices_unpackTriangleFanAndConvert(indexData, indexOutputPtr, count, indexMax); else if (indexType == LatteIndexType::U32_BE) - LatteIndices_unpackTriangleFanAndConvert(indexData, indexOutputPtr, count, indexMax); + LatteIndices_unpackTriangleFanAndConvert(indexData, indexOutputPtr, count, indexMax); + else if (indexType == LatteIndexType::U16_LE) + LatteIndices_unpackTriangleFanAndConvert(indexData, indexOutputPtr, count, indexMax); + else if (indexType == LatteIndexType::U32_LE) + LatteIndices_unpackTriangleFanAndConvert(indexData, indexOutputPtr, count, indexMax); else cemu_assert_debug(false); outputCount = count;