From f864a490142c4da608dab8d2025fc18da857f93f Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 18 May 2023 18:16:03 -0300 Subject: [PATCH] Fix Vulkan blit-like operations swizzle (#5003) --- .../DescriptorSetUpdater.cs | 29 ++++++++++++++++++- src/Ryujinx.Graphics.Vulkan/HelperShader.cs | 12 ++++---- src/Ryujinx.Graphics.Vulkan/PipelineBase.cs | 5 ++++ 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs index ab3befd8..a47ea5ff 100644 --- a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs +++ b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs @@ -228,7 +228,12 @@ namespace Ryujinx.Graphics.Vulkan SignalDirty(DirtyFlags.Storage); } - public void SetTextureAndSampler(CommandBufferScoped cbs, ShaderStage stage, int binding, ITexture texture, ISampler sampler) + public void SetTextureAndSampler( + CommandBufferScoped cbs, + ShaderStage stage, + int binding, + ITexture texture, + ISampler sampler) { if (texture is TextureBuffer textureBuffer) { @@ -251,6 +256,28 @@ namespace Ryujinx.Graphics.Vulkan SignalDirty(DirtyFlags.Texture); } + public void SetTextureAndSamplerIdentitySwizzle( + CommandBufferScoped cbs, + ShaderStage stage, + int binding, + ITexture texture, + ISampler sampler) + { + if (texture is TextureView view) + { + view.Storage.InsertWriteToReadBarrier(cbs, AccessFlags.ShaderReadBit, stage.ConvertToPipelineStageFlags()); + + _textureRefs[binding] = view.GetIdentityImageView(); + _samplerRefs[binding] = ((SamplerHolder)sampler)?.GetSampler(); + + SignalDirty(DirtyFlags.Texture); + } + else + { + SetTextureAndSampler(cbs, stage, binding, texture, sampler); + } + } + public void SetUniformBuffers(CommandBuffer commandBuffer, ReadOnlySpan buffers) { for (int i = 0; i < buffers.Length; i++) diff --git a/src/Ryujinx.Graphics.Vulkan/HelperShader.cs b/src/Ryujinx.Graphics.Vulkan/HelperShader.cs index 155c7f6f..c064696d 100644 --- a/src/Ryujinx.Graphics.Vulkan/HelperShader.cs +++ b/src/Ryujinx.Graphics.Vulkan/HelperShader.cs @@ -415,7 +415,7 @@ namespace Ryujinx.Graphics.Vulkan var sampler = linearFilter ? _samplerLinear : _samplerNearest; - _pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, src, sampler); + _pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Fragment, 0, src, sampler); Span region = stackalloc float[RegionBufferSize / sizeof(float)]; @@ -625,7 +625,7 @@ namespace Ryujinx.Graphics.Vulkan private void BlitDepthStencilDraw(TextureView src, bool isDepth) { - _pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, src, _samplerNearest); + _pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Fragment, 0, src, _samplerNearest); if (isDepth) { @@ -1037,7 +1037,7 @@ namespace Ryujinx.Graphics.Vulkan var srcView = Create2DLayerView(src, srcLayer + z, srcLevel + l, srcFormat); var dstView = Create2DLayerView(dst, dstLayer + z, dstLevel + l); - _pipeline.SetTextureAndSampler(ShaderStage.Compute, 0, srcView, null); + _pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Compute, 0, srcView, null); _pipeline.SetImage(0, dstView, dstFormat); int dispatchX = (Math.Min(srcView.Info.Width, dstView.Info.Width) + 31) / 32; @@ -1177,7 +1177,7 @@ namespace Ryujinx.Graphics.Vulkan var srcView = Create2DLayerView(src, srcLayer + z, 0, format); var dstView = Create2DLayerView(dst, dstLayer + z, 0); - _pipeline.SetTextureAndSampler(ShaderStage.Compute, 0, srcView, null); + _pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Compute, 0, srcView, null); _pipeline.SetImage(0, dstView, format); _pipeline.DispatchCompute(dispatchX, dispatchY, 1); @@ -1313,7 +1313,7 @@ namespace Ryujinx.Graphics.Vulkan var srcView = Create2DLayerView(src, srcLayer + z, 0, format); var dstView = Create2DLayerView(dst, dstLayer + z, 0); - _pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, srcView, null); + _pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Fragment, 0, srcView, null); _pipeline.SetRenderTarget( ((TextureView)dstView).GetView(format).GetImageViewForAttachment(), (uint)dst.Width, @@ -1384,7 +1384,7 @@ namespace Ryujinx.Graphics.Vulkan private void CopyMSAspectDraw(TextureView src, bool fromMS, bool isDepth) { - _pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, src, _samplerNearest); + _pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Fragment, 0, src, _samplerNearest); if (isDepth) { diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index 4aec0dbc..ce6148e2 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -1098,6 +1098,11 @@ namespace Ryujinx.Graphics.Vulkan _descriptorSetUpdater.SetTextureAndSampler(Cbs, stage, binding, texture, sampler); } + public void SetTextureAndSamplerIdentitySwizzle(ShaderStage stage, int binding, ITexture texture, ISampler sampler) + { + _descriptorSetUpdater.SetTextureAndSamplerIdentitySwizzle(Cbs, stage, binding, texture, sampler); + } + public void SetTransformFeedbackBuffers(ReadOnlySpan buffers) { PauseTransformFeedbackInternal();