private void CreateDefaultSwapchainRenderPass(Device SelectedLogicalGraphicsDevice)
        {
            var anAttachmentDescription = new AttachmentDescription
            {
                Format         = VulkanRenderer.Surface.SelectedSurfaceFormat.Format,
                Samples        = SampleCountFlags.Count1,
                LoadOp         = AttachmentLoadOp.Clear,
                StoreOp        = AttachmentStoreOp.Store,
                StencilLoadOp  = AttachmentLoadOp.DontCare,
                StencilStoreOp = AttachmentStoreOp.DontCare,
                InitialLayout  = ImageLayout.Undefined,
                FinalLayout    = ImageLayout.PresentSrcKHR
            };
            var anAttachmentReference = new AttachmentReference {
                Layout = ImageLayout.ColorAttachmentOptimal
            };



            var aSubpassDescription = new SubpassDescription
            {
                PipelineBindPoint = PipelineBindPoint.Graphics,
                ColorAttachments  = new AttachmentReference[] { anAttachmentReference }
            };

            var aRenderPassCreateInfo = new RenderPassCreateInfo
            {
                Attachments = new AttachmentDescription[] { anAttachmentDescription },
                Subpasses   = new SubpassDescription[] { aSubpassDescription }
            };

            myBaseRenderPass = SelectedLogicalGraphicsDevice.CreateRenderPass(aRenderPassCreateInfo);
        }
Example #2
0
        private RenderPass CreateRenderPass(SurfaceFormatKhr surfaceFormat)
        {
            var attDesc = new AttachmentDescription
            {
                Format         = surfaceFormat.Format,
                Samples        = SampleCountFlags.Count1,
                LoadOp         = AttachmentLoadOp.Clear,
                StoreOp        = AttachmentStoreOp.Store,
                StencilLoadOp  = AttachmentLoadOp.DontCare,
                StencilStoreOp = AttachmentStoreOp.DontCare,
                InitialLayout  = ImageLayout.ColorAttachmentOptimal,
                FinalLayout    = ImageLayout.ColorAttachmentOptimal
            };
            var attRef = new AttachmentReference {
                Layout = ImageLayout.ColorAttachmentOptimal
            };
            var subpassDesc = new SubpassDescription
            {
                PipelineBindPoint = PipelineBindPoint.Graphics,
                ColorAttachments  = new [] { attRef }
            };
            var renderPassCreateInfo = new RenderPassCreateInfo
            {
                Attachments = new [] { attDesc },
                Subpasses   = new [] { subpassDesc }
            };

            return(_device.CreateRenderPass(renderPassCreateInfo));
        }
        public RenderPass(FrameBuffer myFrameBuffer, SubPass[] mySubpasses = null)
        {
            List <AttachmentDescription> GBufferSupportedTypes     = new List <AttachmentDescription>();
            List <AttachmentReference>   attachmentColorReferences = new List <AttachmentReference>();
            AttachmentReference          myDepthBuffer;
            SubpassDescription           GeometryBufferSubpassDescription = new SubpassDescription()
            {
                PipelineBindPoint = PipelineBindPoint.Graphics
            };

            foreach (var Attachment in myFrameBuffer.GetAttachments())
            {
                GBufferSupportedTypes.Add(Attachment.AttachmentDescription);
                if (Attachment.AttachmentReference.Layout != ImageLayout.DepthStencilAttachmentOptimal)
                {
                    attachmentColorReferences.Add(Attachment.AttachmentReference);
                }
                else
                {
                    GeometryBufferSubpassDescription.DepthStencilAttachment = Attachment.AttachmentReference;
                }
            }
            GeometryBufferSubpassDescription.ColorAttachments = attachmentColorReferences.ToArray();


            //Above is for the Geometry Buffer to intialize.
            uint starting = 1;
            uint ending   = 2;
            List <SubpassDependency>  myIncomingDependencies = new List <SubpassDependency>();
            List <SubpassDescription> mySubpassDescriptions  = new List <SubpassDescription>();

            if (mySubpasses != null)
            {
                for (int i = 0; i < mySubpasses.Length; i++)
                {
                    myIncomingDependencies.AddRange(mySubpasses[i].GetSubpassDependencies());
                    mySubpassDescriptions.Add(mySubpasses[i].GetSubpassDescription());
                }
                ;
            }

            var aRenderPassCreateInfo = new RenderPassCreateInfo
            {
                Attachments  = GBufferSupportedTypes.ToArray(),
                Subpasses    = mySubpassDescriptions.ToArray(),
                Dependencies = myIncomingDependencies.ToArray()
            };

            myFrameBuffer.SetRenderPass(this);
            CreateRenderPass(aRenderPassCreateInfo);
        }
