mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2025-12-13 10:02:05 +01:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
232b1012b0 | ||
|
|
e747f5cd83 |
@@ -101,6 +101,16 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// <returns>The GPU resource with the given ID</returns>
|
/// <returns>The GPU resource with the given ID</returns>
|
||||||
public abstract T1 Get(int id);
|
public abstract T1 Get(int id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if a given ID is valid and inside the range of the pool.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">ID of the descriptor. This is effectively a zero-based index</param>
|
||||||
|
/// <returns>True if the specified ID is valid, false otherwise</returns>
|
||||||
|
public bool IsValidId(int id)
|
||||||
|
{
|
||||||
|
return (uint)id <= MaximumId;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Synchronizes host memory with guest memory.
|
/// Synchronizes host memory with guest memory.
|
||||||
/// This causes invalidation of pool entries,
|
/// This causes invalidation of pool entries,
|
||||||
|
|||||||
@@ -738,7 +738,22 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
|
|
||||||
TexturePool texturePool = _texturePoolCache.FindOrCreate(_channel, poolAddress, maximumId);
|
TexturePool texturePool = _texturePoolCache.FindOrCreate(_channel, poolAddress, maximumId);
|
||||||
|
|
||||||
return texturePool.GetDescriptor(textureId);
|
TextureDescriptor descriptor;
|
||||||
|
|
||||||
|
if (texturePool.IsValidId(textureId))
|
||||||
|
{
|
||||||
|
descriptor = texturePool.GetDescriptor(textureId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the ID is not valid, we just return a default descriptor with the most common state.
|
||||||
|
// Since this is used for shader specialization, doing so might avoid the need for recompilations.
|
||||||
|
descriptor = new TextureDescriptor();
|
||||||
|
descriptor.Word4 |= (uint)TextureTarget.Texture2D << 23;
|
||||||
|
descriptor.Word5 |= 1u << 31; // Coords normalized.
|
||||||
|
}
|
||||||
|
|
||||||
|
return descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -241,25 +241,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
return (TextureMsaaMode)((Word7 >> 8) & 0xf);
|
return (TextureMsaaMode)((Word7 >> 8) & 0xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create the equivalent of this TextureDescriptor for the shader cache.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The equivalent of this TextureDescriptor for the shader cache.</returns>
|
|
||||||
public GuestTextureDescriptor ToCache()
|
|
||||||
{
|
|
||||||
GuestTextureDescriptor result = new GuestTextureDescriptor
|
|
||||||
{
|
|
||||||
Handle = uint.MaxValue,
|
|
||||||
Format = UnpackFormat(),
|
|
||||||
Target = UnpackTextureTarget(),
|
|
||||||
IsSrgb = UnpackSrgb(),
|
|
||||||
IsTextureCoordNormalized = UnpackTextureCoordNormalized(),
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if two descriptors are equal.
|
/// Check if two descriptors are equal.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -579,9 +579,10 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
textureKey.StageIndex);
|
textureKey.StageIndex);
|
||||||
|
|
||||||
int packedId = TextureHandle.ReadPackedId(textureKey.Handle, cachedTextureBuffer, cachedSamplerBuffer);
|
int packedId = TextureHandle.ReadPackedId(textureKey.Handle, cachedTextureBuffer, cachedSamplerBuffer);
|
||||||
|
|
||||||
int textureId = TextureHandle.UnpackTextureId(packedId);
|
int textureId = TextureHandle.UnpackTextureId(packedId);
|
||||||
|
|
||||||
|
if (pool.IsValidId(textureId))
|
||||||
|
{
|
||||||
ref readonly Image.TextureDescriptor descriptor = ref pool.GetDescriptorRef(textureId);
|
ref readonly Image.TextureDescriptor descriptor = ref pool.GetDescriptorRef(textureId);
|
||||||
|
|
||||||
if (!MatchesTexture(kv.Value, descriptor))
|
if (!MatchesTexture(kv.Value, descriptor))
|
||||||
@@ -590,6 +591,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -966,6 +966,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||||||
SignalExitToDebugExited();
|
SignalExitToDebugExited();
|
||||||
SignalExit();
|
SignalExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KernelStatic.GetCurrentThread().Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UnpauseAndTerminateAllThreadsExcept(KThread currentThread)
|
private void UnpauseAndTerminateAllThreadsExcept(KThread currentThread)
|
||||||
@@ -981,7 +983,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||||||
|
|
||||||
foreach (KThread thread in _threads)
|
foreach (KThread thread in _threads)
|
||||||
{
|
{
|
||||||
if ((thread.SchedFlags & ThreadSchedState.LowMask) != ThreadSchedState.TerminationPending)
|
if (thread != currentThread && (thread.SchedFlags & ThreadSchedState.LowMask) != ThreadSchedState.TerminationPending)
|
||||||
{
|
{
|
||||||
thread.PrepareForTermination();
|
thread.PrepareForTermination();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,6 +227,8 @@ namespace Ryujinx.Memory.Tracking
|
|||||||
// Look up the virtual region using the region list.
|
// Look up the virtual region using the region list.
|
||||||
// Signal up the chain to relevant handles.
|
// Signal up the chain to relevant handles.
|
||||||
|
|
||||||
|
bool shouldThrow = false;
|
||||||
|
|
||||||
lock (TrackingLock)
|
lock (TrackingLock)
|
||||||
{
|
{
|
||||||
ref var overlaps = ref ThreadStaticArray<VirtualRegion>.Get();
|
ref var overlaps = ref ThreadStaticArray<VirtualRegion>.Get();
|
||||||
@@ -235,19 +237,18 @@ namespace Ryujinx.Memory.Tracking
|
|||||||
|
|
||||||
if (count == 0 && !precise)
|
if (count == 0 && !precise)
|
||||||
{
|
{
|
||||||
if (!_memoryManager.IsMapped(address))
|
if (_memoryManager.IsMapped(address))
|
||||||
{
|
{
|
||||||
_invalidAccessHandler?.Invoke(address);
|
|
||||||
|
|
||||||
// We can't continue - it's impossible to remove protection from the page.
|
|
||||||
// Even if the access handler wants us to continue, we wouldn't be able to.
|
|
||||||
throw new InvalidMemoryRegionException();
|
|
||||||
}
|
|
||||||
|
|
||||||
_memoryManager.TrackingReprotect(address & ~(ulong)(_pageSize - 1), (ulong)_pageSize, MemoryPermission.ReadAndWrite);
|
_memoryManager.TrackingReprotect(address & ~(ulong)(_pageSize - 1), (ulong)_pageSize, MemoryPermission.ReadAndWrite);
|
||||||
return false; // We can't handle this - it's probably a real invalid access.
|
return false; // We can't handle this - it's probably a real invalid access.
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shouldThrow = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
VirtualRegion region = overlaps[i];
|
VirtualRegion region = overlaps[i];
|
||||||
@@ -262,6 +263,16 @@ namespace Ryujinx.Memory.Tracking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldThrow)
|
||||||
|
{
|
||||||
|
_invalidAccessHandler?.Invoke(address);
|
||||||
|
|
||||||
|
// We can't continue - it's impossible to remove protection from the page.
|
||||||
|
// Even if the access handler wants us to continue, we wouldn't be able to.
|
||||||
|
throw new InvalidMemoryRegionException();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user