mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-07-04 01:59:06 +00:00
Memory changes 3 (ryubing/ryujinx!202)
See merge request ryubing/ryujinx!202
This commit is contained in:
@@ -451,7 +451,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
|
||||
// TODO: Confirm behaviour on hardware.
|
||||
// When this is active, the origin appears to be on the bottom.
|
||||
if (_state.State.YControl.HasFlag(YControl.NegateY))
|
||||
if ((_state.State.YControl & YControl.NegateY) != 0)
|
||||
{
|
||||
dstY0 -= dstHeight;
|
||||
}
|
||||
|
||||
@@ -646,7 +646,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
int width = scissor.X2 - x;
|
||||
int height = scissor.Y2 - y;
|
||||
|
||||
if (_state.State.YControl.HasFlag(YControl.NegateY))
|
||||
if ((_state.State.YControl & YControl.NegateY) != 0)
|
||||
{
|
||||
ref ScreenScissorState screenScissor = ref _state.State.ScreenScissorState;
|
||||
y = screenScissor.Height - height - y;
|
||||
@@ -730,7 +730,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
FaceState face = _state.State.FaceState;
|
||||
|
||||
bool disableTransform = _state.State.ViewportTransformEnable == 0;
|
||||
bool yNegate = yControl.HasFlag(YControl.NegateY);
|
||||
bool yNegate = (yControl & YControl.NegateY) != 0;
|
||||
|
||||
UpdateFrontFace(yControl, face.FrontFace);
|
||||
UpdateDepthMode();
|
||||
@@ -1230,7 +1230,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// <param name="frontFace">Front face</param>
|
||||
private void UpdateFrontFace(YControl yControl, FrontFace frontFace)
|
||||
{
|
||||
bool isUpperLeftOrigin = !yControl.HasFlag(YControl.TriangleRastFlip);
|
||||
bool isUpperLeftOrigin = (yControl & YControl.TriangleRastFlip) == 0;
|
||||
|
||||
if (isUpperLeftOrigin)
|
||||
{
|
||||
@@ -1521,7 +1521,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
{
|
||||
// Make sure we update the viewport size on the support buffer if it will be consumed on the new shader.
|
||||
|
||||
if (!_fsReadsFragCoord && _state.State.YControl.HasFlag(YControl.NegateY))
|
||||
if (!_fsReadsFragCoord && (_state.State.YControl & YControl.NegateY) != 0)
|
||||
{
|
||||
UpdateSupportBufferViewportSize();
|
||||
}
|
||||
|
||||
@@ -381,9 +381,9 @@ namespace Ryujinx.Graphics.Gpu
|
||||
/// <param name="flags">Modifiers for how host sync should be created</param>
|
||||
internal void CreateHostSyncIfNeeded(HostSyncFlags flags)
|
||||
{
|
||||
bool syncpoint = flags.HasFlag(HostSyncFlags.Syncpoint);
|
||||
bool strict = flags.HasFlag(HostSyncFlags.Strict);
|
||||
bool force = flags.HasFlag(HostSyncFlags.Force);
|
||||
bool syncPoint = (flags & HostSyncFlags.Syncpoint) == HostSyncFlags.Syncpoint;
|
||||
bool strict = (flags & HostSyncFlags.Strict) == HostSyncFlags.Strict;
|
||||
bool force = (flags & HostSyncFlags.Force) == HostSyncFlags.Force;
|
||||
|
||||
if (BufferMigrations.Count > 0)
|
||||
{
|
||||
@@ -402,24 +402,37 @@ namespace Ryujinx.Graphics.Gpu
|
||||
}
|
||||
}
|
||||
|
||||
if (force || _pendingSync || (syncpoint && SyncpointActions.Count > 0))
|
||||
if (force || _pendingSync || (syncPoint && SyncpointActions.Count > 0))
|
||||
{
|
||||
foreach (ISyncActionHandler action in SyncActions)
|
||||
{
|
||||
action.SyncPreAction(syncpoint);
|
||||
action.SyncPreAction(syncPoint);
|
||||
}
|
||||
|
||||
foreach (ISyncActionHandler action in SyncpointActions)
|
||||
{
|
||||
action.SyncPreAction(syncpoint);
|
||||
action.SyncPreAction(syncPoint);
|
||||
}
|
||||
|
||||
Renderer.CreateSync(SyncNumber, strict);
|
||||
|
||||
SyncNumber++;
|
||||
|
||||
SyncActions.RemoveAll(action => action.SyncAction(syncpoint));
|
||||
SyncpointActions.RemoveAll(action => action.SyncAction(syncpoint));
|
||||
for (int i = 0; i < SyncActions.Count; i++)
|
||||
{
|
||||
if (SyncActions[i].SyncAction(syncPoint))
|
||||
{
|
||||
SyncActions.RemoveAt(i--);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < SyncpointActions.Count; i++)
|
||||
{
|
||||
if (SyncpointActions[i].SyncAction(syncPoint))
|
||||
{
|
||||
SyncpointActions.RemoveAt(i--);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_pendingSync = false;
|
||||
|
||||
@@ -1628,7 +1628,15 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
{
|
||||
lock (_poolOwners)
|
||||
{
|
||||
int references = _poolOwners.RemoveAll(entry => entry.Pool == pool && entry.ID == id || id == -1);
|
||||
int references = 0;
|
||||
for (int i = 0; i < _poolOwners.Count; i++)
|
||||
{
|
||||
if (_poolOwners[i].Pool == pool && _poolOwners[i].ID == id || id == -1)
|
||||
{
|
||||
_poolOwners.RemoveAt(i--);
|
||||
references++;
|
||||
}
|
||||
}
|
||||
|
||||
if (references == 0)
|
||||
{
|
||||
|
||||
@@ -45,7 +45,11 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// </summary>
|
||||
private const int GranularLayerThreshold = 8;
|
||||
|
||||
private delegate void HandlesCallbackDelegate(int baseHandle, int regionCount, bool split = false);
|
||||
private delegate bool HandlesCallbackDelegate(int baseHandle, int regionCount, bool split = false, bool specialData = false);
|
||||
|
||||
private readonly HandlesCallbackDelegate _signalModifyingCallback;
|
||||
private readonly HandlesCallbackDelegate _discardDataCallback;
|
||||
private readonly HandlesCallbackDelegate _checkDirtyCallback;
|
||||
|
||||
/// <summary>
|
||||
/// The storage texture associated with this group.
|
||||
@@ -126,6 +130,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
_incompatibleOverlaps = incompatibleOverlaps;
|
||||
_flushIncompatibleOverlaps = TextureCompatibility.IsFormatHostIncompatible(storage.Info, context.Capabilities);
|
||||
|
||||
_signalModifyingCallback = SignalModifyingCallback;
|
||||
_discardDataCallback = DiscardDataCallback;
|
||||
_checkDirtyCallback = CheckDirtyCallback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -253,29 +261,33 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// <param name="consume">True to consume the dirty flags and reprotect, false to leave them as is</param>
|
||||
/// <returns>True if a flag was dirty, false otherwise</returns>
|
||||
public bool CheckDirty(Texture texture, bool consume)
|
||||
{
|
||||
EvaluateRelevantHandles(texture, _checkDirtyCallback, out bool dirty, consume);
|
||||
|
||||
return dirty;
|
||||
}
|
||||
|
||||
bool CheckDirtyCallback(int baseHandle, int regionCount, bool split, bool consume)
|
||||
{
|
||||
bool dirty = false;
|
||||
|
||||
EvaluateRelevantHandles(texture, (baseHandle, regionCount, split) =>
|
||||
|
||||
for (int i = 0; i < regionCount; i++)
|
||||
{
|
||||
for (int i = 0; i < regionCount; i++)
|
||||
TextureGroupHandle group = _handles[baseHandle + i];
|
||||
|
||||
foreach (RegionHandle handle in group.Handles)
|
||||
{
|
||||
TextureGroupHandle group = _handles[baseHandle + i];
|
||||
|
||||
foreach (RegionHandle handle in group.Handles)
|
||||
if (handle.Dirty)
|
||||
{
|
||||
if (handle.Dirty)
|
||||
if (consume)
|
||||
{
|
||||
if (consume)
|
||||
{
|
||||
handle.Reprotect();
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
handle.Reprotect();
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return dirty;
|
||||
}
|
||||
@@ -287,15 +299,19 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// <param name="texture">The texture being discarded</param>
|
||||
public void DiscardData(Texture texture)
|
||||
{
|
||||
EvaluateRelevantHandles(texture, (baseHandle, regionCount, split) =>
|
||||
EvaluateRelevantHandles(texture, _discardDataCallback, out _);
|
||||
}
|
||||
|
||||
bool DiscardDataCallback(int baseHandle, int regionCount, bool split, bool bound)
|
||||
{
|
||||
for (int i = 0; i < regionCount; i++)
|
||||
{
|
||||
for (int i = 0; i < regionCount; i++)
|
||||
{
|
||||
TextureGroupHandle group = _handles[baseHandle + i];
|
||||
TextureGroupHandle group = _handles[baseHandle + i];
|
||||
|
||||
group.DiscardData();
|
||||
}
|
||||
});
|
||||
group.DiscardData();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -307,7 +323,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
{
|
||||
FlushIncompatibleOverlapsIfNeeded();
|
||||
|
||||
EvaluateRelevantHandles(texture, (baseHandle, regionCount, split) =>
|
||||
EvaluateRelevantHandles(texture, (baseHandle, regionCount, split, bound) =>
|
||||
{
|
||||
bool dirty = false;
|
||||
bool anyModified = false;
|
||||
@@ -383,7 +399,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
texture.SynchronizeFull();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -460,7 +478,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// <param name="texture">The texture to synchronize dependents of</param>
|
||||
public void SynchronizeDependents(Texture texture)
|
||||
{
|
||||
EvaluateRelevantHandles(texture, (baseHandle, regionCount, split) =>
|
||||
EvaluateRelevantHandles(texture, (baseHandle, regionCount, split, bound) =>
|
||||
{
|
||||
for (int i = 0; i < regionCount; i++)
|
||||
{
|
||||
@@ -468,7 +486,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
group.SynchronizeDependents();
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -550,7 +570,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
tracked = tracked || ShouldFlushTriggerTracking();
|
||||
bool flushed = false;
|
||||
|
||||
EvaluateRelevantHandles(texture, (baseHandle, regionCount, split) =>
|
||||
EvaluateRelevantHandles(texture, (baseHandle, regionCount, split, bound) =>
|
||||
{
|
||||
int startSlice = 0;
|
||||
int endSlice = 0;
|
||||
@@ -604,7 +624,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
flushed = true;
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}, out _);
|
||||
|
||||
Storage.SignalModifiedDirty();
|
||||
|
||||
@@ -693,7 +715,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
ClearIncompatibleOverlaps(texture);
|
||||
|
||||
EvaluateRelevantHandles(texture, (baseHandle, regionCount, split) =>
|
||||
EvaluateRelevantHandles(texture, (baseHandle, regionCount, split, bound) =>
|
||||
{
|
||||
for (int i = 0; i < regionCount; i++)
|
||||
{
|
||||
@@ -701,7 +723,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
group.SignalModified(_context);
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -714,16 +738,20 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
ModifiedSequence = _context.GetModifiedSequence();
|
||||
|
||||
ClearIncompatibleOverlaps(texture);
|
||||
|
||||
EvaluateRelevantHandles(texture, (baseHandle, regionCount, split) =>
|
||||
|
||||
EvaluateRelevantHandles(texture, _signalModifyingCallback, out _, bound);
|
||||
}
|
||||
|
||||
bool SignalModifyingCallback(int baseHandle, int regionCount, bool split, bool bound)
|
||||
{
|
||||
for (int i = 0; i < regionCount; i++)
|
||||
{
|
||||
for (int i = 0; i < regionCount; i++)
|
||||
{
|
||||
TextureGroupHandle group = _handles[baseHandle + i];
|
||||
TextureGroupHandle group = _handles[baseHandle + i];
|
||||
|
||||
group.SignalModifying(bound, _context);
|
||||
}
|
||||
});
|
||||
group.SignalModifying(bound, _context);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -767,16 +795,16 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// A function to be called with the base index of the range of handles for the given texture, and the number of handles it covers.
|
||||
/// This can be called for multiple disjoint ranges, if required.
|
||||
/// </param>
|
||||
private void EvaluateRelevantHandles(Texture texture, HandlesCallbackDelegate callback)
|
||||
private void EvaluateRelevantHandles(Texture texture, HandlesCallbackDelegate callback, out bool result, bool specialData = false)
|
||||
{
|
||||
if (texture == Storage || !(_hasMipViews || _hasLayerViews))
|
||||
{
|
||||
callback(0, _handles.Length);
|
||||
result = callback(0, _handles.Length, specialData: specialData);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EvaluateRelevantHandles(texture.FirstLayer, texture.FirstLevel, texture.Info.GetSlices(), texture.Info.Levels, callback);
|
||||
EvaluateRelevantHandles(texture.FirstLayer, texture.FirstLevel, texture.Info.GetSlices(), texture.Info.Levels, callback, out result, specialData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -791,11 +819,13 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// A function to be called with the base index of the range of handles for the given texture, and the number of handles it covers.
|
||||
/// This can be called for multiple disjoint ranges, if required.
|
||||
/// </param>
|
||||
private void EvaluateRelevantHandles(int firstLayer, int firstLevel, int slices, int levels, HandlesCallbackDelegate callback)
|
||||
private void EvaluateRelevantHandles(int firstLayer, int firstLevel, int slices, int levels, HandlesCallbackDelegate callback, out bool result, bool specialData = false)
|
||||
{
|
||||
int targetLayerHandles = _hasLayerViews ? slices : 1;
|
||||
int targetLevelHandles = _hasMipViews ? levels : 1;
|
||||
|
||||
result = false;
|
||||
|
||||
if (_isBuffer)
|
||||
{
|
||||
return;
|
||||
@@ -808,7 +838,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
{
|
||||
// When there are no layer views, the mips are at a consistent offset.
|
||||
|
||||
callback(firstLevel, targetLevelHandles);
|
||||
result = callback(firstLevel, targetLevelHandles, specialData: specialData);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -822,7 +852,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
while (levels-- > 1)
|
||||
{
|
||||
callback(firstLayer + levelIndex, slices);
|
||||
result = callback(firstLayer + levelIndex, slices, specialData: specialData);
|
||||
|
||||
levelIndex += layerCount;
|
||||
layerCount = Math.Max(layerCount >> 1, 1);
|
||||
@@ -839,7 +869,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
totalSize += layerCount;
|
||||
}
|
||||
|
||||
callback(firstLayer + levelIndex, totalSize);
|
||||
result = callback(firstLayer + levelIndex, totalSize, specialData: specialData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -856,12 +886,12 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
for (int i = 0; i < slices; i++)
|
||||
{
|
||||
callback(firstLevel + (firstLayer + i) * levelHandles, targetLevelHandles, true);
|
||||
result = callback(firstLevel + (firstLayer + i) * levelHandles, targetLevelHandles, true, specialData: specialData);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(firstLevel + firstLayer * levelHandles, targetLevelHandles + (targetLayerHandles - 1) * levelHandles);
|
||||
result = callback(firstLevel + firstLayer * levelHandles, targetLevelHandles + (targetLayerHandles - 1) * levelHandles, specialData: specialData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1439,8 +1469,16 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
List<(int BaseHandle, int RegionCount)> targetRange = [];
|
||||
List<(int BaseHandle, int RegionCount)> otherRange = [];
|
||||
|
||||
EvaluateRelevantHandles(firstLayer, firstLevel, other.Info.GetSlices(), other.Info.Levels, (baseHandle, regionCount, split) => targetRange.Add((baseHandle, regionCount)));
|
||||
otherGroup.EvaluateRelevantHandles(other, (baseHandle, regionCount, split) => otherRange.Add((baseHandle, regionCount)));
|
||||
EvaluateRelevantHandles(firstLayer, firstLevel, other.Info.GetSlices(), other.Info.Levels, (baseHandle, regionCount, split, specialData) =>
|
||||
{
|
||||
targetRange.Add((baseHandle, regionCount));
|
||||
return true;
|
||||
}, out _);
|
||||
otherGroup.EvaluateRelevantHandles(other, (baseHandle, regionCount, split, specialData) =>
|
||||
{
|
||||
otherRange.Add((baseHandle, regionCount));
|
||||
return true;
|
||||
}, out _);
|
||||
|
||||
int targetIndex = 0;
|
||||
int otherIndex = 0;
|
||||
|
||||
@@ -93,6 +93,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
private ulong _dirtyStart = ulong.MaxValue;
|
||||
private ulong _dirtyEnd = ulong.MaxValue;
|
||||
|
||||
private readonly Action<ulong, ulong> _syncPreRangeAction;
|
||||
private readonly Action<ulong, ulong> _syncRangeAction;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the buffer.
|
||||
/// </summary>
|
||||
@@ -177,6 +180,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
_modifiedDelegate = RegionModified;
|
||||
|
||||
_virtualDependenciesLock = new ReaderWriterLockSlim();
|
||||
|
||||
_syncPreRangeAction = SyncPreRangeAction;
|
||||
_syncRangeAction = SyncRangeAction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -401,13 +407,15 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
if (_preFlush.ShouldCopy)
|
||||
{
|
||||
_modifiedRanges?.GetRangesAtSync(Address, Size, _context.SyncNumber, (address, size) =>
|
||||
{
|
||||
_preFlush.CopyModified(address, size);
|
||||
});
|
||||
_modifiedRanges?.GetRangesAtSync(Address, Size, _context.SyncNumber, _syncPreRangeAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SyncPreRangeAction(ulong address, ulong size)
|
||||
{
|
||||
_preFlush.CopyModified(address, size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Action to be performed when a syncpoint is reached after modification.
|
||||
@@ -420,11 +428,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
if (_useGranular)
|
||||
{
|
||||
_modifiedRanges?.GetRanges(Address, Size, (address, size) =>
|
||||
{
|
||||
_memoryTrackingGranular.RegisterAction(address, size, _externalFlushDelegate);
|
||||
SynchronizeMemory(address, size);
|
||||
});
|
||||
|
||||
|
||||
_modifiedRanges?.GetRanges(Address, Size, _syncRangeAction);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -434,6 +440,12 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SyncRangeAction(ulong address, ulong size)
|
||||
{
|
||||
_memoryTrackingGranular.RegisterAction(address, size, _externalFlushDelegate);
|
||||
SynchronizeMemory(address, size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inherit modified and dirty ranges from another buffer.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Ryujinx.Memory.Range;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Memory
|
||||
@@ -276,13 +277,18 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
// We use the non-span method here because keeping the lock will cause a deadlock.
|
||||
Lock.EnterReadLock();
|
||||
RangeItem<BufferModifiedRange>[] overlaps = FindOverlapsAsArray(address, size);
|
||||
RangeItem<BufferModifiedRange>[] overlaps = FindOverlapsAsArray(address, size, out int length);
|
||||
Lock.ExitReadLock();
|
||||
|
||||
for (int i = 0; i < overlaps.Length; i++)
|
||||
if (length != 0)
|
||||
{
|
||||
BufferModifiedRange overlap = overlaps[i].Value;
|
||||
rangeAction(overlap.Address, overlap.Size);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
BufferModifiedRange overlap = overlaps[i].Value;
|
||||
rangeAction(overlap.Address, overlap.Size);
|
||||
}
|
||||
|
||||
ArrayPool<RangeItem<BufferModifiedRange>>.Shared.Return(overlaps);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,9 +398,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
Lock.EnterWriteLock();
|
||||
// We use the non-span method here because the array is partially modified by the code, which would invalidate a span.
|
||||
RangeItem<BufferModifiedRange>[] overlaps = FindOverlapsAsArray(address, size);
|
||||
|
||||
int rangeCount = overlaps.Length;
|
||||
RangeItem<BufferModifiedRange>[] overlaps = FindOverlapsAsArray(address, size, out int rangeCount);
|
||||
|
||||
if (rangeCount == 0)
|
||||
{
|
||||
@@ -410,7 +414,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
for (int i = 0; i < rangeCount; i++)
|
||||
{
|
||||
BufferModifiedRange overlap = overlaps[i].Value;
|
||||
BufferModifiedRange overlap = overlaps![i].Value;
|
||||
|
||||
long diff = (long)(overlap.SyncNumber - currentSync);
|
||||
|
||||
@@ -430,7 +434,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
// Wait for the syncpoint.
|
||||
_context.Renderer.WaitSync(currentSync + (ulong)highestDiff);
|
||||
|
||||
RemoveRangesAndFlush(overlaps.ToArray(), rangeCount, highestDiff, currentSync, address, endAddress);
|
||||
RemoveRangesAndFlush(overlaps, rangeCount, highestDiff, currentSync, address, endAddress);
|
||||
|
||||
ArrayPool<RangeItem<BufferModifiedRange>>.Shared.Return(overlaps!);
|
||||
|
||||
Lock.ExitWriteLock();
|
||||
}
|
||||
|
||||
@@ -397,7 +397,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
/// <returns>True if queried, false otherwise</returns>
|
||||
public bool IsPrimitiveTopologyQueried()
|
||||
{
|
||||
return _queriedState.HasFlag(QueriedStateFlags.PrimitiveTopology);
|
||||
return (_queriedState & QueriedStateFlags.PrimitiveTopology) == QueriedStateFlags.PrimitiveTopology;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -904,7 +904,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
specState.PipelineState = pipelineState;
|
||||
}
|
||||
|
||||
if (specState._queriedState.HasFlag(QueriedStateFlags.TransformFeedback))
|
||||
if ((specState._queriedState & QueriedStateFlags.TransformFeedback) == QueriedStateFlags.TransformFeedback)
|
||||
{
|
||||
ushort tfCount = 0;
|
||||
dataReader.Read(ref tfCount);
|
||||
@@ -930,7 +930,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
specState._textureSpecialization[textureKey] = textureState;
|
||||
}
|
||||
|
||||
if (specState._queriedState.HasFlag(QueriedStateFlags.TextureArrayFromBuffer))
|
||||
if ((specState._queriedState & QueriedStateFlags.TextureArrayFromBuffer) == QueriedStateFlags.TextureArrayFromBuffer)
|
||||
{
|
||||
dataReader.Read(ref count);
|
||||
|
||||
@@ -946,7 +946,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
}
|
||||
}
|
||||
|
||||
if (specState._queriedState.HasFlag(QueriedStateFlags.TextureArrayFromPool))
|
||||
if ((specState._queriedState & QueriedStateFlags.TextureArrayFromPool) == QueriedStateFlags.TextureArrayFromPool)
|
||||
{
|
||||
dataReader.Read(ref count);
|
||||
|
||||
@@ -1006,7 +1006,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
dataWriter.WriteWithMagicAndSize(ref pipelineState, PgpsMagic);
|
||||
}
|
||||
|
||||
if (_queriedState.HasFlag(QueriedStateFlags.TransformFeedback))
|
||||
if ((_queriedState & QueriedStateFlags.TransformFeedback) == QueriedStateFlags.TransformFeedback)
|
||||
{
|
||||
ushort tfCount = (ushort)TransformFeedbackDescriptors.Length;
|
||||
dataWriter.Write(ref tfCount);
|
||||
@@ -1029,7 +1029,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
dataWriter.WriteWithMagicAndSize(ref textureState.Value, TexsMagic);
|
||||
}
|
||||
|
||||
if (_queriedState.HasFlag(QueriedStateFlags.TextureArrayFromBuffer))
|
||||
if ((_queriedState & QueriedStateFlags.TextureArrayFromBuffer) == QueriedStateFlags.TextureArrayFromBuffer)
|
||||
{
|
||||
count = (ushort)_textureArrayFromBufferSpecialization.Count;
|
||||
dataWriter.Write(ref count);
|
||||
@@ -1044,7 +1044,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
}
|
||||
}
|
||||
|
||||
if (_queriedState.HasFlag(QueriedStateFlags.TextureArrayFromPool))
|
||||
if ((_queriedState & QueriedStateFlags.TextureArrayFromPool) == QueriedStateFlags.TextureArrayFromPool)
|
||||
{
|
||||
count = (ushort)_textureArrayFromPoolSpecialization.Count;
|
||||
dataWriter.Write(ref count);
|
||||
|
||||
Reference in New Issue
Block a user