aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Vulkan/TextureView.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2022-11-02 18:17:19 -0300
committerGitHub <noreply@github.com>2022-11-02 18:17:19 -0300
commitf82309fa2dd46d4339e0709ab835d927fd25361b (patch)
treef864424c938b289780f07a12dc2e52db49721da6 /Ryujinx.Graphics.Vulkan/TextureView.cs
parent7d8e198c33b7ad283db53315129209a2bd310f23 (diff)
Vulkan: Implement multisample <-> non-multisample copies and depth-stencil resolve (#3723)1.1.337
* Vulkan: Implement multisample <-> non-multisample copies and depth-stencil resolve * FramebufferParams is no longer required there * Implement Specialization Constants and merge CopyMS Shaders (#15) * Vulkan: Initial Specialization Constants * Replace with specialized helper shader * Reimplement everything Fix nonexistant interaction with Ryu pipeline caching Decouple specialization info from data and relocate them Generalize mapping and add type enum to better match spv types Use local fixed scopes instead of global unmanaged allocs * Fix misses in initial implementation Use correct info variable in Create2DLayerView Add ShaderStorageImageMultisample to required feature set * Use texture for source image * No point in using ReadOnlyMemory * Apply formatting feedback Co-authored-by: gdkchan <gab.dark.100@gmail.com> * Apply formatting suggestions on shader source Co-authored-by: gdkchan <gab.dark.100@gmail.com> Co-authored-by: gdkchan <gab.dark.100@gmail.com> * Support conversion with samples count that does not match the requested count, other minor changes Co-authored-by: mageven <62494521+mageven@users.noreply.github.com>
Diffstat (limited to 'Ryujinx.Graphics.Vulkan/TextureView.cs')
-rw-r--r--Ryujinx.Graphics.Vulkan/TextureView.cs200
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;
}