diff options
Diffstat (limited to 'Ryujinx.Graphics.Vulkan/TextureView.cs')
-rw-r--r-- | Ryujinx.Graphics.Vulkan/TextureView.cs | 200 |
1 files changed, 40 insertions, 160 deletions
diff --git a/Ryujinx.Graphics.Vulkan/TextureView.cs b/Ryujinx.Graphics.Vulkan/TextureView.cs index 10d0ef05..f47e431b 100644 --- a/Ryujinx.Graphics.Vulkan/TextureView.cs +++ b/Ryujinx.Graphics.Vulkan/TextureView.cs @@ -169,12 +169,15 @@ namespace Ryujinx.Graphics.Vulkan var srcImage = src.GetImage().Get(cbs).Value; var dstImage = dst.GetImage().Get(cbs).Value; - if (src.Info.Target.IsMultisample()) + if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample()) { - int depth = Math.Min(src.Info.Depth, dst.Info.Depth - firstLayer); - int levels = Math.Min(src.Info.Levels, dst.Info.Levels - firstLevel); - - CopyMSToNonMS(_gd, cbs, src, dst, srcImage, dstImage, 0, firstLayer, 0, firstLevel, depth, levels); + int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer); + _gd.HelperShader.CopyMSToNonMS(_gd, cbs, src, dst, 0, firstLayer, layers); + } + else if (dst.Info.Target.IsMultisample() && !Info.Target.IsMultisample()) + { + int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer); + _gd.HelperShader.CopyNonMSToMS(_gd, cbs, src, dst, 0, firstLayer, layers); } else { @@ -213,9 +216,13 @@ namespace Ryujinx.Graphics.Vulkan var srcImage = src.GetImage().Get(cbs).Value; var dstImage = dst.GetImage().Get(cbs).Value; - if (src.Info.Target.IsMultisample()) + if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample()) { - CopyMSToNonMS(_gd, cbs, src, dst, srcImage, dstImage, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1); + _gd.HelperShader.CopyMSToNonMS(_gd, cbs, src, dst, srcLayer, dstLayer, 1); + } + else if (dst.Info.Target.IsMultisample() && !Info.Target.IsMultisample()) + { + _gd.HelperShader.CopyNonMSToMS(_gd, cbs, src, dst, srcLayer, dstLayer, 1); } else { @@ -239,142 +246,6 @@ namespace Ryujinx.Graphics.Vulkan } } - private static void CopyMSToNonMS( - VulkanRenderer gd, - CommandBufferScoped cbs, - TextureView src, - TextureView dst, - Image srcImage, - Image dstImage, - int srcLayer, - int dstLayer, - int srcLevel, - int dstLevel, - int layers, - int levels) - { - bool differentFormats = src.Info.Format != dst.Info.Format; - - var target = src.Info.Target switch - { - Target.Texture2D => Target.Texture2DMultisample, - Target.Texture2DArray => Target.Texture2DMultisampleArray, - Target.Texture2DMultisampleArray => Target.Texture2DArray, - _ => Target.Texture2D - }; - - var intermmediateTarget = differentFormats ? dst.Info.Target : target; - using var intermmediate = CreateIntermmediateTexture(gd, src, ref dst._info, intermmediateTarget, layers, levels); - var intermmediateImage = intermmediate.GetImage().Get(cbs).Value; - - if (differentFormats) - { - // If the formats are different, the resolve would perform format conversion. - // So we need yet another intermmediate texture and do a copy to reinterpret the - // data into the correct (destination) format, without doing any sort of conversion. - using var intermmediate2 = CreateIntermmediateTexture(gd, src, ref src._info, target, layers, levels); - var intermmediate2Image = intermmediate2.GetImage().Get(cbs).Value; - - TextureCopy.Copy( - gd.Api, - cbs.CommandBuffer, - srcImage, - intermmediate2Image, - src.Info, - intermmediate2.Info, - src.FirstLayer, - 0, - src.FirstLevel, - 0, - srcLayer, - 0, - srcLevel, - 0, - layers, - levels); - - TextureCopy.Copy( - gd.Api, - cbs.CommandBuffer, - intermmediate2Image, - intermmediateImage, - intermmediate2.Info, - intermmediate.Info, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - layers, - levels); - } - else - { - TextureCopy.Copy( - gd.Api, - cbs.CommandBuffer, - srcImage, - intermmediateImage, - src.Info, - intermmediate.Info, - src.FirstLayer, - 0, - src.FirstLevel, - 0, - srcLayer, - 0, - srcLevel, - 0, - layers, - levels); - } - - var srcRegion = new Extents2D(0, 0, src.Width, src.Height); - var dstRegion = new Extents2D(0, 0, dst.Width, dst.Height); - - TextureCopy.Blit( - gd.Api, - cbs.CommandBuffer, - intermmediateImage, - dstImage, - intermmediate.Info, - dst.Info, - srcRegion, - dstRegion, - 0, - dst.FirstLevel + dstLevel, - 0, - dst.FirstLayer + dstLayer, - layers, - levels, - true, - ImageAspectFlags.ImageAspectColorBit, - ImageAspectFlags.ImageAspectColorBit); - } - - private static TextureView CreateIntermmediateTexture(VulkanRenderer gd, TextureView src, ref TextureCreateInfo formatInfo, Target target, int depth, int levels) - { - return gd.CreateTextureView(new GAL.TextureCreateInfo( - src.Width, - src.Height, - depth, - levels, - 1, - formatInfo.BlockWidth, - formatInfo.BlockHeight, - formatInfo.BytesPerPixel, - formatInfo.Format, - DepthStencilMode.Depth, - target, - SwizzleComponent.Red, - SwizzleComponent.Green, - SwizzleComponent.Blue, - SwizzleComponent.Alpha), 1f); - } - public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter) { var dst = (TextureView)destination; @@ -422,23 +293,32 @@ namespace Ryujinx.Graphics.Vulkan src.Height == dst.Height && src.VkFormat == dst.VkFormat) { - TextureCopy.Copy( - _gd.Api, - cbs.CommandBuffer, - src.GetImage().Get(cbs).Value, - dst.GetImage().Get(cbs).Value, - src.Info, - dst.Info, - src.FirstLayer, - dst.FirstLayer, - src.FirstLevel, - dst.FirstLevel, - 0, - 0, - 0, - 0, - layers, - levels); + if (src.Info.Samples > 1 && src.Info.Samples != dst.Info.Samples && src.Info.Format.IsDepthOrStencil()) + { + // CmdResolveImage does not support depth-stencil resolve, so we need to use an alternative path + // for those textures. + TextureCopy.ResolveDepthStencil(_gd, _device, cbs, src, dst); + } + else + { + TextureCopy.Copy( + _gd.Api, + cbs.CommandBuffer, + src.GetImage().Get(cbs).Value, + dst.GetImage().Get(cbs).Value, + src.Info, + dst.Info, + src.FirstLayer, + dst.FirstLayer, + src.FirstLevel, + dst.FirstLevel, + 0, + 0, + 0, + 0, + layers, + levels); + } return; } |