aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gpu
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-04-29 17:58:38 -0300
committergdkchan <gab.dark.100@gmail.com>2018-04-29 17:58:38 -0300
commitf73a182b20970f993abc1f1329dfab1e5d3b3354 (patch)
treead46e02d29560b013713291f236b953a601e2d5f /Ryujinx.Graphics/Gpu
parent17f4ccf2d552b9646097282818d82525a3d902cf (diff)
Properly support multiple vertex buffers, stub 2 ioctls, fix a shader issue, change the way how the vertex buffer size is calculated for the buffers with limit = 0
Diffstat (limited to 'Ryujinx.Graphics/Gpu')
-rw-r--r--Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs81
1 files changed, 77 insertions, 4 deletions
diff --git a/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs b/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs
index bf04db36..a6696650 100644
--- a/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs
+++ b/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs
@@ -351,6 +351,7 @@ namespace Ryujinx.Graphics.Gpu
}
Attribs[ArrayIndex].Add(new GalVertexAttrib(
+ Attr,
((Packed >> 6) & 0x1) != 0,
(Packed >> 7) & 0x3fff,
(GalVertexAttribSize)((Packed >> 21) & 0x3f),
@@ -367,17 +368,33 @@ namespace Ryujinx.Graphics.Gpu
bool Enable = (Control & 0x1000) != 0;
+ long VertexPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.VertexArrayNAddress + Index * 4);
+
if (!Enable)
{
continue;
}
- long VertexPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.VertexArrayNAddress + Index * 4);
- long VertexEndPos = MakeInt64From2xInt32(NvGpuEngine3dReg.VertexArrayNEndAddr + Index * 4);
+ int Stride = Control & 0xfff;
- long Size = (VertexEndPos - VertexPosition) + 1;
+ long Size = 0;
- int Stride = Control & 0xfff;
+ if (IndexCount != 0)
+ {
+ Size = GetVertexCountFromIndexBuffer(
+ Memory,
+ IndexPosition,
+ IndexCount,
+ IndexSize);
+ }
+ else
+ {
+ Size = VertexCount;
+ }
+
+ //TODO: Support cases where the Stride is 0.
+ //In this case, we need to use the size of the attribute.
+ Size *= Stride;
VertexPosition = Gpu.GetCpuAddr(VertexPosition);
@@ -402,6 +419,62 @@ namespace Ryujinx.Graphics.Gpu
}
}
+ private int GetVertexCountFromIndexBuffer(
+ AMemory Memory,
+ long IndexPosition,
+ int IndexCount,
+ int IndexSize)
+ {
+ int MaxIndex = -1;
+
+ if (IndexSize == 2)
+ {
+ while (IndexCount -- > 0)
+ {
+ ushort Value = Memory.ReadUInt16(IndexPosition);
+
+ IndexPosition += 2;
+
+ if (MaxIndex < Value)
+ {
+ MaxIndex = Value;
+ }
+ }
+ }
+ else if (IndexSize == 1)
+ {
+ while (IndexCount -- > 0)
+ {
+ byte Value = Memory.ReadByte(IndexPosition++);
+
+ if (MaxIndex < Value)
+ {
+ MaxIndex = Value;
+ }
+ }
+ }
+ else if (IndexSize == 4)
+ {
+ while (IndexCount -- > 0)
+ {
+ uint Value = Memory.ReadUInt32(IndexPosition);
+
+ IndexPosition += 2;
+
+ if (MaxIndex < Value)
+ {
+ MaxIndex = (int)Value;
+ }
+ }
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(IndexSize));
+ }
+
+ return MaxIndex + 1;
+ }
+
private void QueryControl(AMemory Memory, NsGpuPBEntry PBEntry)
{
if (TryGetCpuAddr(NvGpuEngine3dReg.QueryAddress, out long Position))