public SubpassDescription
 (
     SubpassDescriptionFlags flags                = default,
     PipelineBindPoint pipelineBindPoint          = default,
     uint inputAttachmentCount                    = default,
     AttachmentReference *pInputAttachments       = default,
     uint colorAttachmentCount                    = default,
     AttachmentReference *pColorAttachments       = default,
     AttachmentReference *pResolveAttachments     = default,
     AttachmentReference *pDepthStencilAttachment = default,
     uint preserveAttachmentCount                 = default,
     uint *pPreserveAttachments                   = default
 )
 {
     Flags                   = flags;
     PipelineBindPoint       = pipelineBindPoint;
     InputAttachmentCount    = inputAttachmentCount;
     PInputAttachments       = pInputAttachments;
     ColorAttachmentCount    = colorAttachmentCount;
     PColorAttachments       = pColorAttachments;
     PResolveAttachments     = pResolveAttachments;
     PDepthStencilAttachment = pDepthStencilAttachment;
     PreserveAttachmentCount = preserveAttachmentCount;
     PPreserveAttachments    = pPreserveAttachments;
 }
Example #2
0
        public SubpassDescription
        (
            SubpassDescriptionFlags?flags                = null,
            PipelineBindPoint?pipelineBindPoint          = null,
            uint?inputAttachmentCount                    = null,
            AttachmentReference *pInputAttachments       = null,
            uint?colorAttachmentCount                    = null,
            AttachmentReference *pColorAttachments       = null,
            AttachmentReference *pResolveAttachments     = null,
            AttachmentReference *pDepthStencilAttachment = null,
            uint?preserveAttachmentCount                 = null,
            uint *pPreserveAttachments                   = null
        ) : this()
        {
            if (flags is not null)
            {
                Flags = flags.Value;
            }

            if (pipelineBindPoint is not null)
            {
                PipelineBindPoint = pipelineBindPoint.Value;
            }

            if (inputAttachmentCount is not null)
            {
                InputAttachmentCount = inputAttachmentCount.Value;
            }

            if (pInputAttachments is not null)
            {
                PInputAttachments = pInputAttachments;
            }

            if (colorAttachmentCount is not null)
            {
                ColorAttachmentCount = colorAttachmentCount.Value;
            }

            if (pColorAttachments is not null)
            {
                PColorAttachments = pColorAttachments;
            }

            if (pResolveAttachments is not null)
            {
                PResolveAttachments = pResolveAttachments;
            }

            if (pDepthStencilAttachment is not null)
            {
                PDepthStencilAttachment = pDepthStencilAttachment;
            }

            if (preserveAttachmentCount is not null)
            {
                PreserveAttachmentCount = preserveAttachmentCount.Value;
            }

            if (pPreserveAttachments is not null)
            {
                PPreserveAttachments = pPreserveAttachments;
            }
        }
Example #3
0
        public static unsafe DisposableRenderPass ToRenderPass(this ProgramPipelineState state, VulkanRenderer gd, Device device)
        {
            const int MaxAttachments = Constants.MaxRenderTargets + 1;

            AttachmentDescription[] attachmentDescs = null;

            var subpass = new SubpassDescription()
            {
                PipelineBindPoint = PipelineBindPoint.Graphics
            };

            AttachmentReference *attachmentReferences = stackalloc AttachmentReference[MaxAttachments];

            Span <int> attachmentIndices = stackalloc int[MaxAttachments];
            Span <Silk.NET.Vulkan.Format> attachmentFormats = stackalloc Silk.NET.Vulkan.Format[MaxAttachments];

            int attachmentCount         = 0;
            int colorCount              = 0;
            int maxColorAttachmentIndex = 0;

            for (int i = 0; i < state.AttachmentEnable.Length; i++)
            {
                if (state.AttachmentEnable[i])
                {
                    maxColorAttachmentIndex = i;

                    attachmentFormats[attachmentCount] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i]);

                    attachmentIndices[attachmentCount++] = i;
                    colorCount++;
                }
            }

            if (state.DepthStencilEnable)
            {
                attachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.DepthStencilFormat);
            }

            if (attachmentCount != 0)
            {
                attachmentDescs = new AttachmentDescription[attachmentCount];

                for (int i = 0; i < attachmentCount; i++)
                {
                    int bindIndex = attachmentIndices[i];

                    attachmentDescs[i] = new AttachmentDescription(
                        0,
                        attachmentFormats[i],
                        TextureStorage.ConvertToSampleCountFlags((uint)state.SamplesCount),
                        AttachmentLoadOp.Load,
                        AttachmentStoreOp.Store,
                        AttachmentLoadOp.Load,
                        AttachmentStoreOp.Store,
                        ImageLayout.General,
                        ImageLayout.General);
                }

                int colorAttachmentsCount = colorCount;

                if (colorAttachmentsCount > MaxAttachments - 1)
                {
                    colorAttachmentsCount = MaxAttachments - 1;
                }

                if (colorAttachmentsCount != 0)
                {
                    int maxAttachmentIndex = Constants.MaxRenderTargets - 1;
                    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 = attachmentIndices[i];

                        subpass.PColorAttachments[bindIndex] = new AttachmentReference((uint)i, ImageLayout.General);
                    }
                }

                if (state.DepthStencilEnable)
                {
                    uint dsIndex = (uint)attachmentCount - 1;

                    subpass.PDepthStencilAttachment = &attachmentReferences[MaxAttachments - 1];
                    *subpass.PDepthStencilAttachment = new AttachmentReference(dsIndex, ImageLayout.General);
                }
            }

            var subpassDependency = new SubpassDependency(
                0,
                0,
                PipelineStageFlags.PipelineStageAllGraphicsBit,
                PipelineStageFlags.PipelineStageAllGraphicsBit,
                AccessFlags.AccessMemoryReadBit | AccessFlags.AccessMemoryWriteBit,
                AccessFlags.AccessMemoryReadBit | AccessFlags.AccessMemoryWriteBit,
                0);

            fixed(AttachmentDescription *pAttachmentDescs = attachmentDescs)
            {
                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();

                return(new DisposableRenderPass(gd.Api, device, renderPass));
            }
        }