mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-01-05 23:43:04 +00:00
Queries
This commit is contained in:
parent
0d72c7650a
commit
4301dbaca6
13 changed files with 86 additions and 78 deletions
|
@ -21,14 +21,14 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
if (Avx2.IsSupported)
|
||||
{
|
||||
var mask = Vector256.Create(
|
||||
(byte)3, (byte)0, (byte)1, (byte)2,
|
||||
(byte)7, (byte)4, (byte)5, (byte)6,
|
||||
(byte)11, (byte)8, (byte)9, (byte)10,
|
||||
(byte)15, (byte)12, (byte)13, (byte)14,
|
||||
(byte)19, (byte)16, (byte)17, (byte)18,
|
||||
(byte)23, (byte)20, (byte)21, (byte)22,
|
||||
(byte)27, (byte)24, (byte)25, (byte)26,
|
||||
(byte)31, (byte)28, (byte)29, (byte)30);
|
||||
3, 0, 1, 2,
|
||||
7, 4, 5, 6,
|
||||
11, 8, 9, 10,
|
||||
15, 12, 13, 14,
|
||||
19, 16, 17, 18,
|
||||
23, 20, 21, 22,
|
||||
27, 24, 25, 26,
|
||||
31, 28, 29, (byte)30);
|
||||
|
||||
int sizeAligned = data.Length & ~31;
|
||||
|
||||
|
@ -49,10 +49,10 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
else if (Ssse3.IsSupported)
|
||||
{
|
||||
var mask = Vector128.Create(
|
||||
(byte)3, (byte)0, (byte)1, (byte)2,
|
||||
(byte)7, (byte)4, (byte)5, (byte)6,
|
||||
(byte)11, (byte)8, (byte)9, (byte)10,
|
||||
(byte)15, (byte)12, (byte)13, (byte)14);
|
||||
3, 0, 1, 2,
|
||||
7, 4, 5, 6,
|
||||
11, 8, 9, 10,
|
||||
15, 12, 13, (byte)14);
|
||||
|
||||
int sizeAligned = data.Length & ~15;
|
||||
|
||||
|
@ -90,14 +90,14 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
if (Avx2.IsSupported)
|
||||
{
|
||||
var mask = Vector256.Create(
|
||||
(byte)1, (byte)2, (byte)3, (byte)0,
|
||||
(byte)5, (byte)6, (byte)7, (byte)4,
|
||||
(byte)9, (byte)10, (byte)11, (byte)8,
|
||||
(byte)13, (byte)14, (byte)15, (byte)12,
|
||||
(byte)17, (byte)18, (byte)19, (byte)16,
|
||||
(byte)21, (byte)22, (byte)23, (byte)20,
|
||||
(byte)25, (byte)26, (byte)27, (byte)24,
|
||||
(byte)29, (byte)30, (byte)31, (byte)28);
|
||||
1, 2, 3, 0,
|
||||
5, 6, 7, 4,
|
||||
9, 10, 11, 8,
|
||||
13, 14, 15, 12,
|
||||
17, 18, 19, 16,
|
||||
21, 22, 23, 20,
|
||||
25, 26, 27, 24,
|
||||
29, 30, 31, (byte)28);
|
||||
|
||||
int sizeAligned = data.Length & ~31;
|
||||
|
||||
|
@ -118,10 +118,10 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
else if (Ssse3.IsSupported)
|
||||
{
|
||||
var mask = Vector128.Create(
|
||||
(byte)1, (byte)2, (byte)3, (byte)0,
|
||||
(byte)5, (byte)6, (byte)7, (byte)4,
|
||||
(byte)9, (byte)10, (byte)11, (byte)8,
|
||||
(byte)13, (byte)14, (byte)15, (byte)12);
|
||||
1, 2, 3, 0,
|
||||
5, 6, 7, 4,
|
||||
9, 10, 11, 8,
|
||||
13, 14, 15, (byte)12);
|
||||
|
||||
int sizeAligned = data.Length & ~15;
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
}
|
||||
|
||||
private readonly TextureRef[] _images;
|
||||
private GL _api;
|
||||
private readonly GL _api;
|
||||
|
||||
public ImageArray(GL api, int size)
|
||||
{
|
||||
|
|
|
@ -41,9 +41,9 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
_api.SamplerParameter(Handle, SamplerParameterF.BorderColor, borderColor);
|
||||
}
|
||||
|
||||
_api.SamplerParameter(Handle, SamplerParameterF.TextureMinLod, info.MinLod);
|
||||
_api.SamplerParameter(Handle, SamplerParameterF.TextureMaxLod, info.MaxLod);
|
||||
_api.SamplerParameter(Handle, SamplerParameterF.TextureLodBias, info.MipLodBias);
|
||||
_api.SamplerParameter(Handle, SamplerParameterF.MinLod, info.MinLod);
|
||||
_api.SamplerParameter(Handle, SamplerParameterF.MaxLod, info.MaxLod);
|
||||
_api.SamplerParameter(Handle, SamplerParameterF.LodBias, info.MipLodBias);
|
||||
|
||||
_api.SamplerParameter(Handle, SamplerParameterF.MaxAnisotropy, info.MaxAnisotropy);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
}
|
||||
|
||||
private readonly TextureRef[] _textureRefs;
|
||||
private GL _api;
|
||||
private readonly GL _api;
|
||||
|
||||
public TextureArray(GL api, int size)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
class TextureBase
|
||||
{
|
||||
private readonly protected GL Api;
|
||||
public uint Handle { get; protected set; }
|
||||
|
||||
public TextureCreateInfo Info { get; }
|
||||
|
@ -15,14 +16,12 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
public Target Target => Info.Target;
|
||||
public Format Format => Info.Format;
|
||||
|
||||
private protected GL _api;
|
||||
|
||||
public TextureBase(GL api, TextureCreateInfo info)
|
||||
{
|
||||
_api = api;
|
||||
Api = api;
|
||||
Info = info;
|
||||
|
||||
Handle = _api.GenTexture();
|
||||
Handle = Api.GenTexture();
|
||||
}
|
||||
|
||||
public void Bind(uint unit)
|
||||
|
@ -32,8 +31,8 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
protected void Bind(TextureTarget target, uint unit)
|
||||
{
|
||||
_api.ActiveTexture((TextureUnit)((uint)TextureUnit.Texture0 + unit));
|
||||
_api.BindTexture(target, Handle);
|
||||
Api.ActiveTexture((TextureUnit)((uint)TextureUnit.Texture0 + unit));
|
||||
Api.BindTexture(target, Handle);
|
||||
}
|
||||
|
||||
public static void ClearBinding(GL api, uint unit)
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
public PinnedSpan<byte> GetData()
|
||||
{
|
||||
return Buffer.GetData(_api, _renderer, _buffer, _bufferOffset, _bufferSize);
|
||||
return Buffer.GetData(Api, _renderer, _buffer, _bufferOffset, _bufferSize);
|
||||
}
|
||||
|
||||
public PinnedSpan<byte> GetData(int layer, int level)
|
||||
|
@ -59,7 +59,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
var dataSpan = data.Memory.Span;
|
||||
|
||||
Buffer.SetData(_api, _buffer, _bufferOffset, dataSpan[..Math.Min(dataSpan.Length, _bufferSize)]);
|
||||
Buffer.SetData(Api, _buffer, _bufferOffset, dataSpan[..Math.Min(dataSpan.Length, _bufferSize)]);
|
||||
|
||||
data.Dispose();
|
||||
}
|
||||
|
@ -97,14 +97,14 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
SizedInternalFormat format = (SizedInternalFormat)FormatTable.GetFormatInfo(Info.Format).InternalFormat;
|
||||
|
||||
_api.TexBufferRange(TextureTarget.TextureBuffer, format, _buffer.ToUInt32(), buffer.Offset, (uint)buffer.Size);
|
||||
Api.TexBufferRange(TextureTarget.TextureBuffer, format, _buffer.ToUInt32(), buffer.Offset, (uint)buffer.Size);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Handle != 0)
|
||||
{
|
||||
_api.DeleteTexture(Handle);
|
||||
Api.DeleteTexture(Handle);
|
||||
|
||||
Handle = 0;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
class TextureCopy : IDisposable
|
||||
{
|
||||
private GL _api;
|
||||
private readonly GL _api;
|
||||
private readonly OpenGLRenderer _renderer;
|
||||
|
||||
private uint _srcFramebuffer;
|
||||
|
|
|
@ -94,14 +94,14 @@ void main()
|
|||
}";
|
||||
|
||||
private readonly OpenGLRenderer _renderer;
|
||||
private readonly int[] _msToNonMSProgramHandles;
|
||||
private readonly int[] _nonMSToMSProgramHandles;
|
||||
private readonly uint[] _msToNonMSProgramHandles;
|
||||
private readonly uint[] _nonMSToMSProgramHandles;
|
||||
|
||||
public TextureCopyMS(OpenGLRenderer renderer)
|
||||
{
|
||||
_renderer = renderer;
|
||||
_msToNonMSProgramHandles = new int[5];
|
||||
_nonMSToMSProgramHandles = new int[5];
|
||||
_msToNonMSProgramHandles = new uint[5];
|
||||
_nonMSToMSProgramHandles = new uint[5];
|
||||
}
|
||||
|
||||
public void CopyMSToNonMS(ITextureInfo src, ITextureInfo dst, int srcLayer, int dstLayer, int depth)
|
||||
|
@ -177,7 +177,7 @@ void main()
|
|||
};
|
||||
}
|
||||
|
||||
private static int CreateViewIfNeeded(ITextureInfo texture)
|
||||
private static uint CreateViewIfNeeded(ITextureInfo texture)
|
||||
{
|
||||
// Binding sRGB textures as images doesn't work on NVIDIA,
|
||||
// we need to create and bind a RGBA view for it to work.
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
class TextureStorage : ITextureInfo
|
||||
{
|
||||
public ITextureInfo Storage => this;
|
||||
public int Handle { get; private set; }
|
||||
public uint Handle { get; private set; }
|
||||
|
||||
public TextureCreateInfo Info { get; }
|
||||
|
||||
|
|
|
@ -12,50 +12,56 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
private const long DefaultValue = -1;
|
||||
private const ulong HighMask = 0xFFFFFFFF00000000;
|
||||
|
||||
public int Query { get; }
|
||||
public uint Query { get; }
|
||||
|
||||
private readonly int _buffer;
|
||||
private readonly uint _buffer;
|
||||
private readonly IntPtr _bufferMap;
|
||||
private readonly QueryTarget _type;
|
||||
private readonly GL _api;
|
||||
|
||||
public BufferedQuery(QueryTarget type)
|
||||
public BufferedQuery(GL api, QueryTarget type)
|
||||
{
|
||||
_buffer = GL.GenBuffer();
|
||||
Query = GL.GenQuery();
|
||||
_api = api;
|
||||
_buffer = _api.GenBuffer();
|
||||
Query = _api.GenQuery();
|
||||
_type = type;
|
||||
|
||||
GL.BindBuffer(BufferTargetARB.QueryBuffer, _buffer);
|
||||
_api.BindBuffer(BufferTargetARB.QueryBuffer, _buffer);
|
||||
|
||||
unsafe
|
||||
{
|
||||
long defaultValue = DefaultValue;
|
||||
GL.BufferStorage(BufferTargetARB.QueryBuffer, sizeof(long), (IntPtr)(&defaultValue), BufferStorageMask.MapReadBit | BufferStorageMask.MapWriteBit | BufferStorageMask.MapPersistentBit);
|
||||
_api.BufferStorage(BufferStorageTarget.QueryBuffer, sizeof(long), (IntPtr)(&defaultValue), BufferStorageMask.MapReadBit | BufferStorageMask.MapWriteBit | BufferStorageMask.MapPersistentBit);
|
||||
}
|
||||
|
||||
unsafe
|
||||
{
|
||||
_bufferMap = new IntPtr(_api.MapBufferRange(BufferTargetARB.QueryBuffer, IntPtr.Zero, sizeof(long), MapBufferAccessMask.ReadBit | MapBufferAccessMask.WriteBit | MapBufferAccessMask.PersistentBit));
|
||||
}
|
||||
_bufferMap = GL.MapBufferRange(BufferTargetARB.QueryBuffer, IntPtr.Zero, sizeof(long), MapBufferAccessMask.ReadBit | MapBufferAccessMask.WriteBit | MapBufferAccessMask.PersistentBit);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
GL.EndQuery(_type);
|
||||
GL.BeginQuery(_type, Query);
|
||||
_api.EndQuery(_type);
|
||||
_api.BeginQuery(_type, Query);
|
||||
}
|
||||
|
||||
public void Begin()
|
||||
{
|
||||
GL.BeginQuery(_type, Query);
|
||||
_api.BeginQuery(_type, Query);
|
||||
}
|
||||
|
||||
public unsafe void End(bool withResult)
|
||||
{
|
||||
GL.EndQuery(_type);
|
||||
_api.EndQuery(_type);
|
||||
|
||||
if (withResult)
|
||||
{
|
||||
GL.BindBuffer(BufferTargetARB.QueryBuffer, _buffer);
|
||||
_api.BindBuffer(BufferTargetARB.QueryBuffer, _buffer);
|
||||
|
||||
Marshal.WriteInt64(_bufferMap, -1L);
|
||||
GL.GetQueryObject(Query, GetQueryObjectParam.QueryResult, (long*)0);
|
||||
GL.MemoryBarrier(MemoryBarrierMask.QueryBufferBarrierBit | MemoryBarrierMask.ClientMappedBufferBarrierBit);
|
||||
_api.GetQueryObject(Query,QueryObjectParameterName.Result, (long*)0);
|
||||
_api.MemoryBarrier(MemoryBarrierMask.QueryBufferBarrierBit | MemoryBarrierMask.ClientMappedBufferBarrierBit);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -111,10 +117,10 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
GL.BindBuffer(BufferTargetARB.QueryBuffer, _buffer);
|
||||
GL.UnmapBuffer(BufferTargetARB.QueryBuffer);
|
||||
GL.DeleteBuffer(_buffer);
|
||||
GL.DeleteQuery(Query);
|
||||
_api.BindBuffer(BufferTargetARB.QueryBuffer, _buffer);
|
||||
_api.UnmapBuffer(BufferTargetARB.QueryBuffer);
|
||||
_api.DeleteBuffer(_buffer);
|
||||
_api.DeleteQuery(Query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
|
||||
private readonly Thread _consumerThread;
|
||||
|
||||
internal CounterQueue(CounterType type)
|
||||
internal CounterQueue(GL api, CounterType type)
|
||||
{
|
||||
Type = type;
|
||||
|
||||
|
@ -37,10 +37,10 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
_queryPool = new Queue<BufferedQuery>(QueryPoolInitialSize);
|
||||
for (int i = 0; i < QueryPoolInitialSize; i++)
|
||||
{
|
||||
_queryPool.Enqueue(new BufferedQuery(glType));
|
||||
_queryPool.Enqueue(new BufferedQuery(api, glType));
|
||||
}
|
||||
|
||||
_current = new CounterQueueEvent(this, glType, 0);
|
||||
_current = new CounterQueueEvent(api, this, glType, 0);
|
||||
|
||||
_consumerThread = new Thread(EventConsumer);
|
||||
_consumerThread.Start();
|
||||
|
@ -76,7 +76,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
}
|
||||
}
|
||||
|
||||
internal BufferedQuery GetQueryObject()
|
||||
internal BufferedQuery GetQueryObject(GL api)
|
||||
{
|
||||
// Creating/disposing query objects on a context we're sharing with will cause issues.
|
||||
// So instead, make a lot of query objects on the main thread and reuse them.
|
||||
|
@ -90,7 +90,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
}
|
||||
else
|
||||
{
|
||||
return new BufferedQuery(GetTarget(Type));
|
||||
return new BufferedQuery(api, GetTarget(Type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
}
|
||||
}
|
||||
|
||||
public CounterQueueEvent QueueReport(EventHandler<ulong> resultHandler, float divisor, ulong lastDrawIndex, bool hostReserved)
|
||||
public CounterQueueEvent QueueReport(GL api, EventHandler<ulong> resultHandler, float divisor, ulong lastDrawIndex, bool hostReserved)
|
||||
{
|
||||
CounterQueueEvent result;
|
||||
ulong draws = lastDrawIndex - _current.DrawIndex;
|
||||
|
@ -126,7 +126,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
|
||||
result = _current;
|
||||
|
||||
_current = new CounterQueueEvent(this, GetTarget(Type), lastDrawIndex);
|
||||
_current = new CounterQueueEvent(api, this, GetTarget(Type), lastDrawIndex);
|
||||
}
|
||||
|
||||
_queuedEvent.Set();
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
|
||||
public QueryTarget Type { get; }
|
||||
public bool ClearCounter { get; private set; }
|
||||
public int Query => _counter.Query;
|
||||
public uint Query => _counter.Query;
|
||||
|
||||
public bool Disposed { get; private set; }
|
||||
public bool Invalid { get; set; }
|
||||
|
@ -28,11 +28,11 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
private ulong _result = ulong.MaxValue;
|
||||
private double _divisor = 1f;
|
||||
|
||||
public CounterQueueEvent(CounterQueue queue, QueryTarget type, ulong drawIndex)
|
||||
public CounterQueueEvent(GL api, CounterQueue queue, QueryTarget type, ulong drawIndex)
|
||||
{
|
||||
_queue = queue;
|
||||
|
||||
_counter = queue.GetQueryObject();
|
||||
_counter = queue.GetQueryObject(api);
|
||||
Type = type;
|
||||
|
||||
DrawIndex = drawIndex;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Queries
|
||||
|
@ -6,12 +7,14 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
class Counters : IDisposable
|
||||
{
|
||||
private readonly CounterQueue[] _counterQueues;
|
||||
private readonly GL _api;
|
||||
|
||||
public Counters()
|
||||
public Counters(GL api)
|
||||
{
|
||||
int count = Enum.GetNames<CounterType>().Length;
|
||||
|
||||
_counterQueues = new CounterQueue[count];
|
||||
_api = api;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
|
@ -19,13 +22,13 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
for (int index = 0; index < _counterQueues.Length; index++)
|
||||
{
|
||||
CounterType type = (CounterType)index;
|
||||
_counterQueues[index] = new CounterQueue(type);
|
||||
_counterQueues[index] = new CounterQueue(_api, type);
|
||||
}
|
||||
}
|
||||
|
||||
public CounterQueueEvent QueueReport(CounterType type, EventHandler<ulong> resultHandler, float divisor, ulong lastDrawIndex, bool hostReserved)
|
||||
{
|
||||
return _counterQueues[(int)type].QueueReport(resultHandler, divisor, lastDrawIndex, hostReserved);
|
||||
return _counterQueues[(int)type].QueueReport(_api, resultHandler, divisor, lastDrawIndex, hostReserved);
|
||||
}
|
||||
|
||||
public void QueueReset(CounterType type)
|
||||
|
|
Loading…
Reference in a new issue