public static PipelineLayout CreatePipelineLayout(Graphics g, params DescriptorSetLayout[] setLayouts) { var layoutCreateInfo = new PipelineLayoutCreateInfo(setLayouts); return(g.Context.Device.CreatePipelineLayout(layoutCreateInfo)); }
public static Pipeline CreateGraphicsPipeline(Graphics g, PipelineLayout pl, RenderPass rp, string[] shaderNames, bool depthTest, bool depthWrite, bool instancing, Type instanceInfoType, BlendMode blendMode, PrimitiveType primType, PrimitiveRenderMode pmode, PrimitiveCullMode cmode, float lineWidth, Vector2 viewportPos, Vector2 viewportSize) { if (instancing && instanceInfoType == null) { throw new NullReferenceException("Instance info type cannot be null"); } var shaderStageCreateInfos = new PipelineShaderStageCreateInfo[shaderNames.Length]; for (var i = 0; i < shaderNames.Length; i++) { var shader = g.Context.Content.Get <ShaderModule>(shaderNames[i]); var shaderName = Path.GetFileNameWithoutExtension(shaderNames[i]); switch (Path.GetExtension(shaderName)) { case ".vert": shaderStageCreateInfos[i] = new PipelineShaderStageCreateInfo(ShaderStages.Vertex, shader, "main"); break; case ".frag": shaderStageCreateInfos[i] = new PipelineShaderStageCreateInfo(ShaderStages.Fragment, shader, "main"); break; default: throw new NotImplementedException($"Unreognized shader type for file \"{shaderNames[i]}\""); } } var fields = typeof(Vertex).GetFields(); var offset = 0; var loci = 0; List <VertexInputAttributeDescription> vertexAttributes = new List <VertexInputAttributeDescription>(fields.Length); for (var i = 0; i < fields.Length; i++) { var ftype = fields[i].FieldType; if (ftype == typeof(Vector3) || ftype == typeof(Angle)) { vertexAttributes.Add(new VertexInputAttributeDescription(loci, 0, Format.R32G32B32SFloat, offset)); offset += 12; loci++; } else if (ftype == typeof(Vector2)) { vertexAttributes.Add(new VertexInputAttributeDescription(loci, 0, Format.R32G32SFloat, offset)); offset += 8; loci++; } else if (ftype == typeof(Color4)) { vertexAttributes.Add(new VertexInputAttributeDescription(loci, 0, Format.R32G32B32A32SFloat, offset)); offset += 16; loci++; } else if (ftype == typeof(float)) { vertexAttributes.Add(new VertexInputAttributeDescription(loci, 0, Format.R32SFloat, offset)); offset += 4; loci++; } else if (ftype == typeof(Matrix4)) { vertexAttributes.Add(new VertexInputAttributeDescription(loci, 0, Format.R32G32B32A32SFloat, offset)); loci++; offset += 16; vertexAttributes.Add(new VertexInputAttributeDescription(loci, 0, Format.R32G32B32A32SFloat, offset)); loci++; offset += 16; vertexAttributes.Add(new VertexInputAttributeDescription(loci, 0, Format.R32G32B32A32SFloat, offset)); loci++; offset += 16; vertexAttributes.Add(new VertexInputAttributeDescription(loci, 0, Format.R32G32B32A32SFloat, offset)); loci++; offset += 16; } else { throw new Exception("Field " + fields[i] + " of vertex struct is an illegal type"); } } var vertexFieldsLength = fields.Length; if (instancing) { fields = instanceInfoType.GetFields(); offset = 0; for (var i = 0; i < fields.Length; i++) { var ftype = fields[i].FieldType; if (ftype == typeof(Vector3) || ftype == typeof(Angle)) { vertexAttributes.Add(new VertexInputAttributeDescription(loci, 1, Format.R32G32B32SFloat, offset)); loci++; offset += 12; } else if (ftype == typeof(Vector2)) { vertexAttributes.Add(new VertexInputAttributeDescription(loci, 1, Format.R32G32SFloat, offset)); loci++; offset += 8; } else if (ftype == typeof(Color4)) { vertexAttributes.Add(new VertexInputAttributeDescription(loci, 1, Format.R32G32B32A32SFloat, offset)); loci++; offset += 16; } else if (ftype == typeof(float)) { vertexAttributes.Add(new VertexInputAttributeDescription(loci, 1, Format.R32SFloat, offset)); loci++; offset += 4; } else if (ftype == typeof(Matrix4)) { vertexAttributes.Add(new VertexInputAttributeDescription(loci, 1, Format.R32G32B32A32SFloat, offset)); loci++; offset += 16; vertexAttributes.Add(new VertexInputAttributeDescription(loci, 1, Format.R32G32B32A32SFloat, offset)); loci++; offset += 16; vertexAttributes.Add(new VertexInputAttributeDescription(loci, 1, Format.R32G32B32A32SFloat, offset)); loci++; offset += 16; vertexAttributes.Add(new VertexInputAttributeDescription(loci, 1, Format.R32G32B32A32SFloat, offset)); loci++; offset += 16; } else { throw new Exception("Field " + fields[i] + " of instance info struct is an illegal type"); } } } var vertexInputStateCreateInfo = new PipelineVertexInputStateCreateInfo( (instancing ? new[] { new VertexInputBindingDescription(0, Interop.SizeOf <Vertex>(), VertexInputRate.Vertex), new VertexInputBindingDescription(1, System.Runtime.InteropServices.Marshal.SizeOf(instanceInfoType), VertexInputRate.Instance) } : new[] { new VertexInputBindingDescription(0, Interop.SizeOf <Vertex>(), VertexInputRate.Vertex) }), vertexAttributes.ToArray() ); var inputAssemblyStateCreateInfo = new PipelineInputAssemblyStateCreateInfo((PrimitiveTopology)primType); var viewportStateCreateInfo = new PipelineViewportStateCreateInfo( new Viewport(viewportPos.X + viewportSize.X, viewportPos.Y + viewportSize.Y, -viewportSize.X, -viewportSize.Y), new Rect2D((int)viewportPos.X, (int)viewportPos.Y, (int)viewportSize.X, (int)viewportSize.Y)); var rasterizationStateCreateInfo = new PipelineRasterizationStateCreateInfo { PolygonMode = (PolygonMode)pmode, CullMode = (CullModes)cmode, FrontFace = FrontFace.Clockwise, LineWidth = lineWidth }; var multisampleStateCreateInfo = new PipelineMultisampleStateCreateInfo { RasterizationSamples = g.Samples >= 48 ? SampleCounts.Count64 : g.Samples >= 24 ? SampleCounts.Count32 : g.Samples >= 12 ? SampleCounts.Count16 : g.Samples >= 6 ? SampleCounts.Count8 : g.Samples >= 3 ? SampleCounts.Count4 : g.Samples == 2 ? SampleCounts.Count2 : SampleCounts.Count1, MinSampleShading = 1.0f }; var depthStencilCreateInfo = new PipelineDepthStencilStateCreateInfo { DepthTestEnable = depthTest, DepthWriteEnable = depthWrite, DepthCompareOp = CompareOp.LessOrEqual, Back = new StencilOpState { FailOp = StencilOp.Keep, PassOp = StencilOp.Keep, CompareOp = CompareOp.Always }, Front = new StencilOpState { FailOp = StencilOp.Keep, PassOp = StencilOp.Keep, CompareOp = CompareOp.Always } }; var colorBlendAttachmentState = new PipelineColorBlendAttachmentState { SrcColorBlendFactor = BlendMode.GetBlendFactor(blendMode.SrcColorFactor), DstColorBlendFactor = BlendMode.GetBlendFactor(blendMode.DstColorFactor), ColorBlendOp = BlendMode.GetBlendOp(blendMode.ColorOp), SrcAlphaBlendFactor = BlendMode.GetBlendFactor(blendMode.SrcAlphaFactor), DstAlphaBlendFactor = BlendMode.GetBlendFactor(blendMode.DstAlphaFactor), AlphaBlendOp = BlendMode.GetBlendOp(blendMode.AlphaOp), ColorWriteMask = BlendMode.GetColorWriteMask(blendMode.Mask), BlendEnable = true }; var colorBlendStateCreateInfo = new PipelineColorBlendStateCreateInfo( new[] { colorBlendAttachmentState }); var pipelineCreateInfo = new GraphicsPipelineCreateInfo( pl, rp, 0, shaderStageCreateInfos, inputAssemblyStateCreateInfo, vertexInputStateCreateInfo, rasterizationStateCreateInfo, viewportState: viewportStateCreateInfo, multisampleState: multisampleStateCreateInfo, depthStencilState: depthStencilCreateInfo, colorBlendState: colorBlendStateCreateInfo//, //dynamicState: new PipelineDynamicStateCreateInfo(DynamicState.Viewport) ); return(g.Context.Device.CreateGraphicsPipeline(pipelineCreateInfo)); }
public static RenderPass CreateRenderPass(Graphics g, bool clearDepthOnBeginPass) { var subpasses = new[] { new SubpassDescription( new[] { new AttachmentReference(0, VulkanCore.ImageLayout.ColorAttachmentOptimal) }, new AttachmentReference(1, VulkanCore.ImageLayout.DepthStencilAttachmentOptimal)) }; var samples = g.Samples == 64 ? SampleCounts.Count64 : g.Samples == 32 ? SampleCounts.Count32 : g.Samples == 16 ? SampleCounts.Count16 : g.Samples == 8 ? SampleCounts.Count8 : g.Samples == 4 ? SampleCounts.Count4 : g.Samples == 2 ? SampleCounts.Count2 : SampleCounts.Count1; var attachments = new[] { new AttachmentDescription { Format = g.Context.Swapchain.Format, Samples = samples, LoadOp = AttachmentLoadOp.Load, StoreOp = AttachmentStoreOp.Store, StencilLoadOp = AttachmentLoadOp.DontCare, StencilStoreOp = AttachmentStoreOp.DontCare, InitialLayout = VulkanCore.ImageLayout.Undefined, FinalLayout = VulkanCore.ImageLayout.PresentSrcKhr }, new AttachmentDescription { Format = g.Context.DepthStencilFormat, Samples = samples, LoadOp = clearDepthOnBeginPass ? AttachmentLoadOp.Clear : AttachmentLoadOp.Load, StoreOp = AttachmentStoreOp.DontCare, StencilLoadOp = AttachmentLoadOp.DontCare, StencilStoreOp = AttachmentStoreOp.DontCare, InitialLayout = VulkanCore.ImageLayout.Undefined, FinalLayout = VulkanCore.ImageLayout.DepthStencilAttachmentOptimal } }; var dependencies = new[] { new SubpassDependency { SrcSubpass = Constant.SubpassExternal, DstSubpass = 0, SrcStageMask = PipelineStages.BottomOfPipe, DstStageMask = PipelineStages.ColorAttachmentOutput, SrcAccessMask = Accesses.MemoryRead, DstAccessMask = Accesses.ColorAttachmentRead | Accesses.ColorAttachmentWrite, DependencyFlags = Dependencies.ByRegion }, new SubpassDependency { SrcSubpass = 0, DstSubpass = Constant.SubpassExternal, SrcStageMask = PipelineStages.ColorAttachmentOutput, DstStageMask = PipelineStages.BottomOfPipe, SrcAccessMask = Accesses.ColorAttachmentRead | Accesses.ColorAttachmentWrite, DstAccessMask = Accesses.MemoryRead, DependencyFlags = Dependencies.ByRegion } }; var createInfo = new RenderPassCreateInfo(subpasses, attachments, dependencies); return(g.Context.Device.CreateRenderPass(createInfo)); }