| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- using Ryujinx.Graphics.GAL;
- using Silk.NET.Vulkan;
- using System;
- using System.Linq;
- using VkFormat = Silk.NET.Vulkan.Format;
- namespace Ryujinx.Graphics.Vulkan
- {
- class FramebufferParams
- {
- private readonly Device _device;
- private readonly Auto<DisposableImageView>[] _attachments;
- private readonly TextureView[] _colors;
- private readonly TextureView _depthStencil;
- private uint _validColorAttachments;
- public uint Width { get; }
- public uint Height { get; }
- public uint Layers { get; }
- public uint[] AttachmentSamples { get; }
- public VkFormat[] AttachmentFormats { get; }
- public int[] AttachmentIndices { get; }
- public int AttachmentsCount { get; }
- public int MaxColorAttachmentIndex { get; }
- public bool HasDepthStencil { get; }
- public int ColorAttachmentsCount => AttachmentsCount - (HasDepthStencil ? 1 : 0);
- public FramebufferParams(
- Device device,
- Auto<DisposableImageView> view,
- uint width,
- uint height,
- bool isDepthStencil,
- VkFormat format)
- {
- _device = device;
- _attachments = new[] { view };
- _validColorAttachments = 1u;
- Width = width;
- Height = height;
- Layers = 1;
- AttachmentSamples = new[] { 1u };
- AttachmentFormats = new[] { format };
- AttachmentIndices = new[] { 0 };
- AttachmentsCount = 1;
- HasDepthStencil = isDepthStencil;
- }
- public FramebufferParams(Device device, ITexture[] colors, ITexture depthStencil)
- {
- _device = device;
- int colorsCount = colors.Count(IsValidTextureView);
- int count = colorsCount + (IsValidTextureView(depthStencil) ? 1 : 0);
- _attachments = new Auto<DisposableImageView>[count];
- _colors = new TextureView[colorsCount];
- AttachmentSamples = new uint[count];
- AttachmentFormats = new VkFormat[count];
- AttachmentIndices = new int[count];
- MaxColorAttachmentIndex = colors.Length - 1;
- uint width = uint.MaxValue;
- uint height = uint.MaxValue;
- uint layers = uint.MaxValue;
- int index = 0;
- int bindIndex = 0;
- foreach (ITexture color in colors)
- {
- if (IsValidTextureView(color))
- {
- var texture = (TextureView)color;
- _attachments[index] = texture.GetImageViewForAttachment();
- _colors[index] = texture;
- _validColorAttachments |= 1u << bindIndex;
- AttachmentSamples[index] = (uint)texture.Info.Samples;
- AttachmentFormats[index] = texture.VkFormat;
- AttachmentIndices[index] = bindIndex;
- width = Math.Min(width, (uint)texture.Width);
- height = Math.Min(height, (uint)texture.Height);
- layers = Math.Min(layers, (uint)texture.Layers);
- if (++index >= colorsCount)
- {
- break;
- }
- }
- bindIndex++;
- }
- if (depthStencil is TextureView dsTexture && dsTexture.Valid)
- {
- _attachments[count - 1] = dsTexture.GetImageViewForAttachment();
- _depthStencil = dsTexture;
- AttachmentSamples[count - 1] = (uint)dsTexture.Info.Samples;
- AttachmentFormats[count - 1] = dsTexture.VkFormat;
- width = Math.Min(width, (uint)dsTexture.Width);
- height = Math.Min(height, (uint)dsTexture.Height);
- layers = Math.Min(layers, (uint)dsTexture.Layers);
- HasDepthStencil = true;
- }
- if (count == 0)
- {
- width = height = layers = 1;
- }
- Width = width;
- Height = height;
- Layers = layers;
- AttachmentsCount = count;
- }
- public Auto<DisposableImageView> GetAttachment(int index)
- {
- if ((uint)index >= _attachments.Length)
- {
- return null;
- }
- return _attachments[index];
- }
- public bool IsValidColorAttachment(int bindIndex)
- {
- return (uint)bindIndex < Constants.MaxRenderTargets && (_validColorAttachments & (1u << bindIndex)) != 0;
- }
- private static bool IsValidTextureView(ITexture texture)
- {
- return texture is TextureView view && view.Valid;
- }
- public ClearRect GetClearRect(Rectangle<int> scissor, int layer, int layerCount)
- {
- int x = scissor.X;
- int y = scissor.Y;
- int width = Math.Min((int)Width - scissor.X, scissor.Width);
- int height = Math.Min((int)Height - scissor.Y, scissor.Height);
- return new ClearRect(new Rect2D(new Offset2D(x, y), new Extent2D((uint)width, (uint)height)), (uint)layer, (uint)layerCount);
- }
- public unsafe Auto<DisposableFramebuffer> Create(Vk api, CommandBufferScoped cbs, Auto<DisposableRenderPass> renderPass)
- {
- ImageView* attachments = stackalloc ImageView[_attachments.Length];
- for (int i = 0; i < _attachments.Length; i++)
- {
- attachments[i] = _attachments[i].Get(cbs).Value;
- }
- var framebufferCreateInfo = new FramebufferCreateInfo()
- {
- SType = StructureType.FramebufferCreateInfo,
- RenderPass = renderPass.Get(cbs).Value,
- AttachmentCount = (uint)_attachments.Length,
- PAttachments = attachments,
- Width = Width,
- Height = Height,
- Layers = Layers
- };
- api.CreateFramebuffer(_device, framebufferCreateInfo, null, out var framebuffer).ThrowOnError();
- return new Auto<DisposableFramebuffer>(new DisposableFramebuffer(api, _device, framebuffer), null, _attachments);
- }
- public void UpdateModifications()
- {
- if (_colors != null)
- {
- for (int index = 0; index < _colors.Length; index++)
- {
- _colors[index].Storage.SetModification(
- AccessFlags.AccessColorAttachmentWriteBit,
- PipelineStageFlags.PipelineStageColorAttachmentOutputBit);
- }
- }
- _depthStencil?.Storage.SetModification(
- AccessFlags.AccessDepthStencilAttachmentWriteBit,
- PipelineStageFlags.PipelineStageColorAttachmentOutputBit);
- }
- }
- }
|