diff options
author | riperiperi <rhy3756547@hotmail.com> | 2023-03-26 11:51:02 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-26 12:51:02 +0200 |
commit | a34fb0e9392c59e5bd7a764b83f3460bf65b861b (patch) | |
tree | 486113d26809d85f6567866a18df5a8f3fc456f5 /Ryujinx.Graphics.Vulkan/TextureStorage.cs | |
parent | 21ce8a9b80c94b0636acb4a8762d8516bdb800e2 (diff) |
Vulkan: Insert barriers before clears (#4596)1.1.682
* Vulkan: Insert barriers before clears
Newer NVIDIA GPUs seem to be able to start clearing render targets before the last rasterization task is completed, which can cause it to clear a texture while it is being sampled.
This change adds a barrier from read to write when doing a clear, assuming it has been sampled in the past. It could be possible for this to be needed for sample into draw by some GPU, but it's not right now afaik.
This should fix visual artifacts on newer NVIDIA GPUs and driver combos. Contrary to popular belief, TetrisĀ® Effect: Connected is not affected. Testing welcome, hopefully should fix most cases of this and not cost too much performance.
* Visual Studio Moment
* Address feedback
* Address Feedback 2
Diffstat (limited to 'Ryujinx.Graphics.Vulkan/TextureStorage.cs')
-rw-r--r-- | Ryujinx.Graphics.Vulkan/TextureStorage.cs | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/Ryujinx.Graphics.Vulkan/TextureStorage.cs b/Ryujinx.Graphics.Vulkan/TextureStorage.cs index 03a47a09..8ebdd4c0 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 (_lastModificationAccess != AccessFlags.NoneKhr) + if (_lastReadAccess != AccessFlags.NoneKhr) { - ImageAspectFlags aspectFlags; + ImageAspectFlags aspectFlags = Info.Format.ConvertAspectFlags(); - 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; - } + 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 = Info.Format.ConvertAspectFlags(); TextureView.InsertImageBarrier( _gd.Api, |