Example #4
0
        void CreateRenderPass()
        {
            var attachment_descriptions = new AttachmentDescription
            {
                flags                 = (AttachmentDescriptionFlagBits)0,                  // VkAttachmentDescriptionFlagBits   flags
                format                = GetSwapChain.Format,                               // VkFormat                       format
                samples               = SampleCountFlagBits._1Bit,                         // VkSampleCountFlagBits          samples
                loadOperation         = AttachmentLoadOperation.Clear,                     // VkAttachmentLoadOp             loadOp
                storeOperation        = AttachmentStoreOperation.Store,                    // VkAttachmentStoreOp            storeOp
                stencilLoadOperation  = AttachmentLoadOperation.DontCare,                  // VkAttachmentLoadOp             stencilLoadOp
                stencilStoreOperation = AttachmentStoreOperation.DontCare,                 // VkAttachmentStoreOp            stencilStoreOp
                initialLayout         = ImageLayout.Undefined,                             // VkImageLayout                  initialLayout;
                finalLayout           = ImageLayout.PresentSourceKhr                       // VkImageLayout                  finalLayout
            };

            var color_attachment_references = new AttachmentReference
            {
                attachment = 0,                                                            // uint32_t                       attachment
                layout     = ImageLayout.ColorAttachmentOptimal                            // VkImageLayout                  layout
            };

            var subpass_descriptions = new SubpassDescription
            {
                flags                   = 0,                                       // VkSubpassDescriptionFlagBits      flags
                pipelineBindPoint       = PipelineBindPoint.Graphics,              // VkPipelineBindPoint            pipelineBindPoint
                inputAttachmentCount    = 0,                                       // uint32_t                       inputAttachmentCount
                pInputAttachments       = (AttachmentReference *)0,                // const VkAttachmentReference   *pInputAttachments
                colorAttachmentCount    = 1,                                       // uint32_t                       colorAttachmentCount
                pColorAttachments       = &color_attachment_references,            // const VkAttachmentReference   *pColorAttachments
                pResolveAttachments     = (AttachmentReference *)0,                // const VkAttachmentReference   *pResolveAttachments
                pDepthStencilAttachment = (AttachmentReference *)0,                // const VkAttachmentReference   *pDepthStencilAttachment
                preserveAttachmentCount = 0,                                       // uint32_t                       preserveAttachmentCount
                pPreserveAttachments    = (uint *)0                                // const uint32_t*                pPreserveAttachments
            };

            var render_pass_create_info = new RenderPassCreateInfo
            {
                sType           = StructureType.RenderPassCreateInfo,       // VkStructureType                sType
                pNext           = IntPtr.Zero,                              // const void                    *pNext
                flags           = 0,                                        // VkRenderPassCreateFlagBits        flags
                attachmentCount = 1,                                        // uint32_t                       attachmentCount
                pAttachments    = &attachment_descriptions,                 // const VkAttachmentDescription *pAttachments
                subpassCount    = 1,                                        // uint32_t                       subpassCount
                pSubpasses      = &subpass_descriptions,                    // const VkSubpassDescription    *pSubpasses
                dependencyCount = 0,                                        // uint32_t                       dependencyCount
                pDependencies   = (SubpassDependency *)0                    // const VkSubpassDependency     *pDependencies
            };

            vk.CreateRenderPass(GetDevice, ref render_pass_create_info, (AllocationCallbacks *)0, out Vulkan.RenderPass).CheckError();
        }
        private void CreateRenderPass()
        {
            var colorAttachment = new AttachmentDescription()
            {
                Format         = vkSwapChainImageFormat,
                Samples        = SampleCountFlags.Count1,
                LoadOp         = AttachmentLoadOp.Clear,
                StoreOp        = AttachmentStoreOp.Store,
                StencilLoadOp  = AttachmentLoadOp.DontCare,
                StencilStoreOp = AttachmentStoreOp.DontCare,
                InitialLayout  = ImageLayout.Undefined,
                FinalLayout    = ImageLayout.PresentSrcKhr,
            };

            var colorAttachmentRef = new AttachmentReference()
            {
                Attachment = 0,
                Layout     = Vulkan.ImageLayout.ColorAttachmentOptimal,
            };

            var subpass = new SubpassDescription()
            {
                PipelineBindPoint    = PipelineBindPoint.Graphics,
                ColorAttachmentCount = 1,
                ColorAttachments     = new AttachmentReference[] { colorAttachmentRef },
            };

            var dependency = new SubpassDependency()
            {
                SrcSubpass    = VK_SUBPASS_EXTERNAL,
                SrcStageMask  = PipelineStageFlags.ColorAttachmentOutput,
                SrcAccessMask = 0,

                DstSubpass    = 0,
                DstStageMask  = PipelineStageFlags.ColorAttachmentOutput,
                DstAccessMask = AccessFlags.ColorAttachmentRead | AccessFlags.ColorAttachmentWrite,
            };

            var renderPassInfo = new RenderPassCreateInfo()
            {
                AttachmentCount = 1,
                Attachments     = new AttachmentDescription[] { colorAttachment },
                SubpassCount    = 1,
                Subpasses       = new SubpassDescription[] { subpass },
                DependencyCount = 1,
                Dependencies    = new SubpassDependency[] { dependency },
            };

            vkRenderPass = vkDevice.CreateRenderPass(renderPassInfo);
        }
Example #6
0
        protected void CreateRenderPass()
        {
            var colorAttachment = new AttachmentDescription
            {
                Format         = format.Format,
                Samples        = SampleCountFlags.Count1,
                LoadOp         = AttachmentLoadOp.Clear,
                StoreOp        = AttachmentStoreOp.Store,
                StencilLoadOp  = AttachmentLoadOp.DontCare,
                StencilStoreOp = AttachmentStoreOp.DontCare,
                InitialLayout  = ImageLayout.Undefined,
                FinalLayout    = ImageLayout.PresentSrcKhr
            };

            var colorAttachmentRef = new AttachmentReference
            {
                Attachment = 0,
                Layout     = ImageLayout.ColorAttachmentOptimal
            };

            var subpass = new SubpassDescription
            {
                PipelineBindPoint    = PipelineBindPoint.Graphics,
                ColorAttachmentCount = 1,
                ColorAttachments     = new AttachmentReference[] { colorAttachmentRef },
            };

            var dependency = new SubpassDependency
            {
                SrcSubpass    = VK_SUBPASS_INTERNAL,
                DstSubpass    = 0,
                SrcStageMask  = PipelineStageFlags.ColorAttachmentOutput,
                SrcAccessMask = 0,
                DstStageMask  = PipelineStageFlags.ColorAttachmentOutput,
                DstAccessMask = AccessFlags.ColorAttachmentRead | AccessFlags.ColorAttachmentWrite
            };

            var renderPassInfo = new RenderPassCreateInfo
            {
                AttachmentCount = 1,
                Attachments     = new AttachmentDescription[] { colorAttachment },
                SubpassCount    = 1,
                Subpasses       = new SubpassDescription[] { subpass },
                DependencyCount = 1,
                Dependencies    = new SubpassDependency[] { dependency }
            };

            renderPass = device.CreateRenderPass(renderPassInfo);
        }
