implement triangle fan reindexing

This commit is contained in:
Samuliak 2024-08-07 11:44:16 +02:00
parent ac651eba77
commit d7e9aff230
6 changed files with 141 additions and 79 deletions

View file

@ -7,7 +7,7 @@
#include <immintrin.h>
#endif
struct
struct
{
const void* lastPtr;
uint32 lastCount;
@ -284,6 +284,46 @@ void LatteIndices_generateAutoLineLoopIndices(void* indexDataOutput, uint32 coun
indexMax = std::max(count, 1u) - 1;
}
template<typename T>
void LatteIndices_unpackTriangleFanAndConvert(const void* indexDataInput, void* indexDataOutput, uint32 count, uint32& indexMin, uint32& indexMax)
{
debug_printf("TRIANGLE FAN UNPACK\n");
const betype<T>* src = (betype<T>*)indexDataInput;
T* dst = (T*)indexDataOutput;
// TODO: check this
for (sint32 i = 0; i < count; i++)
{
uint32 i0;
if (i % 2 == 0)
i0 = i / 2;
else
i0 = count - 1 - i / 2;
T idx = src[i0];
indexMin = std::min(indexMin, (uint32)idx);
indexMax = std::max(indexMax, (uint32)idx);
dst[i] = idx;
}
}
template<typename T>
void LatteIndices_generateAutoTriangleFanIndices(const void* indexDataInput, void* indexDataOutput, uint32 count, uint32& indexMin, uint32& indexMax)
{
debug_printf("TRIANGLE FAN AUTO\n");
const betype<T>* src = (betype<T>*)indexDataInput;
T* dst = (T*)indexDataOutput;
for (sint32 i = 0; i < count; i++)
{
T idx = i;
if (idx % 2 == 0)
idx = idx / 2;
else
idx = count - 1 - idx / 2;
dst[i] = idx;
}
indexMin = 0;
indexMax = std::max(count, 1u) - 1;
}
#if defined(ARCH_X86_64)
ATTRIBUTE_AVX2
void LatteIndices_fastConvertU16_AVX2(const void* indexDataInput, void* indexDataOutput, uint32 count, uint32& indexMin, uint32& indexMax)
@ -295,7 +335,7 @@ void LatteIndices_fastConvertU16_AVX2(const void* indexDataInput, void* indexDat
sint32 countRemaining = count & 15;
if (count16)
{
__m256i mMin = _mm256_set_epi16((sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF,
__m256i mMin = _mm256_set_epi16((sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF,
(sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF, (sint16)0xFFFF);
__m256i mMax = _mm256_set_epi16(0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000);
__m256i mShuffle16Swap = _mm256_set_epi8(30, 31, 28, 29, 26, 27, 24, 25, 22, 23, 20, 21, 18, 19, 16, 17, 14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
@ -659,6 +699,29 @@ void LatteIndices_decode(const void* indexData, LatteIndexType indexType, uint32
cemu_assert_debug(false);
outputCount = count + 1;
}
else if (primitiveMode == LattePrimitiveMode::TRIANGLE_FAN && g_renderer->GetType() == RendererAPI::Metal)
{
if (indexType == LatteIndexType::AUTO)
{
if (count <= 0xFFFF)
{
LatteIndices_generateAutoTriangleFanIndices<uint16>(indexData, indexOutputPtr, count, indexMin, indexMax);
renderIndexType = Renderer::INDEX_TYPE::U16;
}
else
{
LatteIndices_generateAutoTriangleFanIndices<uint32>(indexData, indexOutputPtr, count, indexMin, indexMax);
renderIndexType = Renderer::INDEX_TYPE::U32;
}
}
else if (indexType == LatteIndexType::U16_BE)
LatteIndices_unpackTriangleFanAndConvert<uint16>(indexData, indexOutputPtr, count, indexMin, indexMax);
else if (indexType == LatteIndexType::U32_BE)
LatteIndices_unpackTriangleFanAndConvert<uint32>(indexData, indexOutputPtr, count, indexMin, indexMax);
else
cemu_assert_debug(false);
outputCount = count;
}
else
{
if (indexType == LatteIndexType::U16_BE)
@ -671,7 +734,7 @@ void LatteIndices_decode(const void* indexData, LatteIndexType indexType, uint32
else
LatteIndices_convertBE<uint16>(indexData, indexOutputPtr, count, indexMin, indexMax);
#else
LatteIndices_convertBE<uint16>(indexData, indexOutputPtr, count, indexMin, indexMax);
LatteIndices_convertBE<uint16>(indexData, indexOutputPtr, count, indexMin, indexMax);
#endif
}
else if (indexType == LatteIndexType::U32_BE)
@ -682,7 +745,7 @@ void LatteIndices_decode(const void* indexData, LatteIndexType indexType, uint32
else
LatteIndices_convertBE<uint32>(indexData, indexOutputPtr, count, indexMin, indexMax);
#else
LatteIndices_convertBE<uint32>(indexData, indexOutputPtr, count, indexMin, indexMax);
LatteIndices_convertBE<uint32>(indexData, indexOutputPtr, count, indexMin, indexMax);
#endif
}
else if (indexType == LatteIndexType::U16_LE)