Пример #1
0
        public static PipelineState ToVulkanPipelineState(this ProgramPipelineState state, VulkanRenderer gd)
        {
            PipelineState pipeline = new PipelineState();

            pipeline.Initialize();

            // It is assumed that Dynamic State is enabled when this conversion is used.

            pipeline.BlendConstantA = state.BlendDescriptors[0].BlendConstant.Alpha;
            pipeline.BlendConstantB = state.BlendDescriptors[0].BlendConstant.Blue;
            pipeline.BlendConstantG = state.BlendDescriptors[0].BlendConstant.Green;
            pipeline.BlendConstantR = state.BlendDescriptors[0].BlendConstant.Red;

            pipeline.CullMode = state.CullEnable ? state.CullMode.Convert() : CullModeFlags.CullModeNone;

            pipeline.DepthBoundsTestEnable = false; // Not implemented.

            pipeline.DepthClampEnable = state.DepthClampEnable;

            pipeline.DepthTestEnable  = state.DepthTest.TestEnable;
            pipeline.DepthWriteEnable = state.DepthTest.WriteEnable;
            pipeline.DepthCompareOp   = state.DepthTest.Func.Convert();

            pipeline.FrontFace = state.FrontFace.Convert();

            pipeline.HasDepthStencil = state.DepthStencilEnable;
            pipeline.LineWidth       = state.LineWidth;
            pipeline.LogicOpEnable   = state.LogicOpEnable;
            pipeline.LogicOp         = state.LogicOp.Convert();

            pipeline.MinDepthBounds = 0f; // Not implemented.
            pipeline.MaxDepthBounds = 0f; // Not implemented.

            pipeline.PatchControlPoints      = state.PatchControlPoints;
            pipeline.PolygonMode             = Silk.NET.Vulkan.PolygonMode.Fill; // Not implemented.
            pipeline.PrimitiveRestartEnable  = state.PrimitiveRestartEnable;
            pipeline.RasterizerDiscardEnable = state.RasterizerDiscard;
            pipeline.SamplesCount            = (uint)state.SamplesCount;

            if (gd.Capabilities.SupportsMultiView)
            {
                pipeline.ScissorsCount  = Constants.MaxViewports;
                pipeline.ViewportsCount = Constants.MaxViewports;
            }
            else
            {
                pipeline.ScissorsCount  = 1;
                pipeline.ViewportsCount = 1;
            }

            pipeline.DepthBiasEnable = state.BiasEnable != 0;

            // Stencil masks and ref are dynamic, so are 0 in the Vulkan pipeline.

            pipeline.StencilFrontFailOp      = state.StencilTest.FrontSFail.Convert();
            pipeline.StencilFrontPassOp      = state.StencilTest.FrontDpPass.Convert();
            pipeline.StencilFrontDepthFailOp = state.StencilTest.FrontDpFail.Convert();
            pipeline.StencilFrontCompareOp   = state.StencilTest.FrontFunc.Convert();
            pipeline.StencilFrontCompareMask = 0;
            pipeline.StencilFrontWriteMask   = 0;
            pipeline.StencilFrontReference   = 0;

            pipeline.StencilBackFailOp      = state.StencilTest.BackSFail.Convert();
            pipeline.StencilBackPassOp      = state.StencilTest.BackDpPass.Convert();
            pipeline.StencilBackDepthFailOp = state.StencilTest.BackDpFail.Convert();
            pipeline.StencilBackCompareOp   = state.StencilTest.BackFunc.Convert();
            pipeline.StencilBackCompareMask = 0;
            pipeline.StencilBackWriteMask   = 0;
            pipeline.StencilBackReference   = 0;

            pipeline.StencilTestEnable = state.StencilTest.TestEnable;

            pipeline.Topology = state.Topology.Convert();

            int vaCount = Math.Min(Constants.MaxVertexAttributes, state.VertexAttribCount);

            for (int i = 0; i < vaCount; i++)
            {
                var attribute   = state.VertexAttribs[i];
                var bufferIndex = attribute.IsZero ? 0 : attribute.BufferIndex + 1;

                pipeline.Internal.VertexAttributeDescriptions[i] = new VertexInputAttributeDescription(
                    (uint)i,
                    (uint)bufferIndex,
                    gd.FormatCapabilities.ConvertToVertexVkFormat(attribute.Format),
                    (uint)attribute.Offset);
            }

            int descriptorIndex = 1;

            pipeline.Internal.VertexBindingDescriptions[0] = new VertexInputBindingDescription(0, 0, VertexInputRate.Vertex);

            int vbCount = Math.Min(Constants.MaxVertexBuffers, state.VertexBufferCount);

            for (int i = 0; i < vbCount; i++)
            {
                var vertexBuffer = state.VertexBuffers[i];

                if (vertexBuffer.Enable)
                {
                    var inputRate = vertexBuffer.Divisor != 0 ? VertexInputRate.Instance : VertexInputRate.Vertex;

                    // TODO: Support divisor > 1
                    pipeline.Internal.VertexBindingDescriptions[descriptorIndex++] = new VertexInputBindingDescription(
                        (uint)i + 1,
                        (uint)vertexBuffer.Stride,
                        inputRate);
                }
            }

            pipeline.VertexBindingDescriptionsCount = (uint)descriptorIndex;

            // NOTE: Viewports, Scissors are dynamic.

            for (int i = 0; i < 8; i++)
            {
                var blend = state.BlendDescriptors[i];

                pipeline.Internal.ColorBlendAttachmentState[i] = new PipelineColorBlendAttachmentState(
                    blend.Enable,
                    blend.ColorSrcFactor.Convert(),
                    blend.ColorDstFactor.Convert(),
                    blend.ColorOp.Convert(),
                    blend.AlphaSrcFactor.Convert(),
                    blend.AlphaDstFactor.Convert(),
                    blend.AlphaOp.Convert(),
                    (ColorComponentFlags)state.ColorWriteMask[i]);
            }

            int maxAttachmentIndex = 0;

            for (int i = 0; i < 8; i++)
            {
                if (state.AttachmentEnable[i])
                {
                    pipeline.Internal.AttachmentFormats[maxAttachmentIndex++] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i]);
                }
            }

            if (state.DepthStencilEnable)
            {
                pipeline.Internal.AttachmentFormats[maxAttachmentIndex++] = gd.FormatCapabilities.ConvertToVkFormat(state.DepthStencilFormat);
            }

            pipeline.ColorBlendAttachmentStateCount   = 8;
            pipeline.VertexAttributeDescriptionsCount = (uint)Math.Min(Constants.MaxVertexAttributes, state.VertexAttribCount);

            return(pipeline);
        }