Quads, QuadStrip, const attributes and half-float attributes support (#447)
* Quads, QuadStrip and const attributes support * Add support for half float attributes and fix texture pitch alignment * Throw when an unsupported float type is used as const attribute aswell
This commit is contained in:
parent
dd3cb33c9f
commit
aa1cd849cf
12 changed files with 420 additions and 53 deletions
|
@ -433,7 +433,7 @@ namespace Ryujinx.Graphics
|
|||
|
||||
private void SetRenderTargets()
|
||||
{
|
||||
//Commercial games do not seem to
|
||||
//Commercial games do not seem to
|
||||
//bool SeparateFragData = ReadRegisterBool(NvGpuEngine3dReg.RTSeparateFragData);
|
||||
|
||||
uint Control = (uint)(ReadRegister(NvGpuEngine3dReg.RTControl));
|
||||
|
@ -568,12 +568,15 @@ namespace Ryujinx.Graphics
|
|||
|
||||
private void UploadVertexArrays(NvGpuVmm Vmm, GalPipelineState State)
|
||||
{
|
||||
long IndexPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.IndexArrayAddress);
|
||||
long IbPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.IndexArrayAddress);
|
||||
|
||||
long IboKey = Vmm.GetPhysicalAddress(IndexPosition);
|
||||
long IboKey = Vmm.GetPhysicalAddress(IbPosition);
|
||||
|
||||
int IndexEntryFmt = ReadRegister(NvGpuEngine3dReg.IndexArrayFormat);
|
||||
int IndexCount = ReadRegister(NvGpuEngine3dReg.IndexBatchCount);
|
||||
int PrimCtrl = ReadRegister(NvGpuEngine3dReg.VertexBeginGl);
|
||||
|
||||
GalPrimitiveType PrimType = (GalPrimitiveType)(PrimCtrl & 0xffff);
|
||||
|
||||
GalIndexFormat IndexFormat = (GalIndexFormat)IndexEntryFmt;
|
||||
|
||||
|
@ -590,14 +593,50 @@ namespace Ryujinx.Graphics
|
|||
|
||||
bool IboCached = Gpu.Renderer.Rasterizer.IsIboCached(IboKey, (uint)IbSize);
|
||||
|
||||
bool UsesLegacyQuads =
|
||||
PrimType == GalPrimitiveType.Quads ||
|
||||
PrimType == GalPrimitiveType.QuadStrip;
|
||||
|
||||
if (!IboCached || QueryKeyUpload(Vmm, IboKey, (uint)IbSize, NvGpuBufferType.Index))
|
||||
{
|
||||
IntPtr DataAddress = Vmm.GetHostAddress(IndexPosition, IbSize);
|
||||
if (!UsesLegacyQuads)
|
||||
{
|
||||
IntPtr DataAddress = Vmm.GetHostAddress(IbPosition, IbSize);
|
||||
|
||||
Gpu.Renderer.Rasterizer.CreateIbo(IboKey, IbSize, DataAddress);
|
||||
Gpu.Renderer.Rasterizer.CreateIbo(IboKey, IbSize, DataAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] Buffer = Vmm.ReadBytes(IbPosition, IbSize);
|
||||
|
||||
if (PrimType == GalPrimitiveType.Quads)
|
||||
{
|
||||
Buffer = QuadHelper.ConvertIbQuadsToTris(Buffer, IndexEntrySize, IndexCount);
|
||||
}
|
||||
else /* if (PrimType == GalPrimitiveType.QuadStrip) */
|
||||
{
|
||||
Buffer = QuadHelper.ConvertIbQuadStripToTris(Buffer, IndexEntrySize, IndexCount);
|
||||
}
|
||||
|
||||
Gpu.Renderer.Rasterizer.CreateIbo(IboKey, IbSize, Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
Gpu.Renderer.Rasterizer.SetIndexArray(IbSize, IndexFormat);
|
||||
if (!UsesLegacyQuads)
|
||||
{
|
||||
Gpu.Renderer.Rasterizer.SetIndexArray(IbSize, IndexFormat);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PrimType == GalPrimitiveType.Quads)
|
||||
{
|
||||
Gpu.Renderer.Rasterizer.SetIndexArray(QuadHelper.ConvertIbSizeQuadsToTris(IbSize), IndexFormat);
|
||||
}
|
||||
else /* if (PrimType == GalPrimitiveType.QuadStrip) */
|
||||
{
|
||||
Gpu.Renderer.Rasterizer.SetIndexArray(QuadHelper.ConvertIbSizeQuadStripToTris(IbSize), IndexFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<GalVertexAttrib>[] Attribs = new List<GalVertexAttrib>[32];
|
||||
|
@ -613,10 +652,19 @@ namespace Ryujinx.Graphics
|
|||
Attribs[ArrayIndex] = new List<GalVertexAttrib>();
|
||||
}
|
||||
|
||||
long VertexPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.VertexArrayNAddress + ArrayIndex * 4);
|
||||
|
||||
int Offset = (Packed >> 7) & 0x3fff;
|
||||
|
||||
//Note: 16 is the maximum size of an attribute,
|
||||
//having a component size of 32-bits with 4 elements (a vec4).
|
||||
IntPtr Pointer = Vmm.GetHostAddress(VertexPosition + Offset, 16);
|
||||
|
||||
Attribs[ArrayIndex].Add(new GalVertexAttrib(
|
||||
Attr,
|
||||
((Packed >> 6) & 0x1) != 0,
|
||||
(Packed >> 7) & 0x3fff,
|
||||
Offset,
|
||||
Pointer,
|
||||
(GalVertexAttribSize)((Packed >> 21) & 0x3f),
|
||||
(GalVertexAttribType)((Packed >> 27) & 0x7),
|
||||
((Packed >> 31) & 0x1) != 0));
|
||||
|
@ -722,6 +770,27 @@ namespace Ryujinx.Graphics
|
|||
|
||||
long IboKey = Vmm.GetPhysicalAddress(IndexPosition);
|
||||
|
||||
//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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else /* if (PrimType == GalPrimitiveType.QuadStrip) */
|
||||
{
|
||||
IndexFirst = QuadHelper.ConvertIbSizeQuadStripToTris(IndexFirst);
|
||||
}
|
||||
}
|
||||
|
||||
Gpu.Renderer.Rasterizer.DrawElements(IboKey, IndexFirst, VertexBase, PrimType);
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue