diff options
author | riperiperi <rhy3756547@hotmail.com> | 2024-01-31 22:49:50 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-31 23:49:50 +0100 |
commit | c94f0fbb8307873f68df982c100d3fb01aa6ccf5 (patch) | |
tree | 327a039f016b3e0ae45713e0f5dd413a04d673ae /src/Ryujinx.Graphics.Vulkan/PipelineBase.cs | |
parent | d1b30fbe08d79ad81167358779d77cf4e7167386 (diff) |
Vulkan: Add Render Pass / Framebuffer Cache (#6182)1.1.1154
* Vulkan: Add Render Pass / Framebuffer Cache
Cache is owned by each texture view.
- Window's way of getting framebuffer cache for swapchain images is really messy - it creates a TextureView out of just a vk image view, with invalid info and no storage.
* Clear up limited use of alternate TextureView constructor
* Formatting and messages
* More formatting and messages
I apologize for `_colorsCanonical[index]?.Storage?.InsertReadToWriteBarrier`, the compiler made me do it
* Self review, change GetFramebuffer to GetPassAndFramebuffer
* Avoid allocations on Remove for HashTableSlim
* Member can be readonly
* Generate texture create info for swapchain images
* Improve hashcode
* Remove format, samples, size and isDepthStencil when possible
Tested in a number of games, seems fine.
* Removed load op barriers
These can be introduced later.
* Reintroduce UpdateModifications
Technically meant to be replaced by load op stuff.
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/PipelineBase.cs')
-rw-r--r-- | src/Ryujinx.Graphics.Vulkan/PipelineBase.cs | 98 |
1 files changed, 11 insertions, 87 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index 61215b67..3aef1317 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -55,6 +55,7 @@ namespace Ryujinx.Graphics.Vulkan protected FramebufferParams FramebufferParams; private Auto<DisposableFramebuffer> _framebuffer; private Auto<DisposableRenderPass> _renderPass; + private RenderPassHolder _nullRenderPass; private int _writtenAttachmentCount; private bool _framebufferUsingColorWriteMask; @@ -1488,98 +1489,22 @@ namespace Ryujinx.Graphics.Vulkan protected unsafe void CreateRenderPass() { - const int MaxAttachments = Constants.MaxRenderTargets + 1; - - AttachmentDescription[] attachmentDescs = null; - - var subpass = new SubpassDescription - { - PipelineBindPoint = PipelineBindPoint.Graphics, - }; - - AttachmentReference* attachmentReferences = stackalloc AttachmentReference[MaxAttachments]; - var hasFramebuffer = FramebufferParams != null; - if (hasFramebuffer && FramebufferParams.AttachmentsCount != 0) - { - attachmentDescs = new AttachmentDescription[FramebufferParams.AttachmentsCount]; - - for (int i = 0; i < FramebufferParams.AttachmentsCount; i++) - { - attachmentDescs[i] = new AttachmentDescription( - 0, - FramebufferParams.AttachmentFormats[i], - TextureStorage.ConvertToSampleCountFlags(Gd.Capabilities.SupportedSampleCounts, FramebufferParams.AttachmentSamples[i]), - AttachmentLoadOp.Load, - AttachmentStoreOp.Store, - AttachmentLoadOp.Load, - AttachmentStoreOp.Store, - ImageLayout.General, - ImageLayout.General); - } - - int colorAttachmentsCount = FramebufferParams.ColorAttachmentsCount; - - if (colorAttachmentsCount > MaxAttachments - 1) - { - colorAttachmentsCount = MaxAttachments - 1; - } - - if (colorAttachmentsCount != 0) - { - int maxAttachmentIndex = FramebufferParams.MaxColorAttachmentIndex; - subpass.ColorAttachmentCount = (uint)maxAttachmentIndex + 1; - subpass.PColorAttachments = &attachmentReferences[0]; - - // Fill with VK_ATTACHMENT_UNUSED to cover any gaps. - for (int i = 0; i <= maxAttachmentIndex; i++) - { - subpass.PColorAttachments[i] = new AttachmentReference(Vk.AttachmentUnused, ImageLayout.Undefined); - } - - for (int i = 0; i < colorAttachmentsCount; i++) - { - int bindIndex = FramebufferParams.AttachmentIndices[i]; - - subpass.PColorAttachments[bindIndex] = new AttachmentReference((uint)i, ImageLayout.General); - } - } + EndRenderPass(); - if (FramebufferParams.HasDepthStencil) - { - uint dsIndex = (uint)FramebufferParams.AttachmentsCount - 1; + if (!hasFramebuffer || FramebufferParams.AttachmentsCount == 0) + { + // Use the null framebuffer. + _nullRenderPass ??= new RenderPassHolder(Gd, Device, new RenderPassCacheKey(), FramebufferParams); - subpass.PDepthStencilAttachment = &attachmentReferences[MaxAttachments - 1]; - *subpass.PDepthStencilAttachment = new AttachmentReference(dsIndex, ImageLayout.General); - } + _renderPass = _nullRenderPass.GetRenderPass(); + _framebuffer = _nullRenderPass.GetFramebuffer(Gd, Cbs, FramebufferParams); } - - var subpassDependency = PipelineConverter.CreateSubpassDependency(); - - fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs) + else { - var renderPassCreateInfo = new RenderPassCreateInfo - { - SType = StructureType.RenderPassCreateInfo, - PAttachments = pAttachmentDescs, - AttachmentCount = attachmentDescs != null ? (uint)attachmentDescs.Length : 0, - PSubpasses = &subpass, - SubpassCount = 1, - PDependencies = &subpassDependency, - DependencyCount = 1, - }; - - Gd.Api.CreateRenderPass(Device, renderPassCreateInfo, null, out var renderPass).ThrowOnError(); - - _renderPass?.Dispose(); - _renderPass = new Auto<DisposableRenderPass>(new DisposableRenderPass(Gd.Api, Device, renderPass)); + (_renderPass, _framebuffer) = FramebufferParams.GetPassAndFramebuffer(Gd, Device, Cbs); } - - EndRenderPass(); - - _framebuffer?.Dispose(); - _framebuffer = hasFramebuffer ? FramebufferParams.Create(Gd.Api, Cbs, _renderPass) : null; } protected void SignalStateChange() @@ -1770,8 +1695,7 @@ namespace Ryujinx.Graphics.Vulkan { if (disposing) { - _renderPass?.Dispose(); - _framebuffer?.Dispose(); + _nullRenderPass?.Dispose(); _newState.Dispose(); _descriptorSetUpdater.Dispose(); _vertexBufferUpdater.Dispose(); |