Allow partially mapped textures with unmapped start (#4394)
This commit is contained in:
parent
5f38086f94
commit
61b1ce252f
2 changed files with 39 additions and 0 deletions
|
@ -474,6 +474,13 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
{
|
{
|
||||||
address = memoryManager.Translate(info.GpuAddress);
|
address = memoryManager.Translate(info.GpuAddress);
|
||||||
|
|
||||||
|
// If the start address is unmapped, let's try to find a page of memory that is mapped.
|
||||||
|
if (address == MemoryManager.PteUnmapped)
|
||||||
|
{
|
||||||
|
address = memoryManager.TranslateFirstMapped(info.GpuAddress, (ulong)info.CalculateSizeInfo(layerSize).TotalSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If address is still invalid, the texture is fully unmapped, so it has no data, just return null.
|
||||||
if (address == MemoryManager.PteUnmapped)
|
if (address == MemoryManager.PteUnmapped)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -583,6 +583,38 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
return UnpackPaFromPte(pte) + (va & PageMask);
|
return UnpackPaFromPte(pte) + (va & PageMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Translates a GPU virtual address to a CPU virtual address on the first mapped page of memory
|
||||||
|
/// on the specified region.
|
||||||
|
/// If no page is mapped on the specified region, <see cref="PteUnmapped"/> is returned.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="va">GPU virtual address to be translated</param>
|
||||||
|
/// <param name="size">Size of the range to be translated</param>
|
||||||
|
/// <returns>CPU virtual address, or <see cref="PteUnmapped"/> if unmapped</returns>
|
||||||
|
public ulong TranslateFirstMapped(ulong va, ulong size)
|
||||||
|
{
|
||||||
|
if (!ValidateAddress(va))
|
||||||
|
{
|
||||||
|
return PteUnmapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong endVa = va + size;
|
||||||
|
|
||||||
|
ulong pte = GetPte(va);
|
||||||
|
|
||||||
|
for (; va < endVa && pte == PteUnmapped; va += PageSize - (va & PageMask))
|
||||||
|
{
|
||||||
|
pte = GetPte(va);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pte == PteUnmapped)
|
||||||
|
{
|
||||||
|
return PteUnmapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UnpackPaFromPte(pte) + (va & PageMask);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the kind of a given memory page.
|
/// Gets the kind of a given memory page.
|
||||||
/// This might indicate the type of resource that can be allocated on the page, and also texture tiling.
|
/// This might indicate the type of resource that can be allocated on the page, and also texture tiling.
|
||||||
|
|
Reference in a new issue