Example #1
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 #2
0
        /// <summary>
        /// Creates a new render pipeline using the given description.
        /// </summary>
        /// <param name="desc">The pipeline description, which must be complete or an error will occur.</param>
        /// <param name="name">An optional name for the pipeline for debug purposes.</param>
        public Pipeline(PipelineDescription desc, string name = null)
        {
            if (desc == null)
            {
                throw new ArgumentNullException(nameof(desc));
            }
            if (!desc.HasTargets)             // Also checked by IsComplete, but this is used to give a more helpful error message
            {
                throw new InvalidOperationException("Cannot create a pipeline without any render targets.");
            }
            if (!desc.IsComplete)
            {
                throw new InvalidOperationException("Cannot create a pipeline from an incomplete description.");
            }
            Name = name;

            // Feature checking
            if ((desc.RasterizerState.Value.FillMode != FillMode.Solid) && !Device.Features.FillModeNonSolid)
            {
                throw new InvalidOperationException("Pipeline cannot be created with non-solid fill modes if that feature is not enabled.");
            }
            if (desc.RasterizerState.Value.LineWidth.HasValue && (desc.RasterizerState.Value.LineWidth.Value != 1) && !Device.Features.WideLines)
            {
                throw new InvalidOperationException("Pipeline cannot be created with wide lines if that feature is not enabled.");
            }
            if (desc.RasterizerState.Value.DepthClampEnable && !Device.Features.DepthClamp)
            {
                throw new InvalidOperationException("Pipeline cannot be created with depth clamping if that feature is not enabled.");
            }

            // Compatibility checking
            if ((desc._dssCI.Value.DepthTestEnable || desc._dssCI.Value.DepthWriteEnable) && !desc._depthAI.HasValue)
            {
                throw new InvalidOperationException("Pipelines with depth operations enabled must be given a depth buffer.");
            }
            if (!desc.CheckRenderTargetSizes())
            {
                throw new InvalidOperationException("Pipeline render targets must all be the same size.");
            }

            // Create the renderpass, framebuffer, and layout
            VkRenderPass  = CreateRenderPass(Device.VkDevice, desc, _renderTargets);
            VkFramebuffer = CreateFramebuffer(VkRenderPass, _renderTargets, desc.TargetSize);
            VkLayout      = CreateLayout(Device.VkDevice);

            // Non-user-specified create infos
            var vsci = new Vk.PipelineViewportStateCreateInfo(
                DefaultViewport = desc.DefaultViewport.Value.ToVulkanNative(),
                DefaultScissor  = desc.DefaultScissor.Value.ToVulkanNative()
                );
            var mssci = new Vk.PipelineMultisampleStateCreateInfo(Vk.SampleCounts.Count1);             // TODO: derive this from the framebuffer once we support multisampling

            // Pipeline creation
            var gpci = new Vk.GraphicsPipelineCreateInfo(
                VkLayout,
                VkRenderPass,
                0,
                desc._shaderCIs,
                desc._piCI.Value,
                desc._vdCI.Value,
                desc._rsCI.Value,
                tessellationState: null,                 // TODO: control this once we support tessellation shaders
                viewportState: vsci,
                multisampleState: mssci,
                depthStencilState: desc._dssCI.Value,
                colorBlendState: desc._cbsCI.Value,
                dynamicState: DEFAULT_DYNAMIC_STATE,
                flags: Vk.PipelineCreateFlags.None,   // TODO: look into derivative pipelines
                basePipelineHandle: null,             // TODO: look into derivative pipelines
                basePipelineIndex: -1                 // TODO: look into derivative pipelines
                );

            VkPipeline = Device.VkDevice.CreateGraphicsPipeline(gpci, null, null);
        }