Example #7
0
        private void CreateRenderPass()
        {
            var colorAttachmentReference = new AttachmentReference {
                Attachment = 0, Layout = ImageLayout.ColorAttachmentOptimal
            };
            var depthStencilAttachmentReference = new AttachmentReference {
                Attachment = 1, Layout = ImageLayout.DepthStencilAttachmentOptimal
            };

            var subpass = new SubpassDescription
            {
                PipelineBindPoint    = PipelineBindPoint.Graphics,
                ColorAttachmentCount = 1,
                ColorAttachments     = new IntPtr(&colorAttachmentReference),
            };

            var attachments = new[]
            {
                new AttachmentDescription
                {
                    Format                = backBufferFormat,
                    Samples               = SampleCountFlags.Sample1,
                    LoadOperation         = AttachmentLoadOperation.Load,
                    StoreOperation        = AttachmentStoreOperation.Store,
                    StencilLoadOperation  = AttachmentLoadOperation.DontCare,
                    StencilStoreOperation = AttachmentStoreOperation.DontCare,
                    InitialLayout         = ImageLayout.ColorAttachmentOptimal,
                    FinalLayout           = ImageLayout.ColorAttachmentOptimal
                },
            };

            fixed(AttachmentDescription *attachmentsPointer = &attachments[0])
            {
                var createInfo = new RenderPassCreateInfo
                {
                    StructureType   = StructureType.RenderPassCreateInfo,
                    AttachmentCount = (uint)attachments.Length,
                    Attachments     = new IntPtr(attachmentsPointer),
                    SubpassCount    = 1,
                    Subpasses       = new IntPtr(&subpass)
                };

                renderPass = device.CreateRenderPass(ref createInfo);
            }
        }
Example #8
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));
            }
        }
        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);
        }
Example #10
0
        private void CreateRenderPass()
        {
            var colorAttachmentReference = new AttachmentReference { Attachment = 0, Layout = ImageLayout.ColorAttachmentOptimal };
            var depthStencilAttachmentReference = new AttachmentReference { Attachment = 1, Layout = ImageLayout.DepthStencilAttachmentOptimal };

            var subpass = new SubpassDescription
            {
                PipelineBindPoint = PipelineBindPoint.Graphics,
                ColorAttachmentCount = 1,
                ColorAttachments = new IntPtr(&colorAttachmentReference),
            };

            var attachments = new[]
            {
                new AttachmentDescription
                {
                    Format = backBufferFormat,
                    Samples = SampleCountFlags.Sample1,
                    LoadOperation = AttachmentLoadOperation.Load,
                    StoreOperation = AttachmentStoreOperation.Store,
                    StencilLoadOperation = AttachmentLoadOperation.DontCare,
                    StencilStoreOperation = AttachmentStoreOperation.DontCare,
                    InitialLayout = ImageLayout.ColorAttachmentOptimal,
                    FinalLayout = ImageLayout.ColorAttachmentOptimal
                },
            };

            fixed (AttachmentDescription* attachmentsPointer = &attachments[0])
            {
                var createInfo = new RenderPassCreateInfo
                {
                    StructureType = StructureType.RenderPassCreateInfo,
                    AttachmentCount = (uint)attachments.Length,
                    Attachments = new IntPtr(attachmentsPointer),
                    SubpassCount = 1,
                    Subpasses = new IntPtr(&subpass)
                };

                renderPass = device.CreateRenderPass(ref createInfo);
            }
        }
Example #11
0
        public static unsafe RenderPassCreateInfo RenderPassCreateInfo(Span <AttachmentDescription> attachments, SubpassDependency dependency, SubpassDescription subpass)
        {
            RenderPassCreateInfo renderPassCreateInfo = new()
            {
                SType = StructureType.RenderPassCreateInfo,

                AttachmentCount = (uint)attachments.Length,

                DependencyCount = 1,
                PDependencies   = &dependency,
                SubpassCount    = 1,
                PSubpasses      = &subpass
            };

            fixed(AttachmentDescription *ptr = &attachments[0])
            {
                renderPassCreateInfo.PAttachments = ptr;
            }

            return(renderPassCreateInfo);
        }
