aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Graphics/Graphics3d/NvGpuEngine3d.cs76
-rw-r--r--Ryujinx.Graphics/QuadHelper.cs8
2 files changed, 67 insertions, 17 deletions
diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuEngine3d.cs b/Ryujinx.Graphics/Graphics3d/NvGpuEngine3d.cs
index fefd2e67..dc1eec3b 100644
--- a/Ryujinx.Graphics/Graphics3d/NvGpuEngine3d.cs
+++ b/Ryujinx.Graphics/Graphics3d/NvGpuEngine3d.cs
@@ -691,11 +691,11 @@ namespace Ryujinx.Graphics.Graphics3d
if (PrimType == GalPrimitiveType.Quads)
{
- Buffer = QuadHelper.ConvertIbQuadsToTris(Buffer, IndexEntrySize, IndexCount);
+ Buffer = QuadHelper.ConvertQuadsToTris(Buffer, IndexEntrySize, IndexCount);
}
else /* if (PrimType == GalPrimitiveType.QuadStrip) */
{
- Buffer = QuadHelper.ConvertIbQuadStripToTris(Buffer, IndexEntrySize, IndexCount);
+ Buffer = QuadHelper.ConvertQuadStripToTris(Buffer, IndexEntrySize, IndexCount);
}
Gpu.Renderer.Rasterizer.CreateIbo(IboKey, IbSize, Buffer);
@@ -710,11 +710,11 @@ namespace Ryujinx.Graphics.Graphics3d
{
if (PrimType == GalPrimitiveType.Quads)
{
- Gpu.Renderer.Rasterizer.SetIndexArray(QuadHelper.ConvertIbSizeQuadsToTris(IbSize), IndexFormat);
+ Gpu.Renderer.Rasterizer.SetIndexArray(QuadHelper.ConvertSizeQuadsToTris(IbSize), IndexFormat);
}
else /* if (PrimType == GalPrimitiveType.QuadStrip) */
{
- Gpu.Renderer.Rasterizer.SetIndexArray(QuadHelper.ConvertIbSizeQuadStripToTris(IbSize), IndexFormat);
+ Gpu.Renderer.Rasterizer.SetIndexArray(QuadHelper.ConvertSizeQuadStripToTris(IbSize), IndexFormat);
}
}
}
@@ -796,12 +796,42 @@ namespace Ryujinx.Graphics.Graphics3d
long VboKey = Vmm.GetPhysicalAddress(VbPosition);
long VbSize = (VbEndPos - VbPosition) + 1;
+ int ModifiedVbSize = (int)VbSize;
- bool VboCached = Gpu.Renderer.Rasterizer.IsVboCached(VboKey, VbSize);
+
+ // If quads convert size to triangle length
+ if (Stride == 0)
+ {
+ if (PrimType == GalPrimitiveType.Quads)
+ {
+ ModifiedVbSize = QuadHelper.ConvertSizeQuadsToTris(ModifiedVbSize);
+ }
+ else if (PrimType == GalPrimitiveType.QuadStrip)
+ {
+ ModifiedVbSize = QuadHelper.ConvertSizeQuadStripToTris(ModifiedVbSize);
+ }
+ }
+
+ bool VboCached = Gpu.Renderer.Rasterizer.IsVboCached(VboKey, ModifiedVbSize);
if (!VboCached || Gpu.ResourceManager.MemoryRegionModified(Vmm, VboKey, VbSize, NvGpuBufferType.Vertex))
{
- if (Vmm.TryGetHostAddress(VbPosition, VbSize, out IntPtr VbPtr))
+ if ((PrimType == GalPrimitiveType.Quads | PrimType == GalPrimitiveType.QuadStrip) && Stride != 0)
+ {
+ // Convert quad buffer to triangles
+ byte[] data = Vmm.ReadBytes(VbPosition, VbSize);
+
+ if (PrimType == GalPrimitiveType.Quads)
+ {
+ data = QuadHelper.ConvertQuadsToTris(data, Stride, (int)(VbSize / Stride));
+ }
+ else
+ {
+ data = QuadHelper.ConvertQuadStripToTris(data, Stride, (int)(VbSize / Stride));
+ }
+ Gpu.Renderer.Rasterizer.CreateVbo(VboKey, data);
+ }
+ else if (Vmm.TryGetHostAddress(VbPosition, VbSize, out IntPtr VbPtr))
{
Gpu.Renderer.Rasterizer.CreateVbo(VboKey, (int)VbSize, VbPtr);
}
@@ -863,22 +893,21 @@ namespace Ryujinx.Graphics.Graphics3d
//Quad primitive types were deprecated on OpenGL 3.x,
//they are converted to a triangles index buffer on IB creation,
//so we should use the triangles type here too.
- if (PrimType == GalPrimitiveType.Quads ||
- PrimType == GalPrimitiveType.QuadStrip)
+ if (PrimType == GalPrimitiveType.Quads || PrimType == GalPrimitiveType.QuadStrip)
{
- PrimType = GalPrimitiveType.Triangles;
-
//Note: We assume that index first points to the first
//vertex of a quad, if it points to the middle of a
//quad (First % 4 != 0 for Quads) then it will not work properly.
if (PrimType == GalPrimitiveType.Quads)
{
- IndexFirst = QuadHelper.ConvertIbSizeQuadsToTris(IndexFirst);
+ IndexFirst = QuadHelper.ConvertSizeQuadsToTris(IndexFirst);
}
- else /* if (PrimType == GalPrimitiveType.QuadStrip) */
+ else // QuadStrip
{
- IndexFirst = QuadHelper.ConvertIbSizeQuadStripToTris(IndexFirst);
+ IndexFirst = QuadHelper.ConvertSizeQuadStripToTris(IndexFirst);
}
+
+ PrimType = GalPrimitiveType.Triangles;
}
Gpu.Renderer.Rasterizer.DrawElements(IboKey, IndexFirst, VertexBase, PrimType);
@@ -888,6 +917,27 @@ namespace Ryujinx.Graphics.Graphics3d
int VertexFirst = ReadRegister(NvGpuEngine3dReg.VertexArrayFirst);
int VertexCount = ReadRegister(NvGpuEngine3dReg.VertexArrayCount);
+ //Quad primitive types were deprecated on OpenGL 3.x,
+ //they are converted to a triangles index buffer on IB creation,
+ //so we should use the triangles type here too.
+ if (PrimType == GalPrimitiveType.Quads || PrimType == GalPrimitiveType.QuadStrip)
+ {
+ //Note: We assume that index first points to the first
+ //vertex of a quad, if it points to the middle of a
+ //quad (First % 4 != 0 for Quads) then it will not work properly.
+ if (PrimType == GalPrimitiveType.Quads)
+ {
+ VertexFirst = QuadHelper.ConvertSizeQuadsToTris(VertexFirst);
+ }
+ else // QuadStrip
+ {
+ VertexFirst = QuadHelper.ConvertSizeQuadStripToTris(VertexFirst);
+ }
+
+ PrimType = GalPrimitiveType.Triangles;
+ VertexCount = QuadHelper.ConvertSizeQuadsToTris(VertexCount);
+ }
+
Gpu.Renderer.Rasterizer.DrawArrays(VertexFirst, VertexCount, PrimType);
}
diff --git a/Ryujinx.Graphics/QuadHelper.cs b/Ryujinx.Graphics/QuadHelper.cs
index 0dfffce0..d5fea9ab 100644
--- a/Ryujinx.Graphics/QuadHelper.cs
+++ b/Ryujinx.Graphics/QuadHelper.cs
@@ -4,17 +4,17 @@ namespace Ryujinx.Graphics
{
static class QuadHelper
{
- public static int ConvertIbSizeQuadsToTris(int Size)
+ public static int ConvertSizeQuadsToTris(int Size)
{
return Size <= 0 ? 0 : (Size / 4) * 6;
}
- public static int ConvertIbSizeQuadStripToTris(int Size)
+ public static int ConvertSizeQuadStripToTris(int Size)
{
return Size <= 1 ? 0 : ((Size - 2) / 2) * 6;
}
- public static byte[] ConvertIbQuadsToTris(byte[] Data, int EntrySize, int Count)
+ public static byte[] ConvertQuadsToTris(byte[] Data, int EntrySize, int Count)
{
int PrimitivesCount = Count / 4;
@@ -46,7 +46,7 @@ namespace Ryujinx.Graphics
return Output;
}
- public static byte[] ConvertIbQuadStripToTris(byte[] Data, int EntrySize, int Count)
+ public static byte[] ConvertQuadStripToTris(byte[] Data, int EntrySize, int Count)
{
int PrimitivesCount = (Count - 2) / 2;