Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
cd78adf07f | ||
|
a3dc295c5f | ||
|
2ef4f92b07 |
@@ -390,7 +390,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
{
|
{
|
||||||
_views.Remove(texture);
|
_views.Remove(texture);
|
||||||
|
|
||||||
Group.RemoveView(texture);
|
Group.RemoveView(_views, texture);
|
||||||
|
|
||||||
texture._viewStorage = texture;
|
texture._viewStorage = texture;
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@ using Ryujinx.Graphics.Texture;
|
|||||||
using Ryujinx.Memory.Range;
|
using Ryujinx.Memory.Range;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Image
|
namespace Ryujinx.Graphics.Gpu.Image
|
||||||
{
|
{
|
||||||
@@ -39,6 +40,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
private readonly MultiRangeList<Texture> _textures;
|
private readonly MultiRangeList<Texture> _textures;
|
||||||
private readonly HashSet<Texture> _partiallyMappedTextures;
|
private readonly HashSet<Texture> _partiallyMappedTextures;
|
||||||
|
|
||||||
|
private readonly ReaderWriterLockSlim _texturesLock;
|
||||||
|
|
||||||
private Texture[] _textureOverlaps;
|
private Texture[] _textureOverlaps;
|
||||||
private OverlapInfo[] _overlapInfo;
|
private OverlapInfo[] _overlapInfo;
|
||||||
|
|
||||||
@@ -57,6 +60,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
_textures = new MultiRangeList<Texture>();
|
_textures = new MultiRangeList<Texture>();
|
||||||
_partiallyMappedTextures = new HashSet<Texture>();
|
_partiallyMappedTextures = new HashSet<Texture>();
|
||||||
|
|
||||||
|
_texturesLock = new ReaderWriterLockSlim();
|
||||||
|
|
||||||
_textureOverlaps = new Texture[OverlapsBufferInitialCapacity];
|
_textureOverlaps = new Texture[OverlapsBufferInitialCapacity];
|
||||||
_overlapInfo = new OverlapInfo[OverlapsBufferInitialCapacity];
|
_overlapInfo = new OverlapInfo[OverlapsBufferInitialCapacity];
|
||||||
|
|
||||||
@@ -75,10 +80,16 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
|
|
||||||
MultiRange unmapped = ((MemoryManager)sender).GetPhysicalRegions(e.Address, e.Size);
|
MultiRange unmapped = ((MemoryManager)sender).GetPhysicalRegions(e.Address, e.Size);
|
||||||
|
|
||||||
lock (_textures)
|
_texturesLock.EnterReadLock();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
overlapCount = _textures.FindOverlaps(unmapped, ref overlaps);
|
overlapCount = _textures.FindOverlaps(unmapped, ref overlaps);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitReadLock();
|
||||||
|
}
|
||||||
|
|
||||||
if (overlapCount > 0)
|
if (overlapCount > 0)
|
||||||
{
|
{
|
||||||
@@ -217,7 +228,18 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
public bool UpdateMapping(Texture texture, MultiRange range)
|
public bool UpdateMapping(Texture texture, MultiRange range)
|
||||||
{
|
{
|
||||||
// There cannot be an existing texture compatible with this mapping in the texture cache already.
|
// There cannot be an existing texture compatible with this mapping in the texture cache already.
|
||||||
int overlapCount = _textures.FindOverlaps(range, ref _textureOverlaps);
|
int overlapCount;
|
||||||
|
|
||||||
|
_texturesLock.EnterReadLock();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
overlapCount = _textures.FindOverlaps(range, ref _textureOverlaps);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitReadLock();
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < overlapCount; i++)
|
for (int i = 0; i < overlapCount; i++)
|
||||||
{
|
{
|
||||||
@@ -231,11 +253,20 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_texturesLock.EnterWriteLock();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
_textures.Remove(texture);
|
_textures.Remove(texture);
|
||||||
|
|
||||||
texture.ReplaceRange(range);
|
texture.ReplaceRange(range);
|
||||||
|
|
||||||
_textures.Add(texture);
|
_textures.Add(texture);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitWriteLock();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -611,11 +642,17 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
|
|
||||||
int sameAddressOverlapsCount;
|
int sameAddressOverlapsCount;
|
||||||
|
|
||||||
lock (_textures)
|
_texturesLock.EnterReadLock();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// Try to find a perfect texture match, with the same address and parameters.
|
// Try to find a perfect texture match, with the same address and parameters.
|
||||||
sameAddressOverlapsCount = _textures.FindOverlaps(address, ref _textureOverlaps);
|
sameAddressOverlapsCount = _textures.FindOverlaps(address, ref _textureOverlaps);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitReadLock();
|
||||||
|
}
|
||||||
|
|
||||||
Texture texture = null;
|
Texture texture = null;
|
||||||
|
|
||||||
@@ -698,10 +735,16 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
|
|
||||||
if (info.Target != Target.TextureBuffer)
|
if (info.Target != Target.TextureBuffer)
|
||||||
{
|
{
|
||||||
lock (_textures)
|
_texturesLock.EnterReadLock();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
overlapsCount = _textures.FindOverlaps(range.Value, ref _textureOverlaps);
|
overlapsCount = _textures.FindOverlaps(range.Value, ref _textureOverlaps);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitReadLock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_overlapInfo.Length != _textureOverlaps.Length)
|
if (_overlapInfo.Length != _textureOverlaps.Length)
|
||||||
@@ -1025,10 +1068,16 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
_cache.Add(texture);
|
_cache.Add(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (_textures)
|
_texturesLock.EnterWriteLock();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_textures.Add(texture);
|
_textures.Add(texture);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitWriteLock();
|
||||||
|
}
|
||||||
|
|
||||||
if (partiallyMapped)
|
if (partiallyMapped)
|
||||||
{
|
{
|
||||||
@@ -1091,7 +1140,19 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int addressMatches = _textures.FindOverlaps(address, ref _textureOverlaps);
|
int addressMatches;
|
||||||
|
|
||||||
|
_texturesLock.EnterReadLock();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
addressMatches = _textures.FindOverlaps(address, ref _textureOverlaps);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitReadLock();
|
||||||
|
}
|
||||||
|
|
||||||
Texture textureMatch = null;
|
Texture textureMatch = null;
|
||||||
|
|
||||||
for (int i = 0; i < addressMatches; i++)
|
for (int i = 0; i < addressMatches; i++)
|
||||||
@@ -1232,10 +1293,16 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// <param name="texture">The texture to be removed</param>
|
/// <param name="texture">The texture to be removed</param>
|
||||||
public void RemoveTextureFromCache(Texture texture)
|
public void RemoveTextureFromCache(Texture texture)
|
||||||
{
|
{
|
||||||
lock (_textures)
|
_texturesLock.EnterWriteLock();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_textures.Remove(texture);
|
_textures.Remove(texture);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitWriteLock();
|
||||||
|
}
|
||||||
|
|
||||||
lock (_partiallyMappedTextures)
|
lock (_partiallyMappedTextures)
|
||||||
{
|
{
|
||||||
@@ -1324,13 +1391,19 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
lock (_textures)
|
_texturesLock.EnterReadLock();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
foreach (Texture texture in _textures)
|
foreach (Texture texture in _textures)
|
||||||
{
|
{
|
||||||
texture.Dispose();
|
texture.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitReadLock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -88,9 +88,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
private MultiRange TextureRange => Storage.Range;
|
private MultiRange TextureRange => Storage.Range;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The views list from the storage texture.
|
/// The views array from the storage texture.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private List<Texture> _views;
|
private Texture[] _views;
|
||||||
private TextureGroupHandle[] _handles;
|
private TextureGroupHandle[] _handles;
|
||||||
private bool[] _loadNeeded;
|
private bool[] _loadNeeded;
|
||||||
|
|
||||||
@@ -1074,7 +1074,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
public void UpdateViews(List<Texture> views, Texture texture)
|
public void UpdateViews(List<Texture> views, Texture texture)
|
||||||
{
|
{
|
||||||
// This is saved to calculate overlapping views for each handle.
|
// This is saved to calculate overlapping views for each handle.
|
||||||
_views = views;
|
_views = views.ToArray();
|
||||||
|
|
||||||
bool layerViews = _hasLayerViews;
|
bool layerViews = _hasLayerViews;
|
||||||
bool mipViews = _hasMipViews;
|
bool mipViews = _hasMipViews;
|
||||||
@@ -1136,9 +1136,13 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes a view from the group, removing it from all overlap lists.
|
/// Removes a view from the group, removing it from all overlap lists.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="views">The views list of the storage texture</param>
|
||||||
/// <param name="view">View to remove from the group</param>
|
/// <param name="view">View to remove from the group</param>
|
||||||
public void RemoveView(Texture view)
|
public void RemoveView(List<Texture> views, Texture view)
|
||||||
{
|
{
|
||||||
|
// This is saved to calculate overlapping views for each handle.
|
||||||
|
_views = views.ToArray();
|
||||||
|
|
||||||
int offset = FindOffset(view);
|
int offset = FindOffset(view);
|
||||||
|
|
||||||
foreach (TextureGroupHandle handle in _handles)
|
foreach (TextureGroupHandle handle in _handles)
|
||||||
@@ -1605,9 +1609,11 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
|
|
||||||
Storage.SignalModifiedDirty();
|
Storage.SignalModifiedDirty();
|
||||||
|
|
||||||
if (_views != null)
|
Texture[] views = _views;
|
||||||
|
|
||||||
|
if (views != null)
|
||||||
{
|
{
|
||||||
foreach (Texture texture in _views)
|
foreach (Texture texture in views)
|
||||||
{
|
{
|
||||||
texture.SignalModifiedDirty();
|
texture.SignalModifiedDirty();
|
||||||
}
|
}
|
||||||
|
@@ -121,7 +121,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
public TextureGroupHandle(TextureGroup group,
|
public TextureGroupHandle(TextureGroup group,
|
||||||
int offset,
|
int offset,
|
||||||
ulong size,
|
ulong size,
|
||||||
List<Texture> views,
|
IEnumerable<Texture> views,
|
||||||
int firstLayer,
|
int firstLayer,
|
||||||
int firstLevel,
|
int firstLevel,
|
||||||
int baseSlice,
|
int baseSlice,
|
||||||
@@ -201,8 +201,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// Calculate a list of which views overlap this handle.
|
/// Calculate a list of which views overlap this handle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="group">The parent texture group, used to find a view's base CPU VA offset</param>
|
/// <param name="group">The parent texture group, used to find a view's base CPU VA offset</param>
|
||||||
/// <param name="views">The list of views to search for overlaps</param>
|
/// <param name="views">The views to search for overlaps</param>
|
||||||
public void RecalculateOverlaps(TextureGroup group, List<Texture> views)
|
public void RecalculateOverlaps(TextureGroup group, IEnumerable<Texture> views)
|
||||||
{
|
{
|
||||||
// Overlaps can be accessed from the memory tracking signal handler, so access must be atomic.
|
// Overlaps can be accessed from the memory tracking signal handler, so access must be atomic.
|
||||||
lock (Overlaps)
|
lock (Overlaps)
|
||||||
|
@@ -81,6 +81,11 @@ namespace Ryujinx.Input.GTK3
|
|||||||
return _pressedKeys.Contains(nativeKey);
|
return _pressedKeys.Contains(nativeKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_pressedKeys.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
public IGamepad GetGamepad(string id)
|
public IGamepad GetGamepad(string id)
|
||||||
{
|
{
|
||||||
if (!_keyboardIdentifers[0].Equals(id))
|
if (!_keyboardIdentifers[0].Equals(id))
|
||||||
|
@@ -107,6 +107,8 @@ namespace Ryujinx.UI.Applet
|
|||||||
swkbdDialog.SetInputLengthValidation(args.StringLengthMin, args.StringLengthMax);
|
swkbdDialog.SetInputLengthValidation(args.StringLengthMin, args.StringLengthMax);
|
||||||
swkbdDialog.SetInputValidation(args.KeyboardMode);
|
swkbdDialog.SetInputValidation(args.KeyboardMode);
|
||||||
|
|
||||||
|
((MainWindow)_parent).RendererWidget.NpadManager.BlockInputUpdates();
|
||||||
|
|
||||||
if (swkbdDialog.Run() == (int)ResponseType.Ok)
|
if (swkbdDialog.Run() == (int)ResponseType.Ok)
|
||||||
{
|
{
|
||||||
inputText = swkbdDialog.InputEntry.Text;
|
inputText = swkbdDialog.InputEntry.Text;
|
||||||
@@ -128,6 +130,7 @@ namespace Ryujinx.UI.Applet
|
|||||||
});
|
});
|
||||||
|
|
||||||
dialogCloseEvent.WaitOne();
|
dialogCloseEvent.WaitOne();
|
||||||
|
((MainWindow)_parent).RendererWidget.NpadManager.UnblockInputUpdates();
|
||||||
|
|
||||||
userText = error ? null : inputText;
|
userText = error ? null : inputText;
|
||||||
|
|
||||||
|
@@ -174,6 +174,11 @@ namespace Ryujinx.Input.HLE
|
|||||||
{
|
{
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
|
foreach (InputConfig inputConfig in _inputConfig)
|
||||||
|
{
|
||||||
|
_controllers[(int)inputConfig.PlayerIndex].GamepadDriver.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
_blockInputUpdates = false;
|
_blockInputUpdates = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,5 +33,11 @@ namespace Ryujinx.Input
|
|||||||
/// <param name="id">The unique id of the gamepad</param>
|
/// <param name="id">The unique id of the gamepad</param>
|
||||||
/// <returns>An instance of <see cref="IGamepad"/> associated to the gamepad id given or null if not found</returns>
|
/// <returns>An instance of <see cref="IGamepad"/> associated to the gamepad id given or null if not found</returns>
|
||||||
IGamepad GetGamepad(string id);
|
IGamepad GetGamepad(string id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Flush the internal state of the driver.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Does nothing by default.</remarks>
|
||||||
|
void Clear() { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -195,7 +195,7 @@ namespace Ryujinx.Ava.Input
|
|||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
_driver?.ResetKeys();
|
_driver?.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() { }
|
public void Dispose() { }
|
||||||
|
@@ -94,7 +94,7 @@ namespace Ryujinx.Ava.Input
|
|||||||
return _pressedKeys.Contains(nativeKey);
|
return _pressedKeys.Contains(nativeKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetKeys()
|
public void Clear()
|
||||||
{
|
{
|
||||||
_pressedKeys.Clear();
|
_pressedKeys.Clear();
|
||||||
}
|
}
|
||||||
|
@@ -122,6 +122,7 @@ namespace Ryujinx.Ava.UI.Applet
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
_parent.ViewModel.AppHost.NpadManager.BlockInputUpdates();
|
||||||
var response = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard], args);
|
var response = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard], args);
|
||||||
|
|
||||||
if (response.Result == UserResult.Ok)
|
if (response.Result == UserResult.Ok)
|
||||||
@@ -143,6 +144,7 @@ namespace Ryujinx.Ava.UI.Applet
|
|||||||
});
|
});
|
||||||
|
|
||||||
dialogCloseEvent.WaitOne();
|
dialogCloseEvent.WaitOne();
|
||||||
|
_parent.ViewModel.AppHost.NpadManager.UnblockInputUpdates();
|
||||||
|
|
||||||
userText = error ? null : inputText;
|
userText = error ? null : inputText;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user