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); }
/// <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); }