|
@@ -691,11 +691,11 @@ namespace Ryujinx.Graphics.Graphics3d
|
|
|
|
|
|
|
|
if (PrimType == GalPrimitiveType.Quads)
|
|
if (PrimType == GalPrimitiveType.Quads)
|
|
|
{
|
|
{
|
|
|
- Buffer = QuadHelper.ConvertIbQuadsToTris(Buffer, IndexEntrySize, IndexCount);
|
|
|
|
|
|
|
+ Buffer = QuadHelper.ConvertQuadsToTris(Buffer, IndexEntrySize, IndexCount);
|
|
|
}
|
|
}
|
|
|
else /* if (PrimType == GalPrimitiveType.QuadStrip) */
|
|
else /* if (PrimType == GalPrimitiveType.QuadStrip) */
|
|
|
{
|
|
{
|
|
|
- Buffer = QuadHelper.ConvertIbQuadStripToTris(Buffer, IndexEntrySize, IndexCount);
|
|
|
|
|
|
|
+ Buffer = QuadHelper.ConvertQuadStripToTris(Buffer, IndexEntrySize, IndexCount);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Gpu.Renderer.Rasterizer.CreateIbo(IboKey, IbSize, Buffer);
|
|
Gpu.Renderer.Rasterizer.CreateIbo(IboKey, IbSize, Buffer);
|
|
@@ -710,11 +710,11 @@ namespace Ryujinx.Graphics.Graphics3d
|
|
|
{
|
|
{
|
|
|
if (PrimType == GalPrimitiveType.Quads)
|
|
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) */
|
|
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 VboKey = Vmm.GetPhysicalAddress(VbPosition);
|
|
|
|
|
|
|
|
long VbSize = (VbEndPos - VbPosition) + 1;
|
|
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 (!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);
|
|
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,
|
|
//Quad primitive types were deprecated on OpenGL 3.x,
|
|
|
//they are converted to a triangles index buffer on IB creation,
|
|
//they are converted to a triangles index buffer on IB creation,
|
|
|
//so we should use the triangles type here too.
|
|
//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
|
|
//Note: We assume that index first points to the first
|
|
|
//vertex of a quad, if it points to the middle of a
|
|
//vertex of a quad, if it points to the middle of a
|
|
|
//quad (First % 4 != 0 for Quads) then it will not work properly.
|
|
//quad (First % 4 != 0 for Quads) then it will not work properly.
|
|
|
if (PrimType == GalPrimitiveType.Quads)
|
|
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);
|
|
Gpu.Renderer.Rasterizer.DrawElements(IboKey, IndexFirst, VertexBase, PrimType);
|
|
@@ -888,6 +917,27 @@ namespace Ryujinx.Graphics.Graphics3d
|
|
|
int VertexFirst = ReadRegister(NvGpuEngine3dReg.VertexArrayFirst);
|
|
int VertexFirst = ReadRegister(NvGpuEngine3dReg.VertexArrayFirst);
|
|
|
int VertexCount = ReadRegister(NvGpuEngine3dReg.VertexArrayCount);
|
|
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);
|
|
Gpu.Renderer.Rasterizer.DrawArrays(VertexFirst, VertexCount, PrimType);
|
|
|
}
|
|
}
|
|
|
|
|
|