Compare commits

...

4 Commits

Author SHA1 Message Date
gdkchan
70895bdb04 Allow concurrent BSD EventFd read/write (#3385) 2022-06-11 14:58:30 -03:00
gdkchan
830cbf91bb Ignore ClipControl on draw texture fallback (#3388) 2022-06-11 14:31:17 -03:00
gdkchan
9a9349f0f4 Fix instanced indexed inline draw index count (#3389) 2022-06-10 23:44:49 -03:00
gdkchan
46cc7b55f0 Fix instanced indexed inline draws (#3383) 2022-06-05 21:24:28 -03:00
8 changed files with 80 additions and 16 deletions

View File

@@ -18,6 +18,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
private bool _instancedDrawPending;
private bool _instancedIndexed;
private bool _instancedIndexedInline;
private int _instancedFirstIndex;
private int _instancedFirstVertex;
@@ -134,13 +135,16 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
{
_instancedDrawPending = true;
int ibCount = _drawState.IbStreamer.InlineIndexCount;
_instancedIndexed = _drawState.DrawIndexed;
_instancedIndexedInline = ibCount != 0;
_instancedFirstIndex = firstIndex;
_instancedFirstVertex = (int)_state.State.FirstVertex;
_instancedFirstInstance = (int)_state.State.FirstInstance;
_instancedIndexCount = indexCount;
_instancedIndexCount = ibCount != 0 ? ibCount : indexCount;
var drawState = _state.State.VertexBufferDrawState;
@@ -451,8 +455,18 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
{
_instancedDrawPending = false;
if (_instancedIndexed)
bool indexedInline = _instancedIndexedInline;
if (_instancedIndexed || indexedInline)
{
if (indexedInline)
{
int inlineIndexCount = _drawState.IbStreamer.GetAndResetInlineIndexCount();
BufferRange br = new BufferRange(_drawState.IbStreamer.GetInlineIndexBuffer(), 0, inlineIndexCount * 4);
_channel.BufferManager.SetIndexBuffer(br, IndexType.UInt);
}
_context.Renderer.Pipeline.DrawIndexed(
_instancedIndexCount,
_instanceIndex + 1,

View File

@@ -20,6 +20,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
/// </summary>
public bool HasInlineIndexData => _inlineIndexCount != 0;
/// <summary>
/// Total numbers of indices that have been pushed.
/// </summary>
public int InlineIndexCount => _inlineIndexCount;
/// <summary>
/// Gets the handle for the host buffer currently holding the inline index buffer data.
/// </summary>

View File

@@ -597,6 +597,8 @@ namespace Ryujinx.Graphics.OpenGL
GL.EndTransformFeedback();
}
GL.ClipControl(ClipOrigin.UpperLeft, ClipDepthMode.NegativeOneToOne);
_drawTexture.Draw(
view,
samp,
@@ -627,6 +629,8 @@ namespace Ryujinx.Graphics.OpenGL
{
GL.BeginTransformFeedback(_tfTopology);
}
RestoreClipControl();
}
}
}

View File

@@ -309,7 +309,7 @@ namespace Ryujinx.HLE.HOS
// only then doing connections to SM is safe.
SmServer.InitDone.WaitOne();
BsdServer = new ServerBase(KernelContext, "BsdServer");
BsdServer = new ServerBase(KernelContext, "BsdServer", null, 2);
AudRenServer = new ServerBase(KernelContext, "AudioRendererServer");
AudOutServer = new ServerBase(KernelContext, "AudioOutServer");
FsServer = new ServerBase(KernelContext, "FsServer");

View File

@@ -735,11 +735,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
ulong argsPtr,
ulong stackTop,
int priority,
int cpuCore)
int cpuCore,
ThreadStart customThreadStart = null)
{
lock (_processLock)
{
return thread.Initialize(entrypoint, argsPtr, stackTop, priority, cpuCore, this, ThreadType.User, null);
return thread.Initialize(entrypoint, argsPtr, stackTop, priority, cpuCore, this, ThreadType.User, customThreadStart);
}
}

View File

@@ -2350,6 +2350,18 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
[PointerSized] ulong stackTop,
int priority,
int cpuCore)
{
return CreateThread(out handle, entrypoint, argsPtr, stackTop, priority, cpuCore, null);
}
public KernelResult CreateThread(
out int handle,
ulong entrypoint,
ulong argsPtr,
ulong stackTop,
int priority,
int cpuCore,
ThreadStart customThreadStart)
{
handle = 0;
@@ -2386,7 +2398,8 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
argsPtr,
stackTop,
priority,
cpuCore);
cpuCore,
customThreadStart);
if (result == KernelResult.Success)
{

View File

@@ -1,3 +1,4 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel;
using Ryujinx.HLE.HOS.Kernel.Common;
@@ -38,15 +39,18 @@ namespace Ryujinx.HLE.HOS.Services
private readonly Dictionary<int, Func<IpcService>> _ports = new Dictionary<int, Func<IpcService>>();
public ManualResetEvent InitDone { get; }
public Func<IpcService> SmObjectFactory { get; }
public string Name { get; }
public Func<IpcService> SmObjectFactory { get; }
public ServerBase(KernelContext context, string name, Func<IpcService> smObjectFactory = null)
private int _threadCount;
public ServerBase(KernelContext context, string name, Func<IpcService> smObjectFactory = null, int threadCount = 1)
{
InitDone = new ManualResetEvent(false);
_context = context;
Name = name;
SmObjectFactory = smObjectFactory;
_context = context;
_threadCount = threadCount;
const ProcessCreationFlags flags =
ProcessCreationFlags.EnableAslr |
@@ -56,7 +60,7 @@ namespace Ryujinx.HLE.HOS.Services
ProcessCreationInfo creationInfo = new ProcessCreationInfo("Service", 1, 0, 0x8000000, 1, flags, 0, 0);
KernelStatic.StartInitialProcess(context, creationInfo, DefaultCapabilities, 44, ServerLoop);
KernelStatic.StartInitialProcess(context, creationInfo, DefaultCapabilities, 44, Main);
}
private void AddPort(int serverPortHandle, Func<IpcService> objectFactory)
@@ -80,6 +84,32 @@ namespace Ryujinx.HLE.HOS.Services
_sessions.Add(serverSessionHandle, obj);
}
private void Main()
{
for (int i = 1; i < _threadCount; i++)
{
KernelResult result = _context.Syscall.CreateThread(out int threadHandle, 0UL, 0UL, 0UL, 44, 3, ServerLoop);
if (result == KernelResult.Success)
{
result = _context.Syscall.StartThread(threadHandle);
if (result != KernelResult.Success)
{
Logger.Error?.Print(LogClass.Service, $"Failed to start thread on {Name}: {result}");
}
_context.Syscall.CloseHandle(threadHandle);
}
else
{
Logger.Error?.Print(LogClass.Service, $"Failed to create thread on {Name}: {result}");
}
}
ServerLoop();
}
private void ServerLoop()
{
_selfProcess = KernelStatic.GetCurrentProcess();

View File

@@ -8,7 +8,6 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
private ulong _value;
private readonly EventFdFlags _flags;
private AutoResetEvent _event;
private object _lock = new object();
@@ -21,7 +20,6 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
_value = value;
_flags = flags;
_event = new AutoResetEvent(false);
WriteEvent = new ManualResetEvent(true);
ReadEvent = new ManualResetEvent(true);
@@ -31,7 +29,6 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
public void Dispose()
{
_event.Dispose();
WriteEvent.Dispose();
ReadEvent.Dispose();
}
@@ -57,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
while (_value == 0)
{
_event.WaitOne();
Monitor.Wait(_lock);
}
}
else
@@ -106,7 +103,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
if (Blocking)
{
_event.WaitOne();
Monitor.Wait(_lock);
}
else
{
@@ -119,7 +116,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
writeSize = sizeof(ulong);
_value += count;
_event.Set();
Monitor.Pulse(_lock);
WriteEvent.Set();