Texture Sync, incompatible overlap handling, data flush improvements. (#2971)
* Initial test for texture sync * WIP new texture flushing setup * Improve rules for incompatible overlaps Fixes a lot of issues with Unreal Engine games. Still a few minor issues (some caused by dma fast path?) Needs docs and cleanup. * Cleanup, improvements Improve rules for fast DMA * Small tweak to group together flushes of overlapping handles. * Fixes, flush overlapping texture data for ASTC and BC4/5 compressed textures. Fixes the new Life is Strange game. * Flush overlaps before init data, fix 3d texture size/overlap stuff * Fix 3D Textures, faster single layer flush Note: nosy people can no longer merge this with Vulkan. (unless they are nosy enough to implement the new backend methods) * Remove unused method * Minor cleanup * More cleanup * Use the More Fun and Hopefully No Driver Bugs method for getting compressed tex too This one's for metro * Address feedback, ASTC+ETC to FormatClass * Change offset to use Span slice rather than IntPtr Add * Fix this too
This commit is contained in:
parent
4864648e72
commit
cda659955c
26 changed files with 1453 additions and 329 deletions
|
@ -154,6 +154,24 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
}
|
||||
}
|
||||
|
||||
public unsafe ReadOnlySpan<byte> GetData(int layer, int level)
|
||||
{
|
||||
int size = Info.GetMipSize(level);
|
||||
|
||||
if (HwCapabilities.UsePersistentBufferForFlush)
|
||||
{
|
||||
return _renderer.PersistentBuffers.Default.GetTextureData(this, size, layer, level);
|
||||
}
|
||||
else
|
||||
{
|
||||
IntPtr target = _renderer.PersistentBuffers.Default.GetHostArray(size);
|
||||
|
||||
int offset = WriteTo2D(target, layer, level);
|
||||
|
||||
return new ReadOnlySpan<byte>(target.ToPointer(), size).Slice(offset);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteToPbo(int offset, bool forceBgra)
|
||||
{
|
||||
WriteTo(IntPtr.Zero + offset, forceBgra);
|
||||
|
@ -182,25 +200,29 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
int mipSize = Info.GetMipSize2D(level);
|
||||
|
||||
// The GL function returns all layers. Must return the offset of the layer we're interested in.
|
||||
int resultOffset = target switch
|
||||
{
|
||||
TextureTarget.TextureCubeMapArray => (layer / 6) * mipSize,
|
||||
TextureTarget.Texture1DArray => layer * mipSize,
|
||||
TextureTarget.Texture2DArray => layer * mipSize,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
if (format.IsCompressed)
|
||||
{
|
||||
GL.GetCompressedTexImage(target, level, data);
|
||||
GL.GetCompressedTextureSubImage(Handle, level, 0, 0, layer, Math.Max(1, Info.Width >> level), Math.Max(1, Info.Height >> level), 1, mipSize, data);
|
||||
}
|
||||
else if (format.PixelFormat != PixelFormat.DepthStencil)
|
||||
{
|
||||
GL.GetTextureSubImage(Handle, level, 0, 0, layer, Math.Max(1, Info.Width >> level), Math.Max(1, Info.Height >> level), 1, pixelFormat, pixelType, mipSize, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.GetTexImage(target, level, pixelFormat, pixelType, data);
|
||||
|
||||
// The GL function returns all layers. Must return the offset of the layer we're interested in.
|
||||
return target switch
|
||||
{
|
||||
TextureTarget.TextureCubeMapArray => (layer / 6) * mipSize,
|
||||
TextureTarget.Texture1DArray => layer * mipSize,
|
||||
TextureTarget.Texture2DArray => layer * mipSize,
|
||||
_ => 0
|
||||
};
|
||||
}
|
||||
|
||||
return resultOffset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void WriteTo(IntPtr data, bool forceBgra = false)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue