Example #1
0
        private unsafe void CreateRenderPass(PipelineStateDescription pipelineStateDescription)
        {
            bool hasDepthStencilAttachment = pipelineStateDescription.Output.DepthStencilFormat != PixelFormat.None;

            var renderTargetCount = pipelineStateDescription.Output.RenderTargetCount;

            var attachmentCount = renderTargetCount;

            if (hasDepthStencilAttachment)
            {
                attachmentCount++;
            }

            var attachments = new AttachmentDescription[attachmentCount];
            var colorAttachmentReferences = new AttachmentReference[renderTargetCount];

            fixed(PixelFormat *renderTargetFormat = &pipelineStateDescription.Output.RenderTargetFormat0)
            fixed(BlendStateRenderTargetDescription * blendDescription = &pipelineStateDescription.BlendState.RenderTarget0)
            {
                for (int i = 0; i < renderTargetCount; i++)
                {
                    var currentBlendDesc = pipelineStateDescription.BlendState.IndependentBlendEnable ? (blendDescription + i) : blendDescription;

                    attachments[i] = new AttachmentDescription
                    {
                        Format                = VulkanConvertExtensions.ConvertPixelFormat(*(renderTargetFormat + i)),
                        Samples               = SampleCountFlags.Sample1,
                        LoadOperation         = currentBlendDesc->BlendEnable ? AttachmentLoadOperation.Load : AttachmentLoadOperation.DontCare, // TODO VULKAN: Only if any destination blend?
                        StoreOperation        = AttachmentStoreOperation.Store,
                        StencilLoadOperation  = AttachmentLoadOperation.DontCare,
                        StencilStoreOperation = AttachmentStoreOperation.DontCare,
                        InitialLayout         = ImageLayout.ColorAttachmentOptimal,
                        FinalLayout           = ImageLayout.ColorAttachmentOptimal,
                    };

                    colorAttachmentReferences[i] = new AttachmentReference
                    {
                        Attachment = (uint)i,
                        Layout     = ImageLayout.ColorAttachmentOptimal,
                    };
                }
            }

            if (hasDepthStencilAttachment)
            {
                attachments[attachmentCount - 1] = new AttachmentDescription
                {
                    Format                = Texture.GetFallbackDepthStencilFormat(GraphicsDevice, VulkanConvertExtensions.ConvertPixelFormat(pipelineStateDescription.Output.DepthStencilFormat)),
                    Samples               = SampleCountFlags.Sample1,
                    LoadOperation         = AttachmentLoadOperation.Load,     // TODO VULKAN: Only if depth read enabled?
                    StoreOperation        = AttachmentStoreOperation.Store,   // TODO VULKAN: Only if depth write enabled?
                    StencilLoadOperation  = AttachmentLoadOperation.DontCare, // TODO VULKAN: Handle stencil
                    StencilStoreOperation = AttachmentStoreOperation.DontCare,
                    InitialLayout         = ImageLayout.DepthStencilAttachmentOptimal,
                    FinalLayout           = ImageLayout.DepthStencilAttachmentOptimal,
                };
            }

            var depthAttachmentReference = new AttachmentReference
            {
                Attachment = (uint)attachments.Length - 1,
                Layout     = ImageLayout.DepthStencilAttachmentOptimal,
            };

            var subpass = new SubpassDescription
            {
                PipelineBindPoint      = PipelineBindPoint.Graphics,
                ColorAttachmentCount   = (uint)renderTargetCount,
                ColorAttachments       = colorAttachmentReferences.Length > 0 ? new IntPtr(Interop.Fixed(colorAttachmentReferences)) : IntPtr.Zero,
                DepthStencilAttachment = hasDepthStencilAttachment ? new IntPtr(&depthAttachmentReference) : IntPtr.Zero,
            };

            var renderPassCreateInfo = new RenderPassCreateInfo
            {
                StructureType   = StructureType.RenderPassCreateInfo,
                AttachmentCount = (uint)attachmentCount,
                Attachments     = attachments.Length > 0 ? new IntPtr(Interop.Fixed(attachments)) : IntPtr.Zero,
                SubpassCount    = 1,
                Subpasses       = new IntPtr(&subpass)
            };

            NativeRenderPass = GraphicsDevice.NativeDevice.CreateRenderPass(ref renderPassCreateInfo);
        }