summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/IndexGenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoCommon/IndexGenerator.cpp')
-rw-r--r--Source/Core/VideoCommon/IndexGenerator.cpp98
1 files changed, 91 insertions, 7 deletions
diff --git a/Source/Core/VideoCommon/IndexGenerator.cpp b/Source/Core/VideoCommon/IndexGenerator.cpp
index be2dc99e3a..5d86561ffd 100644
--- a/Source/Core/VideoCommon/IndexGenerator.cpp
+++ b/Source/Core/VideoCommon/IndexGenerator.cpp
@@ -190,6 +190,39 @@ u16* AddLineStrip(u16* index_ptr, u32 num_verts, u32 index)
return index_ptr;
}
+template <bool pr, bool linestrip>
+u16* AddLines_VSExpand(u16* index_ptr, u32 num_verts, u32 index)
+{
+ // VS Expand uses (index >> 2) as the base vertex
+ // Bit 0 indicates which side of the line (left/right for a vertical line)
+ // Bit 1 indicates which point of the line (top/bottom for a vertical line)
+ // VS Expand assumes the two points will be adjacent vertices
+ constexpr u32 advance = linestrip ? 1 : 2;
+ for (u32 i = 1; i < num_verts; i += advance)
+ {
+ u32 p0 = (index + i - 1) << 2;
+ u32 p1 = (index + i - 0) << 2;
+ if constexpr (pr)
+ {
+ *index_ptr++ = p0 + 0;
+ *index_ptr++ = p0 + 1;
+ *index_ptr++ = p1 + 2;
+ *index_ptr++ = p1 + 3;
+ *index_ptr++ = s_primitive_restart;
+ }
+ else
+ {
+ *index_ptr++ = p0 + 0;
+ *index_ptr++ = p0 + 1;
+ *index_ptr++ = p1 + 2;
+ *index_ptr++ = p0 + 1;
+ *index_ptr++ = p1 + 2;
+ *index_ptr++ = p1 + 3;
+ }
+ }
+ return index_ptr;
+}
+
u16* AddPoints(u16* index_ptr, u32 num_verts, u32 index)
{
for (u32 i = 0; i != num_verts; ++i)
@@ -198,6 +231,35 @@ u16* AddPoints(u16* index_ptr, u32 num_verts, u32 index)
}
return index_ptr;
}
+
+template <bool pr>
+u16* AddPoints_VSExpand(u16* index_ptr, u32 num_verts, u32 index)
+{
+ // VS Expand uses (index >> 2) as the base vertex
+ // Bottom two bits indicate which of (TL, TR, BL, BR) this is
+ for (u32 i = 0; i < num_verts; ++i)
+ {
+ u32 base = (index + i) << 2;
+ if constexpr (pr)
+ {
+ *index_ptr++ = base + 0;
+ *index_ptr++ = base + 1;
+ *index_ptr++ = base + 2;
+ *index_ptr++ = base + 3;
+ *index_ptr++ = s_primitive_restart;
+ }
+ else
+ {
+ *index_ptr++ = base + 0;
+ *index_ptr++ = base + 1;
+ *index_ptr++ = base + 2;
+ *index_ptr++ = base + 1;
+ *index_ptr++ = base + 2;
+ *index_ptr++ = base + 3;
+ }
+ }
+ return index_ptr;
+}
} // Anonymous namespace
void IndexGenerator::Init()
@@ -220,9 +282,27 @@ void IndexGenerator::Init()
m_primitive_table[Primitive::GX_DRAW_TRIANGLE_STRIP] = AddStrip<false>;
m_primitive_table[Primitive::GX_DRAW_TRIANGLE_FAN] = AddFan<false>;
}
- m_primitive_table[Primitive::GX_DRAW_LINES] = AddLineList;
- m_primitive_table[Primitive::GX_DRAW_LINE_STRIP] = AddLineStrip;
- m_primitive_table[Primitive::GX_DRAW_POINTS] = AddPoints;
+ if (g_Config.UseVSForLinePointExpand())
+ {
+ if (g_Config.backend_info.bSupportsPrimitiveRestart)
+ {
+ m_primitive_table[Primitive::GX_DRAW_LINES] = AddLines_VSExpand<true, false>;
+ m_primitive_table[Primitive::GX_DRAW_LINE_STRIP] = AddLines_VSExpand<true, true>;
+ m_primitive_table[Primitive::GX_DRAW_POINTS] = AddPoints_VSExpand<true>;
+ }
+ else
+ {
+ m_primitive_table[Primitive::GX_DRAW_LINES] = AddLines_VSExpand<false, false>;
+ m_primitive_table[Primitive::GX_DRAW_LINE_STRIP] = AddLines_VSExpand<false, true>;
+ m_primitive_table[Primitive::GX_DRAW_POINTS] = AddPoints_VSExpand<false>;
+ }
+ }
+ else
+ {
+ m_primitive_table[Primitive::GX_DRAW_LINES] = AddLineList;
+ m_primitive_table[Primitive::GX_DRAW_LINE_STRIP] = AddLineStrip;
+ m_primitive_table[Primitive::GX_DRAW_POINTS] = AddPoints;
+ }
}
void IndexGenerator::Start(u16* index_ptr)
@@ -246,10 +326,14 @@ void IndexGenerator::AddExternalIndices(const u16* indices, u32 num_indices, u32
m_base_index += num_vertices;
}
-u32 IndexGenerator::GetRemainingIndices() const
+u32 IndexGenerator::GetRemainingIndices(OpcodeDecoder::Primitive primitive) const
{
- // -1 is reserved for primitive restart (OGL + DX11)
- constexpr u32 max_index = 65534;
+ u32 max_index = USHRT_MAX;
+
+ if (g_Config.UseVSForLinePointExpand() && primitive >= OpcodeDecoder::Primitive::GX_DRAW_LINES)
+ max_index >>= 2;
+
+ // -1 is reserved for primitive restart
- return max_index - m_base_index;
+ return max_index - m_base_index - 1;
}