diff --git a/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs b/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs index 7e126e044d..ab3befd811 100644 --- a/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs +++ b/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs @@ -236,7 +236,7 @@ namespace Ryujinx.Graphics.Vulkan } else if (texture is TextureView view) { - view.Storage.InsertBarrier(cbs, AccessFlags.ShaderReadBit, stage.ConvertToPipelineStageFlags()); + view.Storage.InsertWriteToReadBarrier(cbs, AccessFlags.ShaderReadBit, stage.ConvertToPipelineStageFlags()); _textureRefs[binding] = view.GetImageView(); _samplerRefs[binding] = ((SamplerHolder)sampler)?.GetSampler(); diff --git a/Ryujinx.Graphics.Vulkan/EnumConversion.cs b/Ryujinx.Graphics.Vulkan/EnumConversion.cs index 6c273b0500..b69c64aa83 100644 --- a/Ryujinx.Graphics.Vulkan/EnumConversion.cs +++ b/Ryujinx.Graphics.Vulkan/EnumConversion.cs @@ -322,7 +322,7 @@ namespace Ryujinx.Graphics.Vulkan GAL.Format.S8Uint => ImageAspectFlags.StencilBit, GAL.Format.D24UnormS8Uint or GAL.Format.D32FloatS8Uint or - GAL.Format.S8UintD24Unorm => ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit, + GAL.Format.S8UintD24Unorm => ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit, _ => ImageAspectFlags.ColorBit }; } diff --git a/Ryujinx.Graphics.Vulkan/FramebufferParams.cs b/Ryujinx.Graphics.Vulkan/FramebufferParams.cs index 0a1cdcce36..658468d17c 100644 --- a/Ryujinx.Graphics.Vulkan/FramebufferParams.cs +++ b/Ryujinx.Graphics.Vulkan/FramebufferParams.cs @@ -218,5 +218,23 @@ namespace Ryujinx.Graphics.Vulkan AccessFlags.DepthStencilAttachmentWriteBit, PipelineStageFlags.ColorAttachmentOutputBit); } + + public void InsertClearBarrier(CommandBufferScoped cbs, int index) + { + if (_colors != null) + { + int realIndex = Array.IndexOf(AttachmentIndices, index); + + if (realIndex != -1) + { + _colors[realIndex].Storage?.InsertReadToWriteBarrier(cbs, AccessFlags.ColorAttachmentWriteBit, PipelineStageFlags.ColorAttachmentOutputBit); + } + } + } + + public void InsertClearBarrierDS(CommandBufferScoped cbs) + { + _depthStencil?.Storage?.InsertReadToWriteBarrier(cbs, AccessFlags.DepthStencilAttachmentWriteBit, PipelineStageFlags.EarlyFragmentTestsBit); + } } } diff --git a/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/Ryujinx.Graphics.Vulkan/PipelineBase.cs index 6c2f168492..2bec529301 100644 --- a/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -226,6 +226,8 @@ namespace Ryujinx.Graphics.Vulkan var attachment = new ClearAttachment(ImageAspectFlags.ColorBit, (uint)index, clearValue); var clearRect = FramebufferParams.GetClearRect(ClearScissor, layer, layerCount); + FramebufferParams.InsertClearBarrier(Cbs, index); + Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect); } @@ -256,6 +258,8 @@ namespace Ryujinx.Graphics.Vulkan var attachment = new ClearAttachment(flags, 0, clearValue); var clearRect = FramebufferParams.GetClearRect(ClearScissor, layer, layerCount); + FramebufferParams.InsertClearBarrierDS(Cbs); + Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect); } diff --git a/Ryujinx.Graphics.Vulkan/TextureStorage.cs b/Ryujinx.Graphics.Vulkan/TextureStorage.cs index 03a47a091b..8ebdd4c0fd 100644 --- a/Ryujinx.Graphics.Vulkan/TextureStorage.cs +++ b/Ryujinx.Graphics.Vulkan/TextureStorage.cs @@ -46,6 +46,8 @@ namespace Ryujinx.Graphics.Vulkan private AccessFlags _lastModificationAccess; private PipelineStageFlags _lastModificationStage; + private AccessFlags _lastReadAccess; + private PipelineStageFlags _lastReadStage; private int _viewsCount; private ulong _size; @@ -440,31 +442,39 @@ namespace Ryujinx.Graphics.Vulkan _lastModificationStage = stage; } - public void InsertBarrier(CommandBufferScoped cbs, AccessFlags dstAccessFlags, PipelineStageFlags dstStageFlags) + public void InsertReadToWriteBarrier(CommandBufferScoped cbs, AccessFlags dstAccessFlags, PipelineStageFlags dstStageFlags) { + if (_lastReadAccess != AccessFlags.NoneKhr) + { + ImageAspectFlags aspectFlags = Info.Format.ConvertAspectFlags(); + + TextureView.InsertImageBarrier( + _gd.Api, + cbs.CommandBuffer, + _imageAuto.Get(cbs).Value, + _lastReadAccess, + dstAccessFlags, + _lastReadStage, + dstStageFlags, + aspectFlags, + 0, + 0, + _info.GetLayers(), + _info.Levels); + + _lastReadAccess = AccessFlags.NoneKhr; + _lastReadStage = PipelineStageFlags.None; + } + } + + public void InsertWriteToReadBarrier(CommandBufferScoped cbs, AccessFlags dstAccessFlags, PipelineStageFlags dstStageFlags) + { + _lastReadAccess |= dstAccessFlags; + _lastReadStage |= dstStageFlags; + if (_lastModificationAccess != AccessFlags.NoneKhr) { - ImageAspectFlags aspectFlags; - - if (_info.Format.IsDepthOrStencil()) - { - if (_info.Format == GAL.Format.S8Uint) - { - aspectFlags = ImageAspectFlags.StencilBit; - } - else if (_info.Format == GAL.Format.D16Unorm || _info.Format == GAL.Format.D32Float) - { - aspectFlags = ImageAspectFlags.DepthBit; - } - else - { - aspectFlags = ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit; - } - } - else - { - aspectFlags = ImageAspectFlags.ColorBit; - } + ImageAspectFlags aspectFlags = Info.Format.ConvertAspectFlags(); TextureView.InsertImageBarrier( _gd.Api,