Example #12
0
        public void CreateGraphicsPipeline()
        {
            var attachment = new AttachmentDescription
            {
                Samples        = SampleCounts.Count1,
                Format         = Format.B8G8R8A8UNorm,
                InitialLayout  = ImageLayout.Undefined,
                FinalLayout    = ImageLayout.PresentSrcKhr,
                LoadOp         = AttachmentLoadOp.Clear,
                StoreOp        = AttachmentStoreOp.Store,
                StencilLoadOp  = AttachmentLoadOp.DontCare,
                StencilStoreOp = AttachmentStoreOp.DontCare
            };
            var subpass    = new SubpassDescription(new[] { new AttachmentReference(0, ImageLayout.ColorAttachmentOptimal) });
            var createInfo = new RenderPassCreateInfo(new[] { subpass }, new[] { attachment });

            using (PipelineCache cache = Device.CreatePipelineCache())
                using (RenderPass renderPass = Device.CreateRenderPass(createInfo))
                    using (PipelineLayout layout = Device.CreatePipelineLayout())
                        using (ShaderModule vertexShader = Device.CreateShaderModule(new ShaderModuleCreateInfo(ReadAllBytes("Shader.vert.spv"))))
                            using (ShaderModule fragmentShader = Device.CreateShaderModule(new ShaderModuleCreateInfo(ReadAllBytes("Shader.frag.spv"))))
                            {
                                var shaderStageCreateInfos = new[]
                                {
                                    new PipelineShaderStageCreateInfo(ShaderStages.Vertex, vertexShader, "main"),
                                    new PipelineShaderStageCreateInfo(ShaderStages.Fragment, fragmentShader, "main")
                                };
                                var vertexInputStateCreateInfo   = new PipelineVertexInputStateCreateInfo();
                                var inputAssemblyStateCreateInfo = new PipelineInputAssemblyStateCreateInfo(PrimitiveTopology.TriangleList);
                                var viewportStateCreateInfo      = new PipelineViewportStateCreateInfo(
                                    new Viewport(0, 0, 32, 32),
                                    new Rect2D(0, 0, 32, 32));
                                var rasterizationStateCreateInfo = new PipelineRasterizationStateCreateInfo
                                {
                                    PolygonMode = PolygonMode.Fill,
                                    CullMode    = CullModes.Back,
                                    FrontFace   = FrontFace.CounterClockwise,
                                    LineWidth   = 1.0f
                                };
                                var tessellationStateCreateInfo = new PipelineTessellationStateCreateInfo(4);
                                var multisampleStateCreateInfo  = new PipelineMultisampleStateCreateInfo
                                {
                                    RasterizationSamples = SampleCounts.Count1,
                                    MinSampleShading     = 1.0f
                                };
                                var colorBlendAttachmentState = new PipelineColorBlendAttachmentState
                                {
                                    SrcColorBlendFactor = BlendFactor.One,
                                    DstColorBlendFactor = BlendFactor.Zero,
                                    ColorBlendOp        = BlendOp.Add,
                                    SrcAlphaBlendFactor = BlendFactor.One,
                                    DstAlphaBlendFactor = BlendFactor.Zero,
                                    AlphaBlendOp        = BlendOp.Add,
                                    ColorWriteMask      = ColorComponents.All
                                };
                                var depthStencilStateCreateInfo = new PipelineDepthStencilStateCreateInfo();
                                var colorBlendStateCreateInfo   = new PipelineColorBlendStateCreateInfo(
                                    new[] { colorBlendAttachmentState });
                                var dynamicStateCreateInfo = new PipelineDynamicStateCreateInfo(DynamicState.LineWidth);

                                var pipelineCreateInfo = new GraphicsPipelineCreateInfo(
                                    layout, renderPass, 0,
                                    shaderStageCreateInfos,
                                    inputAssemblyStateCreateInfo,
                                    vertexInputStateCreateInfo,
                                    rasterizationStateCreateInfo,
                                    tessellationStateCreateInfo,
                                    viewportStateCreateInfo,
                                    multisampleStateCreateInfo,
                                    depthStencilStateCreateInfo,
                                    colorBlendStateCreateInfo,
                                    dynamicStateCreateInfo);
                                using (Device.CreateGraphicsPipelines(new[] { pipelineCreateInfo })[0]) { }
                                using (Device.CreateGraphicsPipelines(new[] { pipelineCreateInfo }, cache)[0]) { }
                                using (Device.CreateGraphicsPipelines(new[] { pipelineCreateInfo }, allocator: CustomAllocator)[0]) { }
                                using (Device.CreateGraphicsPipelines(new[] { pipelineCreateInfo }, cache, CustomAllocator)[0]) { }
                                using (Device.CreateGraphicsPipeline(pipelineCreateInfo)) { }
                                using (Device.CreateGraphicsPipeline(pipelineCreateInfo, allocator: CustomAllocator)) { }
                                using (Device.CreateGraphicsPipeline(pipelineCreateInfo, cache)) { }
                                using (Device.CreateGraphicsPipeline(pipelineCreateInfo, cache, CustomAllocator)) { }
                            }
        }
        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);
        }
Example #14
0
        public bool Create(string vsName, string fsName,
                           VertexInputBindingDescription [] vbind,
                           VertexInputAttributeDescription [] vatts)
        {
            Device dv = mDevices.GetLogicalDevice();

            PipelineShaderStageCreateInfo plssciv = new PipelineShaderStageCreateInfo(
                ShaderStages.Vertex, mShaders[vsName], "main", null);

            PipelineShaderStageCreateInfo plsscif = new PipelineShaderStageCreateInfo(
                ShaderStages.Fragment, mShaders[fsName], "main", null);

            PipelineVertexInputStateCreateInfo plvisci = new PipelineVertexInputStateCreateInfo(
                vbind, vatts);

            PipelineInputAssemblyStateCreateInfo pliasci = new PipelineInputAssemblyStateCreateInfo(
                PrimitiveTopology.TriangleList);

            Viewport vp = new Viewport(0, 0, 1280, 720, 0f, 1f);

            Rect2D scissor = new Rect2D(Offset2D.Zero, mDevices.GetChainExtent());

            PipelineViewportStateCreateInfo plvpsci = new PipelineViewportStateCreateInfo(
                new Viewport[1] {
                vp
            }, new Rect2D[1] {
                scissor
            });

            PipelineRasterizationStateCreateInfo plrsci = new PipelineRasterizationStateCreateInfo();

            plrsci.LineWidth = 1;

            PipelineMultisampleStateCreateInfo plmssci = new PipelineMultisampleStateCreateInfo();

            plmssci.RasterizationSamples = SampleCounts.Count1;

            PipelineColorBlendAttachmentState plcbas = new PipelineColorBlendAttachmentState();

            plcbas.ColorWriteMask = ColorComponents.All;
            plcbas.BlendEnable    = false;

            PipelineColorBlendStateCreateInfo plcbsci = new PipelineColorBlendStateCreateInfo();

            plcbsci.LogicOpEnable = false;
            plcbsci.LogicOp       = LogicOp.Copy;
            plcbsci.Attachments   = new PipelineColorBlendAttachmentState[1] {
                plcbas
            };
            plcbsci.BlendConstants = ColorF4.Zero;

            PipelineLayoutCreateInfo pllci = new PipelineLayoutCreateInfo(
                mDevices.GetDSLs());

            mPipeLayout = dv.CreatePipelineLayout(pllci);

            AttachmentDescription ad = new AttachmentDescription();

            ad.Format         = Format.B8G8R8A8UNorm;
            ad.Samples        = SampleCounts.Count1;
            ad.LoadOp         = AttachmentLoadOp.Clear;
            ad.StoreOp        = AttachmentStoreOp.Store;
            ad.StencilLoadOp  = AttachmentLoadOp.DontCare;
            ad.StencilStoreOp = AttachmentStoreOp.DontCare;
            ad.InitialLayout  = ImageLayout.Undefined;
            ad.FinalLayout    = ImageLayout.PresentSrcKhr;

            AttachmentReference ar = new AttachmentReference(0, ImageLayout.ColorAttachmentOptimal);

            SubpassDescription spd = new SubpassDescription();

            spd.ColorAttachments = new AttachmentReference[1] {
                ar
            };

            SubpassDependency spdc = new SubpassDependency();

            spdc.SrcSubpass    = Constant.SubpassExternal;
            spdc.DstSubpass    = 0;
            spdc.SrcStageMask  = PipelineStages.ColorAttachmentOutput;
            spdc.SrcAccessMask = 0;
            spdc.DstStageMask  = PipelineStages.ColorAttachmentOutput;
            spdc.DstAccessMask = Accesses.ColorAttachmentRead | Accesses.ColorAttachmentWrite;


            RenderPassCreateInfo rpci = new RenderPassCreateInfo(
                new SubpassDescription[1] {
                spd
            },
                new AttachmentDescription[1] {
                ad
            },
                new SubpassDependency[1] {
                spdc
            });

            mRenderPass = dv.CreateRenderPass(rpci);

            GraphicsPipelineCreateInfo gplci = new GraphicsPipelineCreateInfo();

            gplci.Stages = new PipelineShaderStageCreateInfo[2] {
                plssciv, plsscif
            };
            gplci.VertexInputState   = plvisci;
            gplci.InputAssemblyState = pliasci;
            gplci.ViewportState      = plvpsci;
            gplci.RasterizationState = plrsci;
            gplci.MultisampleState   = plmssci;
            gplci.DepthStencilState  = null;
            gplci.ColorBlendState    = plcbsci;
            gplci.DynamicState       = null;
            gplci.Layout             = mPipeLayout;
            gplci.RenderPass         = mRenderPass;
            gplci.Subpass            = 0;
            gplci.BasePipelineHandle = null;
            gplci.BasePipelineIndex  = -1;

            mPipe = dv.CreateGraphicsPipeline(gplci);

            CreateSyncObjects();

            return(true);
        }
