mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2025-12-11 00:12:06 +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>
|
||||
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>
|
||||
/// Synchronizes host memory with guest memory.
|
||||
/// This causes invalidation of pool entries,
|
||||
|
||||
@@ -738,7 +738,22 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
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>
|
||||
|
||||
@@ -241,25 +241,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
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>
|
||||
/// Check if two descriptors are equal.
|
||||
/// </summary>
|
||||
|
||||
@@ -579,14 +579,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
textureKey.StageIndex);
|
||||
|
||||
int packedId = TextureHandle.ReadPackedId(textureKey.Handle, cachedTextureBuffer, cachedSamplerBuffer);
|
||||
|
||||
int textureId = TextureHandle.UnpackTextureId(packedId);
|
||||
|
||||
ref readonly Image.TextureDescriptor descriptor = ref pool.GetDescriptorRef(textureId);
|
||||
|
||||
if (!MatchesTexture(kv.Value, descriptor))
|
||||
if (pool.IsValidId(textureId))
|
||||
{
|
||||
return false;
|
||||
ref readonly Image.TextureDescriptor descriptor = ref pool.GetDescriptorRef(textureId);
|
||||
|
||||
if (!MatchesTexture(kv.Value, descriptor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -966,6 +966,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
SignalExitToDebugExited();
|
||||
SignalExit();
|
||||
}
|
||||
|
||||
KernelStatic.GetCurrentThread().Exit();
|
||||
}
|
||||
|
||||
private void UnpauseAndTerminateAllThreadsExcept(KThread currentThread)
|
||||
@@ -981,7 +983,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
|
||||
foreach (KThread thread in _threads)
|
||||
{
|
||||
if ((thread.SchedFlags & ThreadSchedState.LowMask) != ThreadSchedState.TerminationPending)
|
||||
if (thread != currentThread && (thread.SchedFlags & ThreadSchedState.LowMask) != ThreadSchedState.TerminationPending)
|
||||
{
|
||||
thread.PrepareForTermination();
|
||||
}
|
||||
|
||||
@@ -227,6 +227,8 @@ namespace Ryujinx.Memory.Tracking
|
||||
// Look up the virtual region using the region list.
|
||||
// Signal up the chain to relevant handles.
|
||||
|
||||
bool shouldThrow = false;
|
||||
|
||||
lock (TrackingLock)
|
||||
{
|
||||
ref var overlaps = ref ThreadStaticArray<VirtualRegion>.Get();
|
||||
@@ -235,32 +237,41 @@ namespace Ryujinx.Memory.Tracking
|
||||
|
||||
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);
|
||||
return false; // We can't handle this - it's probably a real invalid access.
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
VirtualRegion region = overlaps[i];
|
||||
|
||||
if (precise)
|
||||
{
|
||||
region.SignalPrecise(address, size, write);
|
||||
_memoryManager.TrackingReprotect(address & ~(ulong)(_pageSize - 1), (ulong)_pageSize, MemoryPermission.ReadAndWrite);
|
||||
return false; // We can't handle this - it's probably a real invalid access.
|
||||
}
|
||||
else
|
||||
{
|
||||
region.Signal(address, size, write);
|
||||
shouldThrow = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
VirtualRegion region = overlaps[i];
|
||||
|
||||
if (precise)
|
||||
{
|
||||
region.SignalPrecise(address, size, write);
|
||||
}
|
||||
else
|
||||
{
|
||||
region.Signal(address, size, write);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user