Пример #1
0
        public static PipelineLayout CreatePipelineLayout(Graphics g, params DescriptorSetLayout[] setLayouts)
        {
            var layoutCreateInfo = new PipelineLayoutCreateInfo(setLayouts);

            return(g.Context.Device.CreatePipelineLayout(layoutCreateInfo));
        }
Пример #2
0
        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));
        }
Пример #3
0
        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));
        }