Replace OGL buffer streaming from SubData to MapAndOprhan

This commit is contained in:
ReinUsesLisp 2018-07-06 00:02:04 -03:00
parent 0bec547b9d
commit 8a21cf0b78
2 changed files with 46 additions and 47 deletions

View file

@ -4,6 +4,7 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.Gal.OpenGL
{
@ -156,9 +157,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
int Size = Math.Min(Data.Length, Buffer.Size);
byte[] Destiny = Buffer.Map(Size);
IntPtr Map = Buffer.Map(Size);
Array.Copy(Data, Destiny, Size);
Marshal.Copy(Data, 0, Map, Size);
Buffer.Unmap(Size);
}
@ -251,7 +252,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
int FreeBinding = 0;
int BindUniformBlocksIfNotNull(ShaderStage Stage)
void BindUniformBlocksIfNotNull(ShaderStage Stage)
{
if (Stage != null)
{
@ -270,8 +271,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
FreeBinding++;
}
}
return FreeBinding;
}
BindUniformBlocksIfNotNull(Current.Vertex);
@ -285,7 +284,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
int FreeBinding = 0;
int BindUniformBuffersIfNotNull(ShaderStage Stage)
void BindUniformBuffersIfNotNull(ShaderStage Stage)
{
if (Stage != null)
{
@ -293,13 +292,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
OGLStreamBuffer Buffer = GetConstBuffer(Stage.Type, DeclInfo.Cbuf);
GL.BindBufferBase(BufferRangeTarget.UniformBuffer, FreeBinding, Buffer.Handle);
Buffer.Bind(FreeBinding);
FreeBinding++;
}
}
return FreeBinding;
}
BindUniformBuffersIfNotNull(Current.Vertex);

View file

@ -1,5 +1,6 @@
using System;
using OpenTK.Graphics.OpenGL;
using System;
using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.Gal.OpenGL
{
@ -11,7 +12,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
protected BufferTarget Target { get; private set; }
private bool Mapped = false;
private bool Mapped;
public OGLStreamBuffer(BufferTarget Target, int MaxSize)
{
@ -24,18 +25,17 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public static OGLStreamBuffer Create(BufferTarget Target, int MaxSize)
{
//TODO: Query here for ARB_buffer_storage and use when available
return new SubDataBuffer(Target, MaxSize);
return new MapAndOrphan(Target, MaxSize);
}
public byte[] Map(int Size)
public IntPtr Map(int Size)
{
if (Handle == 0 || Mapped || Size > this.Size)
{
throw new InvalidOperationException();
}
byte[] Memory = InternMap(Size);
IntPtr Memory = InternMap(Size);
Mapped = true;
@ -54,7 +54,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Mapped = false;
}
protected abstract byte[] InternMap(int Size);
public abstract void Bind(int Index);
protected abstract IntPtr InternMap(int Size);
protected abstract void InternUnmap(int UsedSize);
@ -72,41 +74,41 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Handle = 0;
}
}
}
class SubDataBuffer : OGLStreamBuffer
{
private byte[] Memory;
public SubDataBuffer(BufferTarget Target, int MaxSize)
: base(Target, MaxSize)
class MapAndOrphan : OGLStreamBuffer
{
Memory = new byte[MaxSize];
private const BufferAccessMask Access =
BufferAccessMask.MapInvalidateBufferBit |
BufferAccessMask.MapUnsynchronizedBit |
BufferAccessMask.MapWriteBit;
GL.GenBuffers(1, out int Handle);
GL.BindBuffer(Target, Handle);
GL.BufferData(Target, Size, IntPtr.Zero, BufferUsageHint.StreamDraw);
this.Handle = Handle;
}
protected override byte[] InternMap(int Size)
{
return Memory;
}
protected override void InternUnmap(int UsedSize)
{
GL.BindBuffer(Target, Handle);
unsafe
public MapAndOrphan(BufferTarget Target, int MaxSize)
: base(Target, MaxSize)
{
fixed (byte* MemoryPtr = Memory)
{
GL.BufferSubData(Target, IntPtr.Zero, UsedSize, (IntPtr)MemoryPtr);
}
Handle = GL.GenBuffer();
GL.BindBuffer(Target, Handle);
GL.BufferData(Target, Size, IntPtr.Zero, BufferUsageHint.StreamDraw);
}
public override void Bind(int Index)
{
GL.BindBufferBase((BufferRangeTarget)Target, Index, Handle);
}
protected override IntPtr InternMap(int Size)
{
GL.BindBuffer(Target, Handle);
return GL.MapBufferRange(Target, IntPtr.Zero, Size, Access);
}
protected override void InternUnmap(int UsedSize)
{
//It's not needed to bind handle to Target here, since Map was called previously
GL.UnmapBuffer(Target);
}
}
}