Example #15
0
        //[HandleProcessCorruptedStateExceptionsAttribute, SecurityCriticalAttribute]
        private unsafe void Recreate()
        {
            errorDuringCreate = false;

            if (Description.RootSignature == null)
            {
                return;
            }

            PipelineShaderStageCreateInfo[] stages;

            // create render pass
            bool hasDepthStencilAttachment = Description.Output.DepthStencilFormat != PixelFormat.None;

            var renderTargetCount = Description.Output.RenderTargetCount;

            var attachmentCount = renderTargetCount;

            if (hasDepthStencilAttachment)
            {
                attachmentCount++;
            }

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

            fixed(PixelFormat *renderTargetFormat = &Description.Output.RenderTargetFormat0)
            fixed(BlendStateRenderTargetDescription * blendDescription = &Description.BlendState.RenderTarget0)
            {
                for (int i = 0; i < renderTargetCount; i++)
                {
                    var currentBlendDesc = Description.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(Description.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)
            };

            // create pipeline layout
            // Remap descriptor set indices to those in the shader. This ordering generated by the ShaderCompiler
            var resourceGroups = Description.EffectBytecode.Reflection.ResourceBindings.Select(x => x.ResourceGroup ?? "Globals").Distinct().ToList();

            ResourceGroupCount = resourceGroups.Count;

            var layouts = Description.RootSignature.EffectDescriptorSetReflection.Layouts;

            // Get binding indices used by the shader
            var destinationBindings = Description.EffectBytecode.Stages
                                      .SelectMany(x => BinarySerialization.Read <ShaderInputBytecode>(x.Data).ResourceBindings)
                                      .GroupBy(x => x.Key, x => x.Value)
                                      .ToDictionary(x => x.Key, x => x.First());

            var maxBindingIndex    = destinationBindings.Max(x => x.Value);
            var destinationEntries = new DescriptorSetLayoutBuilder.Entry[maxBindingIndex + 1];

            DescriptorBindingMapping = new List <DescriptorSetInfo>();

            for (int i = 0; i < resourceGroups.Count; i++)
            {
                var resourceGroupName = resourceGroups[i] == "Globals" ? Description.RootSignature.EffectDescriptorSetReflection.DefaultSetSlot : resourceGroups[i];
                var layoutIndex       = resourceGroups[i] == null ? 0 : layouts.FindIndex(x => x.Name == resourceGroupName);

                // Check if the resource group is used by the shader
                if (layoutIndex == -1)
                {
                    continue;
                }

                var sourceEntries = layouts[layoutIndex].Layout.Entries;

                for (int sourceBinding = 0; sourceBinding < sourceEntries.Count; sourceBinding++)
                {
                    var sourceEntry = sourceEntries[sourceBinding];

                    int destinationBinding;
                    if (destinationBindings.TryGetValue(sourceEntry.Key.Name, out destinationBinding))
                    {
                        destinationEntries[destinationBinding] = sourceEntry;

                        // No need to umpdate immutable samplers
                        if (sourceEntry.Class == EffectParameterClass.Sampler && sourceEntry.ImmutableSampler != null)
                        {
                            continue;
                        }

                        DescriptorBindingMapping.Add(new DescriptorSetInfo
                        {
                            SourceSet          = layoutIndex,
                            SourceBinding      = sourceBinding,
                            DestinationBinding = destinationBinding,
                            DescriptorType     = VulkanConvertExtensions.ConvertDescriptorType(sourceEntry.Class, sourceEntry.Type)
                        });
                    }
                }
            }

            // Create default sampler, used by texture and buffer loads
            destinationEntries[0] = new DescriptorSetLayoutBuilder.Entry
            {
                Class            = EffectParameterClass.Sampler,
                Type             = EffectParameterType.Sampler,
                ImmutableSampler = GraphicsDevice.SamplerStates.PointWrap,
                ArraySize        = 1,
            };

            // Create descriptor set layout
            NativeDescriptorSetLayout = DescriptorSetLayout.CreateNativeDescriptorSetLayout(GraphicsDevice, destinationEntries, out DescriptorTypeCounts);

            // Create pipeline layout
            var nativeDescriptorSetLayout = NativeDescriptorSetLayout;
            var pipelineLayoutCreateInfo  = new PipelineLayoutCreateInfo
            {
                StructureType  = StructureType.PipelineLayoutCreateInfo,
                SetLayoutCount = 1,
                SetLayouts     = new IntPtr(&nativeDescriptorSetLayout)
            };

            // Create shader stages
            Dictionary <int, string> inputAttributeNames;

            // Note: important to pin this so that stages[x].Name is valid during this whole function
            void *defaultEntryPointData = Interop.Fixed(defaultEntryPoint);

            stages = CreateShaderStages(Description, out inputAttributeNames);

            var inputAttributes     = new VertexInputAttributeDescription[Description.InputElements.Length];
            int inputAttributeCount = 0;
            var inputBindings       = new VertexInputBindingDescription[inputAttributes.Length];
            int inputBindingCount   = 0;

            for (int inputElementIndex = 0; inputElementIndex < inputAttributes.Length; inputElementIndex++)
            {
                var inputElement = Description.InputElements[inputElementIndex];
                var slotIndex    = inputElement.InputSlot;

                if (inputElement.InstanceDataStepRate > 1)
                {
                    throw new NotImplementedException();
                }

                Format format;
                int    size;
                bool   isCompressed;
                VulkanConvertExtensions.ConvertPixelFormat(inputElement.Format, out format, out size, out isCompressed);

                var location = inputAttributeNames.FirstOrDefault(x => x.Value == inputElement.SemanticName && inputElement.SemanticIndex == 0 || x.Value == inputElement.SemanticName + inputElement.SemanticIndex);
                if (location.Value != null)
                {
                    inputAttributes[inputAttributeCount++] = new VertexInputAttributeDescription
                    {
                        Format   = format,
                        Offset   = (uint)inputElement.AlignedByteOffset,
                        Binding  = (uint)inputElement.InputSlot,
                        Location = (uint)location.Key
                    };
                }

                inputBindings[slotIndex].Binding   = (uint)slotIndex;
                inputBindings[slotIndex].InputRate = inputElement.InputSlotClass == InputClassification.Vertex ? VertexInputRate.Vertex : VertexInputRate.Instance;

                // TODO VULKAN: This is currently an argument to Draw() overloads.
                if (inputBindings[slotIndex].Stride < inputElement.AlignedByteOffset + size)
                {
                    inputBindings[slotIndex].Stride = (uint)(inputElement.AlignedByteOffset + size);
                }

                if (inputElement.InputSlot >= inputBindingCount)
                {
                    inputBindingCount = inputElement.InputSlot + 1;
                }
            }

            var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo
            {
                StructureType          = StructureType.PipelineInputAssemblyStateCreateInfo,
                Topology               = VulkanConvertExtensions.ConvertPrimitiveType(Description.PrimitiveType),
                PrimitiveRestartEnable = VulkanConvertExtensions.ConvertPrimitiveRestart(Description.PrimitiveType),
            };

            // TODO VULKAN: Tessellation and multisampling
            var multisampleState = new PipelineMultisampleStateCreateInfo
            {
                StructureType        = StructureType.PipelineMultisampleStateCreateInfo,
                RasterizationSamples = SampleCountFlags.Sample1
            };

            //var tessellationState = new PipelineTessellationStateCreateInfo();

            var rasterizationState = new PipelineRasterizationStateCreateInfo
            {
                StructureType           = StructureType.PipelineRasterizationStateCreateInfo,
                CullMode                = VulkanConvertExtensions.ConvertCullMode(Description.RasterizerState.CullMode),
                FrontFace               = Description.RasterizerState.FrontFaceCounterClockwise ? FrontFace.CounterClockwise : FrontFace.Clockwise,
                PolygonMode             = VulkanConvertExtensions.ConvertFillMode(Description.RasterizerState.FillMode),
                DepthBiasEnable         = true, // TODO VULKAN
                DepthBiasConstantFactor = Description.RasterizerState.DepthBias,
                DepthBiasSlopeFactor    = Description.RasterizerState.SlopeScaleDepthBias,
                DepthBiasClamp          = Description.RasterizerState.DepthBiasClamp,
                LineWidth               = 1.0f,
                DepthClampEnable        = !Description.RasterizerState.DepthClipEnable,
                RasterizerDiscardEnable = false,
            };

            var depthStencilState = new PipelineDepthStencilStateCreateInfo
            {
                StructureType     = StructureType.PipelineDepthStencilStateCreateInfo,
                DepthTestEnable   = Description.DepthStencilState.DepthBufferEnable,
                StencilTestEnable = Description.DepthStencilState.StencilEnable,
                DepthWriteEnable  = Description.DepthStencilState.DepthBufferWriteEnable,

                MinDepthBounds        = 0.0f,
                MaxDepthBounds        = 1.0f,
                DepthCompareOperation = VulkanConvertExtensions.ConvertComparisonFunction(Description.DepthStencilState.DepthBufferFunction),
                Front = new StencilOperationState
                {
                    CompareOperation   = VulkanConvertExtensions.ConvertComparisonFunction(Description.DepthStencilState.FrontFace.StencilFunction),
                    DepthFailOperation = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.FrontFace.StencilDepthBufferFail),
                    FailOperation      = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.FrontFace.StencilFail),
                    PassOperation      = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.FrontFace.StencilPass),
                    CompareMask        = Description.DepthStencilState.StencilMask,
                    WriteMask          = Description.DepthStencilState.StencilWriteMask
                },
                Back = new StencilOperationState
                {
                    CompareOperation   = VulkanConvertExtensions.ConvertComparisonFunction(Description.DepthStencilState.BackFace.StencilFunction),
                    DepthFailOperation = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.BackFace.StencilDepthBufferFail),
                    FailOperation      = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.BackFace.StencilFail),
                    PassOperation      = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.BackFace.StencilPass),
                    CompareMask        = Description.DepthStencilState.StencilMask,
                    WriteMask          = Description.DepthStencilState.StencilWriteMask
                }
            };

            var description = Description.BlendState;

            var colorBlendAttachments = new PipelineColorBlendAttachmentState[renderTargetCount];

            var renderTargetBlendState = &description.RenderTarget0;

            for (int i = 0; i < renderTargetCount; i++)
            {
                colorBlendAttachments[i] = new PipelineColorBlendAttachmentState
                {
                    BlendEnable                 = renderTargetBlendState->BlendEnable,
                    AlphaBlendOperation         = VulkanConvertExtensions.ConvertBlendFunction(renderTargetBlendState->AlphaBlendFunction),
                    ColorBlendOperation         = VulkanConvertExtensions.ConvertBlendFunction(renderTargetBlendState->ColorBlendFunction),
                    DestinationAlphaBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->AlphaDestinationBlend),
                    DestinationColorBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->ColorDestinationBlend),
                    SourceAlphaBlendFactor      = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->AlphaSourceBlend),
                    SourceColorBlendFactor      = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->ColorSourceBlend),
                    ColorWriteMask              = VulkanConvertExtensions.ConvertColorWriteChannels(renderTargetBlendState->ColorWriteChannels),
                };

                if (description.IndependentBlendEnable)
                {
                    renderTargetBlendState++;
                }
            }

            var viewportState = new PipelineViewportStateCreateInfo
            {
                StructureType = StructureType.PipelineViewportStateCreateInfo,
                ScissorCount  = 1,
                ViewportCount = 1,
            };

            fixed(void *dynamicStatesPointer   = dynamicStates.Length == 0?null : dynamicStates,
                  inputAttributesPointer       = inputAttributes.Length == 0?null : inputAttributes,
                  inputBindingsPointer         = inputBindings.Length == 0?null : inputBindings,
                  colorBlendAttachmentsPointer = colorBlendAttachments.Length == 0?null : colorBlendAttachments,
                  stagesPointer = stages.Length == 0?null : stages)
            {
                var vertexInputState = new PipelineVertexInputStateCreateInfo
                {
                    StructureType = StructureType.PipelineVertexInputStateCreateInfo,
                    VertexAttributeDescriptionCount = (uint)inputAttributeCount,
                    VertexAttributeDescriptions     = (IntPtr)inputAttributesPointer,
                    VertexBindingDescriptionCount   = (uint)inputBindingCount,
                    VertexBindingDescriptions       = (IntPtr)inputBindingsPointer,
                };

                var colorBlendState = new PipelineColorBlendStateCreateInfo
                {
                    StructureType   = StructureType.PipelineColorBlendStateCreateInfo,
                    AttachmentCount = (uint)renderTargetCount,
                    Attachments     = (IntPtr)colorBlendAttachmentsPointer,
                };

                var dynamicState = new PipelineDynamicStateCreateInfo
                {
                    StructureType     = StructureType.PipelineDynamicStateCreateInfo,
                    DynamicStateCount = (uint)dynamicStates.Length,
                    DynamicStates     = (IntPtr)dynamicStatesPointer,
                };

                var createInfo = new GraphicsPipelineCreateInfo
                {
                    StructureType = StructureType.GraphicsPipelineCreateInfo,
                    StageCount    = (uint)stages.Length,
                    Stages        = (IntPtr)stagesPointer,
                    //TessellationState = new IntPtr(&tessellationState),
                    VertexInputState   = new IntPtr(&vertexInputState),
                    InputAssemblyState = new IntPtr(&inputAssemblyState),
                    RasterizationState = new IntPtr(&rasterizationState),
                    MultisampleState   = new IntPtr(&multisampleState),
                    DepthStencilState  = new IntPtr(&depthStencilState),
                    ColorBlendState    = new IntPtr(&colorBlendState),
                    DynamicState       = new IntPtr(&dynamicState),
                    ViewportState      = new IntPtr(&viewportState),
                    Subpass            = 0,
                };

                using (GraphicsDevice.QueueLock.ReadLock())
                {
                    NativeRenderPass = GraphicsDevice.NativeDevice.CreateRenderPass(ref renderPassCreateInfo);
                    NativeLayout     = GraphicsDevice.NativeDevice.CreatePipelineLayout(ref pipelineLayoutCreateInfo);

                    createInfo.Layout     = NativeLayout;
                    createInfo.RenderPass = NativeRenderPass;

                    try {
                        NativePipeline = GraphicsDevice.NativeDevice.CreateGraphicsPipelines(PipelineCache.Null, 1, &createInfo);
                    } catch (Exception e) {
                        errorDuringCreate = true;
                        NativePipeline    = Pipeline.Null;
                    }
                }
            }

            // Cleanup shader modules
            for (int i = 0; i < stages.Length; i++)
            {
                GraphicsDevice.NativeDevice.DestroyShaderModule(stages[i].Module);
            }
        }
        private RenderPass CreateRenderpass()
        {
            AttachmentDescription *pAttachments = stackalloc AttachmentDescription[2]
            {
                //Color Attachment
                new AttachmentDescription
                {
                    Format         = SwapchainImageFormat,
                    Samples        = SampleCountFlags.SampleCount1Bit,
                    LoadOp         = AttachmentLoadOp.Clear,
                    StoreOp        = AttachmentStoreOp.Store,
                    StencilLoadOp  = AttachmentLoadOp.DontCare,
                    StencilStoreOp = AttachmentStoreOp.DontCare,
                    InitialLayout  = ImageLayout.Undefined,
                    FinalLayout    = ImageLayout.PresentSrcKhr
                },

                //Depth Attachment
                new AttachmentDescription
                {
                    Format         = DepthFormat,
                    Samples        = SampleCountFlags.SampleCount1Bit,
                    LoadOp         = AttachmentLoadOp.Clear,
                    StoreOp        = AttachmentStoreOp.DontCare,
                    StencilLoadOp  = AttachmentLoadOp.DontCare,
                    StencilStoreOp = AttachmentStoreOp.DontCare,
                    InitialLayout  = ImageLayout.Undefined,
                    FinalLayout    = ImageLayout.DepthStencilAttachmentOptimal
                }
            };

            var colorAttachmentRef = new AttachmentReference(0, ImageLayout.ColorAttachmentOptimal);

            var depthAttachmentRef = new AttachmentReference(1, ImageLayout.DepthStencilAttachmentOptimal);

            var subpass = new SubpassDescription
            {
                PipelineBindPoint       = PipelineBindPoint.Graphics,
                ColorAttachmentCount    = 1,
                PColorAttachments       = &colorAttachmentRef,
                PDepthStencilAttachment = &depthAttachmentRef
            };

            var dependency = new SubpassDependency
            {
                SrcSubpass    = Vk.SubpassExternal,
                DstSubpass    = 0,
                SrcStageMask  = PipelineStageFlags.PipelineStageColorAttachmentOutputBit,
                SrcAccessMask = 0,
                DstStageMask  = PipelineStageFlags.PipelineStageColorAttachmentOutputBit,
                DstAccessMask = AccessFlags.AccessColorAttachmentReadBit | AccessFlags.AccessColorAttachmentWriteBit
            };

            var renderPassInfo = new RenderPassCreateInfo
            {
                SType           = StructureType.RenderPassCreateInfo,
                AttachmentCount = 2,
                PAttachments    = pAttachments,
                SubpassCount    = 1,
                PSubpasses      = &subpass,
                DependencyCount = 1,
                PDependencies   = &dependency
            };

            RenderPass rPass;
            var        res = VkApi.CreateRenderPass(Device, &renderPassInfo, null, &rPass);

            if (res != Result.Success)
            {
                throw new VMASharp.VulkanResultException("Failed to create RenderPass!", res);
            }

            return(rPass);
        }
    }
