aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL/GraphicsPipeline.cs
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2019-10-15 00:10:20 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commitf90ee9b7070dfbf3d6f9713a180b0ec899a039b8 (patch)
tree243227d30c147ffce2e52b4ab42319fe7702cabf /Ryujinx.Graphics.OpenGL/GraphicsPipeline.cs
parentcdeeac163fb134a34c547cf1f45a4dd21daa41ea (diff)
Handle quad and quad strip primitive types using triangle fans
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/GraphicsPipeline.cs')
-rw-r--r--Ryujinx.Graphics.OpenGL/GraphicsPipeline.cs218
1 files changed, 194 insertions, 24 deletions
diff --git a/Ryujinx.Graphics.OpenGL/GraphicsPipeline.cs b/Ryujinx.Graphics.OpenGL/GraphicsPipeline.cs
index e9f6b2fb..e904efed 100644
--- a/Ryujinx.Graphics.OpenGL/GraphicsPipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/GraphicsPipeline.cs
@@ -273,30 +273,82 @@ namespace Ryujinx.Graphics.OpenGL
PrepareForDraw();
- if (firstInstance == 0 && instanceCount == 1)
+ if (_primitiveType == PrimitiveType.Quads)
{
- if (_primitiveType == PrimitiveType.Quads)
- {
- for (int offset = 0; offset < vertexCount; offset += 4)
- {
- GL.DrawArrays(PrimitiveType.TriangleFan, firstVertex + offset, 4);
- }
- }
- else if (_primitiveType == PrimitiveType.QuadStrip)
- {
- GL.DrawArrays(PrimitiveType.TriangleFan, firstVertex, 4);
+ DrawQuadsImpl(vertexCount, instanceCount, firstVertex, firstInstance);
+ }
+ else if (_primitiveType == PrimitiveType.QuadStrip)
+ {
+ DrawQuadStripImpl(vertexCount, instanceCount, firstVertex, firstInstance);
+ }
+ else
+ {
+ DrawImpl(vertexCount, instanceCount, firstVertex, firstInstance);
+ }
+ }
- for (int offset = 2; offset < vertexCount; offset += 2)
- {
- GL.DrawArrays(PrimitiveType.TriangleFan, firstVertex + offset, 4);
- }
- }
- else
- {
- GL.DrawArrays(_primitiveType, firstVertex, vertexCount);
- }
+ private void DrawQuadsImpl(
+ int vertexCount,
+ int instanceCount,
+ int firstVertex,
+ int firstInstance)
+ {
+ // TODO: Instanced rendering.
+ int quadsCount = vertexCount / 4;
+
+ int[] firsts = new int[quadsCount];
+ int[] counts = new int[quadsCount];
+
+ for (int quadIndex = 0; quadIndex < quadsCount; quadIndex++)
+ {
+ firsts[quadIndex] = firstVertex + quadIndex * 4;
+ counts[quadIndex] = 4;
+ }
+
+ GL.MultiDrawArrays(
+ PrimitiveType.TriangleFan,
+ firsts,
+ counts,
+ quadsCount);
+ }
+
+ private void DrawQuadStripImpl(
+ int vertexCount,
+ int instanceCount,
+ int firstVertex,
+ int firstInstance)
+ {
+ // TODO: Instanced rendering.
+ int quadsCount = (vertexCount - 2) / 2;
+
+ int[] firsts = new int[quadsCount];
+ int[] counts = new int[quadsCount];
+
+ firsts[0] = firstVertex;
+ counts[0] = 4;
+
+ for (int quadIndex = 1; quadIndex < quadsCount; quadIndex++)
+ {
+ firsts[quadIndex] = firstVertex + quadIndex * 2;
+ counts[quadIndex] = 4;
+ }
+
+ GL.MultiDrawArrays(
+ PrimitiveType.TriangleFan,
+ firsts,
+ counts,
+ quadsCount);
+ }
- // GL.DrawArrays(_primitiveType, firstVertex, vertexCount);
+ private void DrawImpl(
+ int vertexCount,
+ int instanceCount,
+ int firstVertex,
+ int firstInstance)
+ {
+ if (firstInstance == 0 && instanceCount == 1)
+ {
+ GL.DrawArrays(_primitiveType, firstVertex, vertexCount);
}
else if (firstInstance == 0)
{
@@ -329,14 +381,132 @@ namespace Ryujinx.Graphics.OpenGL
int firstIndexOffset = firstIndex;
+ int indexElemSize = 1;
+
switch (_elementsType)
{
- case DrawElementsType.UnsignedShort: firstIndexOffset *= 2; break;
- case DrawElementsType.UnsignedInt: firstIndexOffset *= 4; break;
+ case DrawElementsType.UnsignedShort: indexElemSize = 2; break;
+ case DrawElementsType.UnsignedInt: indexElemSize = 4; break;
+ }
+
+ IntPtr indexBaseOffset = _indexBaseOffset + firstIndex * indexElemSize;
+
+ if (_primitiveType == PrimitiveType.Quads)
+ {
+ DrawQuadsIndexedImpl(
+ indexCount,
+ instanceCount,
+ indexBaseOffset,
+ indexElemSize,
+ firstVertex,
+ firstInstance);
+ }
+ else if (_primitiveType == PrimitiveType.QuadStrip)
+ {
+ DrawQuadStripIndexedImpl(
+ indexCount,
+ instanceCount,
+ indexBaseOffset,
+ indexElemSize,
+ firstVertex,
+ firstInstance);
+ }
+ else
+ {
+ DrawIndexedImpl(
+ indexCount,
+ instanceCount,
+ indexBaseOffset,
+ indexElemSize,
+ firstVertex,
+ firstInstance);
+ }
+ }
+
+ private void DrawQuadsIndexedImpl(
+ int indexCount,
+ int instanceCount,
+ IntPtr indexBaseOffset,
+ int indexElemSize,
+ int firstVertex,
+ int firstInstance)
+ {
+ // TODO: Instanced rendering.
+ int quadsCount = indexCount / 4;
+
+ IntPtr[] indices = new IntPtr[quadsCount];
+
+ int[] counts = new int[quadsCount];
+
+ int[] baseVertices = new int[quadsCount];
+
+ for (int quadIndex = 0; quadIndex < quadsCount; quadIndex++)
+ {
+ indices[quadIndex] = indexBaseOffset + quadIndex * 4 * indexElemSize;
+
+ counts[quadIndex] = 4;
+
+ baseVertices[quadIndex] = firstVertex;
+ }
+
+ GL.MultiDrawElementsBaseVertex(
+ PrimitiveType.TriangleFan,
+ counts,
+ _elementsType,
+ indices,
+ quadsCount,
+ baseVertices);
+ }
+
+ private void DrawQuadStripIndexedImpl(
+ int indexCount,
+ int instanceCount,
+ IntPtr indexBaseOffset,
+ int indexElemSize,
+ int firstVertex,
+ int firstInstance)
+ {
+ // TODO: Instanced rendering.
+ int quadsCount = (indexCount - 2) / 2;
+
+ IntPtr[] indices = new IntPtr[quadsCount];
+
+ int[] counts = new int[quadsCount];
+
+ int[] baseVertices = new int[quadsCount];
+
+ indices[0] = indexBaseOffset;
+
+ counts[0] = 4;
+
+ baseVertices[0] = firstVertex;
+
+ for (int quadIndex = 1; quadIndex < quadsCount; quadIndex++)
+ {
+ indices[quadIndex] = indexBaseOffset + quadIndex * 2 * indexElemSize;
+
+ counts[quadIndex] = 4;
+
+ baseVertices[quadIndex] = firstVertex;
}
- IntPtr indexBaseOffset = _indexBaseOffset + firstIndexOffset;
+ GL.MultiDrawElementsBaseVertex(
+ PrimitiveType.TriangleFan,
+ counts,
+ _elementsType,
+ indices,
+ quadsCount,
+ baseVertices);
+ }
+ private void DrawIndexedImpl(
+ int indexCount,
+ int instanceCount,
+ IntPtr indexBaseOffset,
+ int indexElemSize,
+ int firstVertex,
+ int firstInstance)
+ {
if (firstInstance == 0 && firstVertex == 0 && instanceCount == 1)
{
GL.DrawElements(_primitiveType, indexCount, _elementsType, indexBaseOffset);