diff options
author | gdk <gab.dark.100@gmail.com> | 2019-10-15 00:10:20 -0300 |
---|---|---|
committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
commit | f90ee9b7070dfbf3d6f9713a180b0ec899a039b8 (patch) | |
tree | 243227d30c147ffce2e52b4ab42319fe7702cabf /Ryujinx.Graphics.OpenGL/GraphicsPipeline.cs | |
parent | cdeeac163fb134a34c547cf1f45a4dd21daa41ea (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.cs | 218 |
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); |