Support copy between multisample and non-multisample depth textures (#4676)
* Support copy between multisample and non-multisample depth textures * PR feedback
This commit is contained in:
parent
eabd0ec93f
commit
d9b63353b0
12 changed files with 947 additions and 66 deletions
|
@ -117,12 +117,20 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
TextureView destinationView = (TextureView)destination;
|
||||
|
||||
if (!destinationView.Target.IsMultisample() && Target.IsMultisample())
|
||||
bool srcIsMultisample = Target.IsMultisample();
|
||||
bool dstIsMultisample = destinationView.Target.IsMultisample();
|
||||
|
||||
if (dstIsMultisample != srcIsMultisample && Info.Format.IsDepthOrStencil())
|
||||
{
|
||||
int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
|
||||
CopyWithBlitForDepthMS(destinationView, 0, firstLayer, layers);
|
||||
}
|
||||
else if (!dstIsMultisample && srcIsMultisample)
|
||||
{
|
||||
int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
|
||||
_renderer.TextureCopyMS.CopyMSToNonMS(this, destinationView, 0, firstLayer, layers);
|
||||
}
|
||||
else if (destinationView.Target.IsMultisample() && !Target.IsMultisample())
|
||||
else if (dstIsMultisample && !srcIsMultisample)
|
||||
{
|
||||
int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
|
||||
_renderer.TextureCopyMS.CopyNonMSToMS(this, destinationView, 0, firstLayer, layers);
|
||||
|
@ -143,11 +151,18 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
TextureView destinationView = (TextureView)destination;
|
||||
|
||||
if (!destinationView.Target.IsMultisample() && Target.IsMultisample())
|
||||
bool srcIsMultisample = Target.IsMultisample();
|
||||
bool dstIsMultisample = destinationView.Target.IsMultisample();
|
||||
|
||||
if (dstIsMultisample != srcIsMultisample && Info.Format.IsDepthOrStencil())
|
||||
{
|
||||
CopyWithBlitForDepthMS(destinationView, srcLayer, dstLayer, 1);
|
||||
}
|
||||
else if (!dstIsMultisample && srcIsMultisample)
|
||||
{
|
||||
_renderer.TextureCopyMS.CopyMSToNonMS(this, destinationView, srcLayer, dstLayer, 1);
|
||||
}
|
||||
else if (destinationView.Target.IsMultisample() && !Target.IsMultisample())
|
||||
else if (dstIsMultisample && !srcIsMultisample)
|
||||
{
|
||||
_renderer.TextureCopyMS.CopyNonMSToMS(this, destinationView, srcLayer, dstLayer, 1);
|
||||
}
|
||||
|
@ -161,6 +176,61 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
}
|
||||
}
|
||||
|
||||
private void CopyWithBlitForDepthMS(TextureView destinationView, int srcLayer, int dstLayer, int layers)
|
||||
{
|
||||
// This is currently used for multisample <-> non-multisample copies.
|
||||
// We can't do that with compute because it's not possible to write depth textures on compute.
|
||||
// It can be done with draws, but we don't have support for saving and restoring the OpenGL state
|
||||
// for a draw with different state right now.
|
||||
// This approach uses blit, which causes a resolution loss since some samples will be lost
|
||||
// in the process.
|
||||
|
||||
Extents2D srcRegion = new Extents2D(0, 0, Width, Height);
|
||||
Extents2D dstRegion = new Extents2D(0, 0, destinationView.Width, destinationView.Height);
|
||||
|
||||
if (destinationView.Target.IsMultisample())
|
||||
{
|
||||
TextureView intermmediate = _renderer.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast(
|
||||
Info.Target,
|
||||
Info.BlockWidth,
|
||||
Info.BlockHeight,
|
||||
Info.BytesPerPixel,
|
||||
Format,
|
||||
destinationView.Width,
|
||||
destinationView.Height,
|
||||
Info.Depth,
|
||||
1,
|
||||
1);
|
||||
|
||||
_renderer.TextureCopy.Copy(this, intermmediate, srcRegion, dstRegion, false);
|
||||
_renderer.TextureCopy.Copy(intermmediate, destinationView, dstRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, layers, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Target target = Target switch
|
||||
{
|
||||
Target.Texture2DMultisample => Target.Texture2D,
|
||||
Target.Texture2DMultisampleArray => Target.Texture2DArray,
|
||||
_ => Target
|
||||
};
|
||||
|
||||
TextureView intermmediate = _renderer.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast(
|
||||
target,
|
||||
Info.BlockWidth,
|
||||
Info.BlockHeight,
|
||||
Info.BytesPerPixel,
|
||||
Format,
|
||||
Width,
|
||||
Height,
|
||||
Info.Depth,
|
||||
1,
|
||||
1);
|
||||
|
||||
_renderer.TextureCopy.Copy(this, intermmediate, srcRegion, srcRegion, false);
|
||||
_renderer.TextureCopy.Copy(intermmediate, destinationView, srcRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, layers, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
|
||||
{
|
||||
_renderer.TextureCopy.Copy(this, (TextureView)destination, srcRegion, dstRegion, linearFilter);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue