Cache vertex and index data aswell, some cleanup
This commit is contained in:
parent
e7a9b0a870
commit
197944f783
5 changed files with 127 additions and 97 deletions
|
@ -68,6 +68,12 @@ namespace ChocolArm64.Memory
|
|||
|
||||
if (Count != 0)
|
||||
{
|
||||
//We shouldn't reset pages that aren't being fully used,
|
||||
//to prevent missing modifications to other parts of the
|
||||
//page that may be accessed later.
|
||||
//This rounds the size down to the nearest page-aligned size.
|
||||
Size = (IntPtr)((long)Size & ~(Granularity - 1));
|
||||
|
||||
ResetWriteWatch(Address, Size);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -23,8 +23,6 @@ namespace Ryujinx.Core.Gpu
|
|||
|
||||
private HashSet<long> FrameBuffers;
|
||||
|
||||
private HashSet<long> ModifiedPages;
|
||||
|
||||
public NvGpuEngine3d(NvGpu Gpu)
|
||||
{
|
||||
this.Gpu = Gpu;
|
||||
|
@ -57,8 +55,6 @@ namespace Ryujinx.Core.Gpu
|
|||
}
|
||||
|
||||
FrameBuffers = new HashSet<long>();
|
||||
|
||||
ModifiedPages = new HashSet<long>();
|
||||
}
|
||||
|
||||
public void CallMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
|
||||
|
@ -287,8 +283,6 @@ namespace Ryujinx.Core.Gpu
|
|||
|
||||
if (NewTexture.Equals(Texture) && !Vmm.IsRegionModified(Tag, Size))
|
||||
{
|
||||
//System.Console.WriteLine("skip upload texture!");
|
||||
|
||||
Gpu.Renderer.BindTexture(Tag, TexIndex);
|
||||
|
||||
return;
|
||||
|
@ -353,11 +347,16 @@ namespace Ryujinx.Core.Gpu
|
|||
|
||||
if (IndexSize != 0)
|
||||
{
|
||||
int BufferSize = IndexCount * IndexSize;
|
||||
int IbSize = IndexCount * IndexSize;
|
||||
|
||||
byte[] Data = Vmm.ReadBytes(IndexPosition, BufferSize);
|
||||
if (Vmm.IsRegionModified(IndexPosition, (uint)IbSize))
|
||||
{
|
||||
byte[] Data = Vmm.ReadBytes(IndexPosition, IbSize);
|
||||
|
||||
Gpu.Renderer.SetIndexArray(Data, IndexFormat);
|
||||
Gpu.Renderer.CreateIbo(IndexPosition, Data);
|
||||
}
|
||||
|
||||
Gpu.Renderer.SetIndexArray(IndexPosition, IbSize, IndexFormat);
|
||||
}
|
||||
|
||||
List<GalVertexAttrib>[] Attribs = new List<GalVertexAttrib>[32];
|
||||
|
@ -382,10 +381,17 @@ namespace Ryujinx.Core.Gpu
|
|||
((Packed >> 31) & 0x1) != 0));
|
||||
}
|
||||
|
||||
int VertexFirst = ReadRegister(NvGpuEngine3dReg.VertexArrayFirst);
|
||||
int VertexCount = ReadRegister(NvGpuEngine3dReg.VertexArrayCount);
|
||||
|
||||
int PrimCtrl = ReadRegister(NvGpuEngine3dReg.VertexBeginGl);
|
||||
|
||||
for (int Index = 0; Index < 32; Index++)
|
||||
{
|
||||
int VertexFirst = ReadRegister(NvGpuEngine3dReg.VertexArrayFirst);
|
||||
int VertexCount = ReadRegister(NvGpuEngine3dReg.VertexArrayCount);
|
||||
if (Attribs[Index] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int Control = ReadRegister(NvGpuEngine3dReg.VertexArrayNControl + Index * 4);
|
||||
|
||||
|
@ -401,35 +407,36 @@ namespace Ryujinx.Core.Gpu
|
|||
|
||||
int Stride = Control & 0xfff;
|
||||
|
||||
long Size = 0;
|
||||
long VbSize = 0;
|
||||
|
||||
if (IndexCount != 0)
|
||||
{
|
||||
Size = (VertexEndPos - VertexPosition) + 1;
|
||||
VbSize = (VertexEndPos - VertexPosition) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Size = VertexCount * Stride;
|
||||
VbSize = VertexCount * Stride;
|
||||
}
|
||||
|
||||
byte[] Data = Vmm.ReadBytes(VertexPosition, Size);
|
||||
|
||||
GalVertexAttrib[] AttribArray = Attribs[Index]?.ToArray() ?? new GalVertexAttrib[0];
|
||||
|
||||
Gpu.Renderer.SetVertexArray(Index, Stride, Data, AttribArray);
|
||||
|
||||
int PrimCtrl = ReadRegister(NvGpuEngine3dReg.VertexBeginGl);
|
||||
|
||||
GalPrimitiveType PrimType = (GalPrimitiveType)(PrimCtrl & 0xffff);
|
||||
|
||||
if (IndexCount != 0)
|
||||
if (Vmm.IsRegionModified(VertexPosition, VbSize))
|
||||
{
|
||||
Gpu.Renderer.DrawElements(Index, IndexFirst, PrimType);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gpu.Renderer.DrawArrays(Index, VertexFirst, VertexCount, PrimType);
|
||||
byte[] Data = Vmm.ReadBytes(VertexPosition, VbSize);
|
||||
|
||||
Gpu.Renderer.CreateVbo(VertexPosition, Data);
|
||||
}
|
||||
|
||||
Gpu.Renderer.SetVertexArray(Index, Stride, VertexPosition, Attribs[Index].ToArray());
|
||||
}
|
||||
|
||||
GalPrimitiveType PrimType = (GalPrimitiveType)(PrimCtrl & 0xffff);
|
||||
|
||||
if (IndexCount != 0)
|
||||
{
|
||||
Gpu.Renderer.DrawElements(IndexPosition, IndexFirst, PrimType);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gpu.Renderer.DrawArrays(VertexFirst, VertexCount, PrimType);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,13 +49,17 @@ namespace Ryujinx.Graphics.Gal
|
|||
//Rasterizer
|
||||
void ClearBuffers(int RtIndex, GalClearBufferFlags Flags);
|
||||
|
||||
void SetVertexArray(int VbIndex, int Stride, byte[] Buffer, GalVertexAttrib[] Attribs);
|
||||
void CreateVbo(long Tag, byte[] Buffer);
|
||||
|
||||
void SetIndexArray(byte[] Buffer, GalIndexFormat Format);
|
||||
void CreateIbo(long Tag, byte[] Buffer);
|
||||
|
||||
void DrawArrays(int VbIndex, int First, int PrimCount, GalPrimitiveType PrimType);
|
||||
void SetVertexArray(int VbIndex, int Stride, long VboTag, GalVertexAttrib[] Attribs);
|
||||
|
||||
void DrawElements(int VbIndex, int First, GalPrimitiveType PrimType);
|
||||
void SetIndexArray(long Tag, int Size, GalIndexFormat Format);
|
||||
|
||||
void DrawArrays(int First, int PrimCount, GalPrimitiveType PrimType);
|
||||
|
||||
void DrawElements(long IboTag, int First, GalPrimitiveType PrimType);
|
||||
|
||||
//Shader
|
||||
void CreateShader(IGalMemory Memory, long Tag, GalShaderType Type);
|
||||
|
|
|
@ -46,7 +46,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
private struct IbInfo
|
||||
{
|
||||
public int IboHandle;
|
||||
public int Count;
|
||||
|
||||
public DrawElementsType Type;
|
||||
|
@ -56,12 +55,18 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
private int[] VertexBuffers;
|
||||
|
||||
private Dictionary<long, int> VboCache;
|
||||
private Dictionary<long, int> IboCache;
|
||||
|
||||
private IbInfo IndexBuffer;
|
||||
|
||||
public OGLRasterizer()
|
||||
{
|
||||
VertexBuffers = new int[32];
|
||||
|
||||
VboCache = new Dictionary<long, int>();
|
||||
IboCache = new Dictionary<long, int>();
|
||||
|
||||
IndexBuffer = new IbInfo();
|
||||
}
|
||||
|
||||
|
@ -92,15 +97,49 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
GL.Clear(Mask);
|
||||
}
|
||||
|
||||
public void SetVertexArray(int VbIndex, int Stride, byte[] Buffer, GalVertexAttrib[] Attribs)
|
||||
public void CreateVbo(long Tag, byte[] Buffer)
|
||||
{
|
||||
EnsureVbInitialized(VbIndex);
|
||||
if (!VboCache.TryGetValue(Tag, out int Handle))
|
||||
{
|
||||
Handle = GL.GenBuffer();
|
||||
|
||||
VboCache.Add(Tag, Handle);
|
||||
}
|
||||
|
||||
IntPtr Length = new IntPtr(Buffer.Length);
|
||||
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBuffers[VbIndex]);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, Handle);
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, Length, Buffer, BufferUsageHint.StreamDraw);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||
}
|
||||
|
||||
public void CreateIbo(long Tag, byte[] Buffer)
|
||||
{
|
||||
if (!IboCache.TryGetValue(Tag, out int Handle))
|
||||
{
|
||||
Handle = GL.GenBuffer();
|
||||
|
||||
IboCache.Add(Tag, Handle);
|
||||
}
|
||||
|
||||
IntPtr Length = new IntPtr(Buffer.Length);
|
||||
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, Handle);
|
||||
GL.BufferData(BufferTarget.ElementArrayBuffer, Length, Buffer, BufferUsageHint.StreamDraw);
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
|
||||
}
|
||||
|
||||
public void SetVertexArray(int VbIndex, int Stride, long VboTag, GalVertexAttrib[] Attribs)
|
||||
{
|
||||
if (!VboCache.TryGetValue(VboTag, out int VboHandle))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (VaoHandle == 0)
|
||||
{
|
||||
VaoHandle = GL.GenVertexArray();
|
||||
}
|
||||
|
||||
GL.BindVertexArray(VaoHandle);
|
||||
|
||||
|
@ -108,7 +147,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
{
|
||||
GL.EnableVertexAttribArray(Attrib.Index);
|
||||
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBuffers[VbIndex]);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle);
|
||||
|
||||
bool Unsigned =
|
||||
Attrib.Type == GalVertexAttribType.Unorm ||
|
||||
|
@ -139,22 +178,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
GL.BindVertexArray(0);
|
||||
}
|
||||
|
||||
public void SetIndexArray(byte[] Buffer, GalIndexFormat Format)
|
||||
public void SetIndexArray(long Tag, int Size, GalIndexFormat Format)
|
||||
{
|
||||
EnsureIbInitialized();
|
||||
|
||||
IndexBuffer.Type = OGLEnumConverter.GetDrawElementsType(Format);
|
||||
|
||||
IndexBuffer.Count = Buffer.Length >> (int)Format;
|
||||
|
||||
IntPtr Length = new IntPtr(Buffer.Length);
|
||||
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, IndexBuffer.IboHandle);
|
||||
GL.BufferData(BufferTarget.ElementArrayBuffer, Length, Buffer, BufferUsageHint.StreamDraw);
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
|
||||
IndexBuffer.Count = Size >> (int)Format;
|
||||
}
|
||||
|
||||
public void DrawArrays(int VbIndex, int First, int PrimCount, GalPrimitiveType PrimType)
|
||||
public void DrawArrays(int First, int PrimCount, GalPrimitiveType PrimType)
|
||||
{
|
||||
if (PrimCount == 0)
|
||||
{
|
||||
|
@ -166,36 +197,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
GL.DrawArrays(OGLEnumConverter.GetPrimitiveType(PrimType), First, PrimCount);
|
||||
}
|
||||
|
||||
public void DrawElements(int VbIndex, int First, GalPrimitiveType PrimType)
|
||||
public void DrawElements(long IboTag, int First, GalPrimitiveType PrimType)
|
||||
{
|
||||
if (!IboCache.TryGetValue(IboTag, out int IboHandle))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PrimitiveType Mode = OGLEnumConverter.GetPrimitiveType(PrimType);
|
||||
|
||||
GL.BindVertexArray(VaoHandle);
|
||||
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, IndexBuffer.IboHandle);
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, IboHandle);
|
||||
|
||||
GL.DrawElements(Mode, IndexBuffer.Count, IndexBuffer.Type, First);
|
||||
}
|
||||
|
||||
private void EnsureVbInitialized(int VbIndex)
|
||||
{
|
||||
if (VaoHandle == 0)
|
||||
{
|
||||
VaoHandle = GL.GenVertexArray();
|
||||
}
|
||||
|
||||
if (VertexBuffers[VbIndex] == 0)
|
||||
{
|
||||
VertexBuffers[VbIndex] = GL.GenBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureIbInitialized()
|
||||
{
|
||||
if (IndexBuffer.IboHandle == 0)
|
||||
{
|
||||
IndexBuffer.IboHandle = GL.GenBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -156,46 +156,44 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
ActionsQueue.Enqueue(() => Rasterizer.ClearBuffers(RtIndex, Flags));
|
||||
}
|
||||
|
||||
public void SetVertexArray(int VbIndex, int Stride, byte[] Buffer, GalVertexAttrib[] Attribs)
|
||||
public void CreateVbo(long Tag, byte[] Buffer)
|
||||
{
|
||||
ActionsQueue.Enqueue(() => Rasterizer.CreateVbo(Tag, Buffer));
|
||||
}
|
||||
|
||||
public void CreateIbo(long Tag, byte[] Buffer)
|
||||
{
|
||||
ActionsQueue.Enqueue(() => Rasterizer.CreateIbo(Tag, Buffer));
|
||||
}
|
||||
|
||||
public void SetVertexArray(int VbIndex, int Stride, long VboTag, GalVertexAttrib[] Attribs)
|
||||
{
|
||||
if ((uint)VbIndex > 31)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(VbIndex));
|
||||
}
|
||||
|
||||
ActionsQueue.Enqueue(() => Rasterizer.SetVertexArray(VbIndex, Stride,
|
||||
Buffer ?? throw new ArgumentNullException(nameof(Buffer)),
|
||||
Attribs ?? throw new ArgumentNullException(nameof(Attribs))));
|
||||
}
|
||||
|
||||
public void SetIndexArray(byte[] Buffer, GalIndexFormat Format)
|
||||
{
|
||||
if (Buffer == null)
|
||||
if (Attribs == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(Buffer));
|
||||
throw new ArgumentNullException(nameof(Attribs));
|
||||
}
|
||||
|
||||
ActionsQueue.Enqueue(() => Rasterizer.SetIndexArray(Buffer, Format));
|
||||
ActionsQueue.Enqueue(() => Rasterizer.SetVertexArray(VbIndex, Stride, VboTag, Attribs));
|
||||
}
|
||||
|
||||
public void DrawArrays(int VbIndex, int First, int PrimCount, GalPrimitiveType PrimType)
|
||||
public void SetIndexArray(long Tag, int Size, GalIndexFormat Format)
|
||||
{
|
||||
if ((uint)VbIndex > 31)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(VbIndex));
|
||||
}
|
||||
|
||||
ActionsQueue.Enqueue(() => Rasterizer.DrawArrays(VbIndex, First, PrimCount, PrimType));
|
||||
ActionsQueue.Enqueue(() => Rasterizer.SetIndexArray(Tag, Size, Format));
|
||||
}
|
||||
|
||||
public void DrawElements(int VbIndex, int First, GalPrimitiveType PrimType)
|
||||
public void DrawArrays(int First, int PrimCount, GalPrimitiveType PrimType)
|
||||
{
|
||||
if ((uint)VbIndex > 31)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(VbIndex));
|
||||
}
|
||||
ActionsQueue.Enqueue(() => Rasterizer.DrawArrays(First, PrimCount, PrimType));
|
||||
}
|
||||
|
||||
ActionsQueue.Enqueue(() => Rasterizer.DrawElements(VbIndex, First, PrimType));
|
||||
public void DrawElements(long IboTag, int First, GalPrimitiveType PrimType)
|
||||
{
|
||||
ActionsQueue.Enqueue(() => Rasterizer.DrawElements(IboTag, First, PrimType));
|
||||
}
|
||||
|
||||
public void CreateShader(IGalMemory Memory, long Tag, GalShaderType Type)
|
||||
|
|
Loading…
Add table
Reference in a new issue