Example #17
0
        public unsafe RenderPass(Api api, SwapChain swapChain, DepthBuffer depthBuffer, AttachmentLoadOp colorBufferLoadOp, AttachmentLoadOp depthBufferLoadOp)
        {
            _api = api;

            var colorAttachment = new AttachmentDescription();

            colorAttachment.Format         = swapChain.Format;
            colorAttachment.Samples        = SampleCountFlags.SampleCount1Bit;
            colorAttachment.LoadOp         = colorBufferLoadOp;
            colorAttachment.StoreOp        = AttachmentStoreOp.Store;
            colorAttachment.StencilLoadOp  = AttachmentLoadOp.DontCare;
            colorAttachment.StencilStoreOp = AttachmentStoreOp.DontCare;
            colorAttachment.InitialLayout  = colorBufferLoadOp == AttachmentLoadOp.Clear ? ImageLayout.Undefined : ImageLayout.PresentSrcKhr;
            colorAttachment.FinalLayout    = ImageLayout.PresentSrcKhr;

            var depthAttachment = new AttachmentDescription();

            depthAttachment.Format         = depthBuffer.Format;
            depthAttachment.Samples        = SampleCountFlags.SampleCount1Bit;
            depthAttachment.LoadOp         = depthBufferLoadOp;
            depthAttachment.StoreOp        = AttachmentStoreOp.DontCare;
            depthAttachment.StencilLoadOp  = AttachmentLoadOp.DontCare;
            depthAttachment.StencilStoreOp = AttachmentStoreOp.DontCare;
            depthAttachment.InitialLayout  = depthBufferLoadOp == AttachmentLoadOp.Clear ? ImageLayout.Undefined : ImageLayout.DepthStencilAttachmentOptimal;
            depthAttachment.FinalLayout    = ImageLayout.DepthStencilAttachmentOptimal;

            var colorAttachmentRef = new AttachmentReference();

            colorAttachmentRef.Attachment = 0;
            colorAttachmentRef.Layout     = ImageLayout.ColorAttachmentOptimal;

            var depthAttachmentRef = new AttachmentReference();

            depthAttachmentRef.Attachment = 1;
            depthAttachmentRef.Layout     = ImageLayout.DepthStencilAttachmentOptimal;

            var subpass = new SubpassDescription();

            subpass.PipelineBindPoint       = PipelineBindPoint.Graphics;
            subpass.ColorAttachmentCount    = 1;
            subpass.PColorAttachments       = (AttachmentReference *)Unsafe.AsPointer(ref colorAttachmentRef);
            subpass.PDepthStencilAttachment = (AttachmentReference *)Unsafe.AsPointer(ref depthAttachmentRef);

            var dependency = new SubpassDependency();

            dependency.SrcSubpass    = Vk.SubpassExternal;
            dependency.DstSubpass    = 0;
            dependency.SrcStageMask  = PipelineStageFlags.PipelineStageColorAttachmentOutputBit;
            dependency.SrcAccessMask = 0;
            dependency.DstStageMask  = PipelineStageFlags.PipelineStageColorAttachmentOutputBit;
            dependency.DstAccessMask = AccessFlags.AccessColorAttachmentReadBit | AccessFlags.AccessColorAttachmentWriteBit;

            Span <AttachmentDescription> attachments = stackalloc AttachmentDescription[]
            {
                colorAttachment,
                depthAttachment
            };

            var renderPassInfo = new RenderPassCreateInfo();

            renderPassInfo.SType           = StructureType.RenderPassCreateInfo;
            renderPassInfo.AttachmentCount = (uint)attachments.Length;
            renderPassInfo.PAttachments    = (AttachmentDescription *)Unsafe.AsPointer(ref attachments[0]);
            renderPassInfo.SubpassCount    = 1;
            renderPassInfo.PSubpasses      = (SubpassDescription *)Unsafe.AsPointer(ref subpass);
            renderPassInfo.DependencyCount = 1;
            renderPassInfo.PDependencies   = (SubpassDependency *)Unsafe.AsPointer(ref dependency);

            Util.Verify(
                _api.Vk.CreateRenderPass(_api.Vk.CurrentDevice.Value, renderPassInfo, default, out _vkRenderPass),