Replace OGL buffer streaming from SubData to MapAndOprhan
This commit is contained in:
parent
0bec547b9d
commit
8a21cf0b78
2 changed files with 46 additions and 47 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue