Esempio n. 1
0
        protected void init(GraphicPipelineConfig cfg)
        {
            if (state != ActivableState.Activated)
            {
                Layout.Activate();
                RenderPass.Activate();
                Cache?.Activate();

                List <VkPipelineShaderStageCreateInfo> shaderStages = new List <VkPipelineShaderStageCreateInfo> ();
                foreach (ShaderInfo shader in cfg.Shaders)
                {
                    shaderStages.Add(shader.Info);
                }

                using (PinnedObjects pctx = new PinnedObjects()) {
                    VkPipelineColorBlendStateCreateInfo colorBlendInfo = VkPipelineColorBlendStateCreateInfo.New();
                    colorBlendInfo.logicOpEnable = cfg.ColorBlendLogicOpEnable;
                    colorBlendInfo.logicOp       = cfg.ColorBlendLogicOp;
                    unsafe {
                        colorBlendInfo.blendConstants[0] = cfg.ColorBlendConstants.X;
                        colorBlendInfo.blendConstants[1] = cfg.ColorBlendConstants.Y;
                        colorBlendInfo.blendConstants[2] = cfg.ColorBlendConstants.Z;
                        colorBlendInfo.blendConstants[3] = cfg.ColorBlendConstants.W;
                    }
                    colorBlendInfo.attachmentCount = (uint)cfg.blendAttachments.Count;
                    colorBlendInfo.pAttachments    = cfg.blendAttachments.Pin(pctx);

                    VkPipelineDynamicStateCreateInfo dynStatesInfo = VkPipelineDynamicStateCreateInfo.New();
                    dynStatesInfo.dynamicStateCount = (uint)cfg.dynamicStates.Count;
                    dynStatesInfo.pDynamicStates    = cfg.dynamicStates.Cast <int> ().ToArray().Pin(pctx);

                    VkPipelineVertexInputStateCreateInfo vertInputInfo = VkPipelineVertexInputStateCreateInfo.New();
                    vertInputInfo.vertexBindingDescriptionCount   = (uint)cfg.vertexBindings.Count;
                    vertInputInfo.pVertexBindingDescriptions      = cfg.vertexBindings.Pin(pctx);
                    vertInputInfo.vertexAttributeDescriptionCount = (uint)cfg.vertexAttributes.Count;
                    vertInputInfo.pVertexAttributeDescriptions    = cfg.vertexAttributes.Pin(pctx);

                    VkPipelineViewportStateCreateInfo viewportState = VkPipelineViewportStateCreateInfo.New();
                    if (cfg.Viewports.Count > 0)
                    {
                        viewportState.viewportCount = (uint)cfg.Viewports.Count;
                        viewportState.pViewports    = cfg.Viewports.Pin(pctx);
                    }
                    else
                    {
                        viewportState.viewportCount = 1;
                    }

                    if (cfg.Scissors.Count > 0)
                    {
                        viewportState.scissorCount = (uint)cfg.Scissors.Count;
                        viewportState.pScissors    = cfg.Scissors.Pin(pctx);
                    }
                    else
                    {
                        viewportState.scissorCount = 1;
                    }

                    VkGraphicsPipelineCreateInfo info = VkGraphicsPipelineCreateInfo.New();
                    info.renderPass          = RenderPass.handle;
                    info.layout              = Layout.handle;
                    info.pVertexInputState   = vertInputInfo.Pin(pctx);
                    info.pInputAssemblyState = cfg.inputAssemblyState.Pin(pctx);
                    info.pRasterizationState = cfg.rasterizationState.Pin(pctx);
                    info.pColorBlendState    = colorBlendInfo.Pin(pctx);
                    info.pMultisampleState   = cfg.multisampleState.Pin(pctx);
                    info.pViewportState      = viewportState.Pin(pctx);
                    info.pDepthStencilState  = cfg.depthStencilState.Pin(pctx);
                    info.pDynamicState       = dynStatesInfo.Pin(pctx);
                    info.stageCount          = (uint)cfg.Shaders.Count;
                    info.pStages             = shaderStages.Pin(pctx);
                    info.subpass             = cfg.SubpassIndex;

                    Utils.CheckResult(vkCreateGraphicsPipelines(Dev.VkDev, Cache == null ? VkPipelineCache.Null : Cache.handle, 1, ref info, IntPtr.Zero, out handle));
                }
            }
            base.Activate();
        }
Esempio n. 2
0
        public VkPipeline(VkGraphicsDevice gd, ref GraphicsPipelineDescription description)
            : base(ref description)
        {
            _gd = gd;
            IsComputePipeline = false;
            RefCount          = new ResourceRefCount(DisposeCore);

            VkGraphicsPipelineCreateInfo pipelineCI = VkGraphicsPipelineCreateInfo.New();

            // Blend State
            VkPipelineColorBlendStateCreateInfo blendStateCI = VkPipelineColorBlendStateCreateInfo.New();
            int attachmentsCount = description.BlendState.AttachmentStates.Length;
            VkPipelineColorBlendAttachmentState *attachmentsPtr
                = stackalloc VkPipelineColorBlendAttachmentState[attachmentsCount];

            for (int i = 0; i < attachmentsCount; i++)
            {
                BlendAttachmentDescription          vdDesc          = description.BlendState.AttachmentStates[i];
                VkPipelineColorBlendAttachmentState attachmentState = new VkPipelineColorBlendAttachmentState();
                attachmentState.srcColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceColorFactor);
                attachmentState.dstColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationColorFactor);
                attachmentState.colorBlendOp        = VkFormats.VdToVkBlendOp(vdDesc.ColorFunction);
                attachmentState.srcAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceAlphaFactor);
                attachmentState.dstAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationAlphaFactor);
                attachmentState.alphaBlendOp        = VkFormats.VdToVkBlendOp(vdDesc.AlphaFunction);
                attachmentState.blendEnable         = vdDesc.BlendEnabled;
                attachmentState.colorWriteMask      = VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A;
                attachmentsPtr[i] = attachmentState;
            }

            blendStateCI.attachmentCount = (uint)attachmentsCount;
            blendStateCI.pAttachments    = attachmentsPtr;
            RgbaFloat blendFactor = description.BlendState.BlendFactor;

            blendStateCI.blendConstants_0 = blendFactor.R;
            blendStateCI.blendConstants_1 = blendFactor.G;
            blendStateCI.blendConstants_2 = blendFactor.B;
            blendStateCI.blendConstants_3 = blendFactor.A;

            pipelineCI.pColorBlendState = &blendStateCI;

            // Rasterizer State
            RasterizerStateDescription             rsDesc = description.RasterizerState;
            VkPipelineRasterizationStateCreateInfo rsCI   = VkPipelineRasterizationStateCreateInfo.New();

            rsCI.cullMode         = VkFormats.VdToVkCullMode(rsDesc.CullMode);
            rsCI.polygonMode      = VkFormats.VdToVkPolygonMode(rsDesc.FillMode);
            rsCI.depthClampEnable = !rsDesc.DepthClipEnabled;
            rsCI.frontFace        = rsDesc.FrontFace == FrontFace.Clockwise ? VkFrontFace.Clockwise : VkFrontFace.CounterClockwise;
            rsCI.lineWidth        = 1f;

            pipelineCI.pRasterizationState = &rsCI;

            ScissorTestEnabled = rsDesc.ScissorTestEnabled;

            // Dynamic State
            VkPipelineDynamicStateCreateInfo dynamicStateCI = VkPipelineDynamicStateCreateInfo.New();
            VkDynamicState *dynamicStates = stackalloc VkDynamicState[2];

            dynamicStates[0] = VkDynamicState.Viewport;
            dynamicStates[1] = VkDynamicState.Scissor;
            dynamicStateCI.dynamicStateCount = 2;
            dynamicStateCI.pDynamicStates    = dynamicStates;

            pipelineCI.pDynamicState = &dynamicStateCI;

            // Depth Stencil State
            DepthStencilStateDescription          vdDssDesc = description.DepthStencilState;
            VkPipelineDepthStencilStateCreateInfo dssCI     = VkPipelineDepthStencilStateCreateInfo.New();

            dssCI.depthWriteEnable  = vdDssDesc.DepthWriteEnabled;
            dssCI.depthTestEnable   = vdDssDesc.DepthTestEnabled;
            dssCI.depthCompareOp    = VkFormats.VdToVkCompareOp(vdDssDesc.DepthComparison);
            dssCI.stencilTestEnable = vdDssDesc.StencilTestEnabled;

            dssCI.front.failOp      = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.Fail);
            dssCI.front.passOp      = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.Pass);
            dssCI.front.depthFailOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.DepthFail);
            dssCI.front.compareOp   = VkFormats.VdToVkCompareOp(vdDssDesc.StencilFront.Comparison);
            dssCI.front.compareMask = vdDssDesc.StencilReadMask;
            dssCI.front.writeMask   = vdDssDesc.StencilWriteMask;
            dssCI.front.reference   = vdDssDesc.StencilReference;

            dssCI.back.failOp      = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.Fail);
            dssCI.back.passOp      = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.Pass);
            dssCI.back.depthFailOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.DepthFail);
            dssCI.back.compareOp   = VkFormats.VdToVkCompareOp(vdDssDesc.StencilBack.Comparison);
            dssCI.back.compareMask = vdDssDesc.StencilReadMask;
            dssCI.back.writeMask   = vdDssDesc.StencilWriteMask;
            dssCI.back.reference   = vdDssDesc.StencilReference;

            pipelineCI.pDepthStencilState = &dssCI;

            // Multisample
            VkPipelineMultisampleStateCreateInfo multisampleCI = VkPipelineMultisampleStateCreateInfo.New();
            VkSampleCountFlags vkSampleCount = VkFormats.VdToVkSampleCount(description.Outputs.SampleCount);

            multisampleCI.rasterizationSamples  = vkSampleCount;
            multisampleCI.alphaToCoverageEnable = description.BlendState.AlphaToCoverageEnabled;

            pipelineCI.pMultisampleState = &multisampleCI;

            // Input Assembly
            VkPipelineInputAssemblyStateCreateInfo inputAssemblyCI = VkPipelineInputAssemblyStateCreateInfo.New();

            inputAssemblyCI.topology = VkFormats.VdToVkPrimitiveTopology(description.PrimitiveTopology);

            pipelineCI.pInputAssemblyState = &inputAssemblyCI;

            // Vertex Input State
            VkPipelineVertexInputStateCreateInfo vertexInputCI = VkPipelineVertexInputStateCreateInfo.New();

            VertexLayoutDescription[] inputDescriptions = description.ShaderSet.VertexLayouts;
            uint bindingCount   = (uint)inputDescriptions.Length;
            uint attributeCount = 0;

            for (int i = 0; i < inputDescriptions.Length; i++)
            {
                attributeCount += (uint)inputDescriptions[i].Elements.Length;
            }
            VkVertexInputBindingDescription *  bindingDescs   = stackalloc VkVertexInputBindingDescription[(int)bindingCount];
            VkVertexInputAttributeDescription *attributeDescs = stackalloc VkVertexInputAttributeDescription[(int)attributeCount];

            int targetIndex    = 0;
            int targetLocation = 0;

            for (int binding = 0; binding < inputDescriptions.Length; binding++)
            {
                VertexLayoutDescription inputDesc = inputDescriptions[binding];
                bindingDescs[binding] = new VkVertexInputBindingDescription()
                {
                    binding   = (uint)binding,
                    inputRate = (inputDesc.InstanceStepRate != 0) ? VkVertexInputRate.Instance : VkVertexInputRate.Vertex,
                    stride    = inputDesc.Stride
                };

                uint currentOffset = 0;
                for (int location = 0; location < inputDesc.Elements.Length; location++)
                {
                    VertexElementDescription inputElement = inputDesc.Elements[location];

                    attributeDescs[targetIndex] = new VkVertexInputAttributeDescription()
                    {
                        format   = VkFormats.VdToVkVertexElementFormat(inputElement.Format),
                        binding  = (uint)binding,
                        location = (uint)(targetLocation + location),
                        offset   = inputElement.Offset != 0 ? inputElement.Offset : currentOffset
                    };

                    targetIndex   += 1;
                    currentOffset += FormatHelpers.GetSizeInBytes(inputElement.Format);
                }

                targetLocation += inputDesc.Elements.Length;
            }

            vertexInputCI.vertexBindingDescriptionCount   = bindingCount;
            vertexInputCI.pVertexBindingDescriptions      = bindingDescs;
            vertexInputCI.vertexAttributeDescriptionCount = attributeCount;
            vertexInputCI.pVertexAttributeDescriptions    = attributeDescs;

            pipelineCI.pVertexInputState = &vertexInputCI;

            // Shader Stage

            VkSpecializationInfo specializationInfo;

            SpecializationConstant[] specDescs = description.ShaderSet.Specializations;
            if (specDescs != null)
            {
                uint specDataSize = 0;
                foreach (SpecializationConstant spec in specDescs)
                {
                    specDataSize += VkFormats.GetSpecializationConstantSize(spec.Type);
                }
                byte *fullSpecData                   = stackalloc byte[(int)specDataSize];
                int   specializationCount            = specDescs.Length;
                VkSpecializationMapEntry *mapEntries = stackalloc VkSpecializationMapEntry[specializationCount];
                uint specOffset = 0;
                for (int i = 0; i < specializationCount; i++)
                {
                    ulong data     = specDescs[i].Data;
                    byte *srcData  = (byte *)&data;
                    uint  dataSize = VkFormats.GetSpecializationConstantSize(specDescs[i].Type);
                    Unsafe.CopyBlock(fullSpecData + specOffset, srcData, dataSize);
                    mapEntries[i].constantID = specDescs[i].ID;
                    mapEntries[i].offset     = specOffset;
                    mapEntries[i].size       = (UIntPtr)dataSize;
                    specOffset += dataSize;
                }
                specializationInfo.dataSize      = (UIntPtr)specDataSize;
                specializationInfo.pData         = fullSpecData;
                specializationInfo.mapEntryCount = (uint)specializationCount;
                specializationInfo.pMapEntries   = mapEntries;
            }

            Shader[] shaders = description.ShaderSet.Shaders;
            StackList <VkPipelineShaderStageCreateInfo> stages = new StackList <VkPipelineShaderStageCreateInfo>();

            foreach (Shader shader in shaders)
            {
                VkShader vkShader = Util.AssertSubtype <Shader, VkShader>(shader);
                VkPipelineShaderStageCreateInfo stageCI = VkPipelineShaderStageCreateInfo.New();
                stageCI.module = vkShader.ShaderModule;
                stageCI.stage  = VkFormats.VdToVkShaderStages(shader.Stage);
                // stageCI.pName = CommonStrings.main; // Meh
                stageCI.pName = new FixedUtf8String(shader.EntryPoint); // TODO: DONT ALLOCATE HERE
                stageCI.pSpecializationInfo = &specializationInfo;
                stages.Add(stageCI);
            }

            pipelineCI.stageCount = stages.Count;
            pipelineCI.pStages    = (VkPipelineShaderStageCreateInfo *)stages.Data;

            // ViewportState
            VkPipelineViewportStateCreateInfo viewportStateCI = VkPipelineViewportStateCreateInfo.New();

            viewportStateCI.viewportCount = 1;
            viewportStateCI.scissorCount  = 1;

            pipelineCI.pViewportState = &viewportStateCI;

            // Pipeline Layout
            ResourceLayout[]           resourceLayouts  = description.ResourceLayouts;
            VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New();

            pipelineLayoutCI.setLayoutCount = (uint)resourceLayouts.Length;
            VkDescriptorSetLayout *dsls = stackalloc VkDescriptorSetLayout[resourceLayouts.Length];

            for (int i = 0; i < resourceLayouts.Length; i++)
            {
                dsls[i] = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(resourceLayouts[i]).DescriptorSetLayout;
            }
            pipelineLayoutCI.pSetLayouts = dsls;

            vkCreatePipelineLayout(_gd.Device, ref pipelineLayoutCI, null, out _pipelineLayout);
            pipelineCI.layout = _pipelineLayout;

            // Create fake RenderPass for compatibility.

            VkRenderPassCreateInfo renderPassCI = VkRenderPassCreateInfo.New();
            OutputDescription      outputDesc   = description.Outputs;
            StackList <VkAttachmentDescription, Size512Bytes> attachments = new StackList <VkAttachmentDescription, Size512Bytes>();

            // TODO: A huge portion of this next part is duplicated in VkFramebuffer.cs.

            StackList <VkAttachmentDescription> colorAttachmentDescs = new StackList <VkAttachmentDescription>();
            StackList <VkAttachmentReference>   colorAttachmentRefs  = new StackList <VkAttachmentReference>();

            for (uint i = 0; i < outputDesc.ColorAttachments.Length; i++)
            {
                colorAttachmentDescs[i].format         = VkFormats.VdToVkPixelFormat(outputDesc.ColorAttachments[i].Format);
                colorAttachmentDescs[i].samples        = vkSampleCount;
                colorAttachmentDescs[i].loadOp         = VkAttachmentLoadOp.DontCare;
                colorAttachmentDescs[i].storeOp        = VkAttachmentStoreOp.Store;
                colorAttachmentDescs[i].stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                colorAttachmentDescs[i].stencilStoreOp = VkAttachmentStoreOp.DontCare;
                colorAttachmentDescs[i].initialLayout  = VkImageLayout.Undefined;
                colorAttachmentDescs[i].finalLayout    = VkImageLayout.ShaderReadOnlyOptimal;
                attachments.Add(colorAttachmentDescs[i]);

                colorAttachmentRefs[i].attachment = i;
                colorAttachmentRefs[i].layout     = VkImageLayout.ColorAttachmentOptimal;
            }

            VkAttachmentDescription depthAttachmentDesc = new VkAttachmentDescription();
            VkAttachmentReference   depthAttachmentRef  = new VkAttachmentReference();

            if (outputDesc.DepthAttachment != null)
            {
                PixelFormat depthFormat = outputDesc.DepthAttachment.Value.Format;
                bool        hasStencil  = FormatHelpers.IsStencilFormat(depthFormat);
                depthAttachmentDesc.format         = VkFormats.VdToVkPixelFormat(outputDesc.DepthAttachment.Value.Format, toDepthFormat: true);
                depthAttachmentDesc.samples        = vkSampleCount;
                depthAttachmentDesc.loadOp         = VkAttachmentLoadOp.DontCare;
                depthAttachmentDesc.storeOp        = VkAttachmentStoreOp.Store;
                depthAttachmentDesc.stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                depthAttachmentDesc.stencilStoreOp = hasStencil ? VkAttachmentStoreOp.Store : VkAttachmentStoreOp.DontCare;
                depthAttachmentDesc.initialLayout  = VkImageLayout.Undefined;
                depthAttachmentDesc.finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal;

                depthAttachmentRef.attachment = (uint)outputDesc.ColorAttachments.Length;
                depthAttachmentRef.layout     = VkImageLayout.DepthStencilAttachmentOptimal;
            }

            VkSubpassDescription subpass = new VkSubpassDescription();

            subpass.pipelineBindPoint    = VkPipelineBindPoint.Graphics;
            subpass.colorAttachmentCount = (uint)outputDesc.ColorAttachments.Length;
            subpass.pColorAttachments    = (VkAttachmentReference *)colorAttachmentRefs.Data;
            for (int i = 0; i < colorAttachmentDescs.Count; i++)
            {
                attachments.Add(colorAttachmentDescs[i]);
            }

            if (outputDesc.DepthAttachment != null)
            {
                subpass.pDepthStencilAttachment = &depthAttachmentRef;
                attachments.Add(depthAttachmentDesc);
            }

            VkSubpassDependency subpassDependency = new VkSubpassDependency();

            subpassDependency.srcSubpass    = SubpassExternal;
            subpassDependency.srcStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite;

            renderPassCI.attachmentCount = attachments.Count;
            renderPassCI.pAttachments    = (VkAttachmentDescription *)attachments.Data;
            renderPassCI.subpassCount    = 1;
            renderPassCI.pSubpasses      = &subpass;
            renderPassCI.dependencyCount = 1;
            renderPassCI.pDependencies   = &subpassDependency;

            VkResult creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPass);

            CheckResult(creationResult);

            pipelineCI.renderPass = _renderPass;

            VkResult result = vkCreateGraphicsPipelines(_gd.Device, VkPipelineCache.Null, 1, ref pipelineCI, null, out _devicePipeline);

            CheckResult(result);

            ResourceSetCount    = (uint)description.ResourceLayouts.Length;
            DynamicOffsetsCount = 0;
            foreach (VkResourceLayout layout in description.ResourceLayouts)
            {
                DynamicOffsetsCount += layout.DynamicBufferCount;
            }
        }
Esempio n. 3
0
        public static VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo()
        {
            VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo = VkPipelineVertexInputStateCreateInfo.New();

            return(pipelineVertexInputStateCreateInfo);
        }
Esempio n. 4
0
        void preparePipelines()
        {
            VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
                Initializers.pipelineInputAssemblyStateCreateInfo(
                    VkPrimitiveTopology.TriangleList,
                    0,
                    False);

            VkPipelineRasterizationStateCreateInfo rasterizationState =
                Initializers.pipelineRasterizationStateCreateInfo(
                    VkPolygonMode.Fill,
                    VkCullModeFlags.Back,
                    VkFrontFace.Clockwise,
                    0);

            VkPipelineColorBlendAttachmentState blendAttachmentState =
                Initializers.pipelineColorBlendAttachmentState(
                    (VkColorComponentFlags)0xf,
                    False);

            VkPipelineColorBlendStateCreateInfo colorBlendState =
                Initializers.pipelineColorBlendStateCreateInfo(
                    1,
                    &blendAttachmentState);

            VkPipelineDepthStencilStateCreateInfo depthStencilState =
                Initializers.pipelineDepthStencilStateCreateInfo(
                    True,
                    True,
                    VkCompareOp.LessOrEqual);

            VkPipelineViewportStateCreateInfo viewportState =
                Initializers.pipelineViewportStateCreateInfo(1, 1, 0);

            VkPipelineMultisampleStateCreateInfo multisampleState =
                Initializers.pipelineMultisampleStateCreateInfo(VkSampleCountFlags._1);

            FixedArray3 <VkDynamicState> dynamicStateEnables = new FixedArray3 <VkDynamicState>(
                VkDynamicState.Viewport,
                VkDynamicState.Scissor,
                VkDynamicState.LineWidth);
            VkPipelineDynamicStateCreateInfo dynamicState =
                Initializers.pipelineDynamicStateCreateInfo((VkDynamicState *)Unsafe.AsPointer(ref dynamicStateEnables), dynamicStateEnables.Count);

            VkGraphicsPipelineCreateInfo pipelineCreateInfo =
                Initializers.pipelineCreateInfo(pipelineLayout, RenderPass);

            FixedArray2 <VkPipelineShaderStageCreateInfo> shaderStages = new FixedArray2 <VkPipelineShaderStageCreateInfo>();

            shaderStages.First  = loadShader(getAssetPath() + "shaders/pipelines/phong.vert.spv", VkShaderStageFlags.Vertex);
            shaderStages.Second = loadShader(getAssetPath() + "shaders/pipelines/phong.frag.spv", VkShaderStageFlags.Fragment);

            pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
            pipelineCreateInfo.pRasterizationState = &rasterizationState;
            pipelineCreateInfo.pColorBlendState    = &colorBlendState;
            pipelineCreateInfo.pMultisampleState   = &multisampleState;
            pipelineCreateInfo.pViewportState      = &viewportState;
            pipelineCreateInfo.pDepthStencilState  = &depthStencilState;
            pipelineCreateInfo.pDynamicState       = &dynamicState;
            pipelineCreateInfo.stageCount          = shaderStages.Count;
            pipelineCreateInfo.pStages             = (VkPipelineShaderStageCreateInfo *)Unsafe.AsPointer(ref shaderStages);

            // Shared vertex bindings and attributes used by all pipelines

            // Binding description
            VkVertexInputBindingDescription vertexInputBindings
                = Initializers.vertexInputBindingDescription(VERTEX_BUFFER_BIND_ID, vertexLayout.GetStride(), VkVertexInputRate.Vertex);

            // Attribute descriptions
            FixedArray4 <VkVertexInputAttributeDescription> vertexInputAttributes = new FixedArray4 <VkVertexInputAttributeDescription>
            {
                First  = Initializers.vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 0, VkFormat.R32g32b32Sfloat, 0),                  // Location 0: Position
                Second = Initializers.vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 1, VkFormat.R32g32b32Sfloat, sizeof(float) * 3),  // Location 1: Color
                Third  = Initializers.vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 2, VkFormat.R32g32Sfloat, sizeof(float) * 6),     // Location 2 : Texture coordinates
                Fourth = Initializers.vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 3, VkFormat.R32g32b32Sfloat, sizeof(float) * 8),  // Location 3 : Normal
            };

            VkPipelineVertexInputStateCreateInfo vertexInputState = VkPipelineVertexInputStateCreateInfo.New();

            vertexInputState.vertexBindingDescriptionCount   = 1;
            vertexInputState.pVertexBindingDescriptions      = &vertexInputBindings;
            vertexInputState.vertexAttributeDescriptionCount = vertexInputAttributes.Count;
            vertexInputState.pVertexAttributeDescriptions    = (VkVertexInputAttributeDescription *)Unsafe.AsPointer(ref vertexInputAttributes);

            pipelineCreateInfo.pVertexInputState = &vertexInputState;

            // Create the graphics pipeline state objects

            // We are using this pipeline as the base for the other pipelines (derivatives)
            // Pipeline derivatives can be used for pipelines that share most of their state
            // Depending on the implementation this may result in better performance for pipeline
            // switchting and faster creation time
            pipelineCreateInfo.flags = VkPipelineCreateFlags.AllowDerivatives;

            // Textured pipeline
            // Phong shading pipeline
            shaderStages.First  = loadShader(getAssetPath() + "shaders/pipelines/phong.vert.spv", VkShaderStageFlags.Vertex);
            shaderStages.Second = loadShader(getAssetPath() + "shaders/pipelines/phong.frag.spv", VkShaderStageFlags.Fragment);
            Util.CheckResult(vkCreateGraphicsPipelines(Device, PipelineCache, 1, ref pipelineCreateInfo, null, out pipelines_phong));

            // All pipelines created after the base pipeline will be derivatives
            pipelineCreateInfo.flags = VkPipelineCreateFlags.Derivative;
            // Base pipeline will be our first created pipeline
            pipelineCreateInfo.basePipelineHandle = pipelines_phong;
            // It's only allowed to either use a handle or index for the base pipeline
            // As we use the handle, we must set the index to -1 (see section 9.5 of the specification)
            pipelineCreateInfo.basePipelineIndex = -1;

            // Toon shading pipeline
            shaderStages.First  = loadShader(getAssetPath() + "shaders/pipelines/toon.vert.spv", VkShaderStageFlags.Vertex);
            shaderStages.Second = loadShader(getAssetPath() + "shaders/pipelines/toon.frag.spv", VkShaderStageFlags.Fragment);
            Util.CheckResult(vkCreateGraphicsPipelines(Device, PipelineCache, 1, ref pipelineCreateInfo, null, out pipelines_toon));

            // Pipeline for wire frame rendering
            // Non solid rendering is not a mandatory Vulkan feature
            if (DeviceFeatures.fillModeNonSolid != 0)
            {
                rasterizationState.polygonMode = VkPolygonMode.Line;
                shaderStages.First             = loadShader(getAssetPath() + "shaders/pipelines/wireframe.vert.spv", VkShaderStageFlags.Vertex);
                shaderStages.Second            = loadShader(getAssetPath() + "shaders/pipelines/wireframe.frag.spv", VkShaderStageFlags.Fragment);
                Util.CheckResult(vkCreateGraphicsPipelines(Device, PipelineCache, 1, ref pipelineCreateInfo, null, out pipelines_wireframe));
            }
        }
Esempio n. 5
0
        protected void init(GraphicPipelineConfig cfg)
        {
            if (state != ActivableState.Activated)
            {
                Layout.Activate();
                RenderPass.Activate();
                Cache?.Activate();

                List <VkPipelineShaderStageCreateInfo> shaderStages = new List <VkPipelineShaderStageCreateInfo> ();
                foreach (ShaderInfo shader in cfg.shaders)
                {
                    shaderStages.Add(shader.GetStageCreateInfo(Dev));
                }

                VkPipelineColorBlendStateCreateInfo colorBlendInfo = VkPipelineColorBlendStateCreateInfo.New();
                colorBlendInfo.attachmentCount = (uint)cfg.blendAttachments.Count;
                colorBlendInfo.pAttachments    = cfg.blendAttachments.Pin();

                VkPipelineDynamicStateCreateInfo dynStatesInfo = VkPipelineDynamicStateCreateInfo.New();
                dynStatesInfo.dynamicStateCount = (uint)cfg.dynamicStates.Count;
                dynStatesInfo.pDynamicStates    = cfg.dynamicStates.Pin();

                VkPipelineVertexInputStateCreateInfo vertInputInfo = VkPipelineVertexInputStateCreateInfo.New();
                vertInputInfo.vertexBindingDescriptionCount   = (uint)cfg.vertexBindings.Count;
                vertInputInfo.pVertexBindingDescriptions      = cfg.vertexBindings.Pin();
                vertInputInfo.vertexAttributeDescriptionCount = (uint)cfg.vertexAttributes.Count;
                vertInputInfo.pVertexAttributeDescriptions    = cfg.vertexAttributes.Pin();

                VkGraphicsPipelineCreateInfo info = VkGraphicsPipelineCreateInfo.New();
                info.renderPass          = RenderPass.handle;
                info.layout              = Layout.handle;
                info.pVertexInputState   = vertInputInfo.Pin();
                info.pInputAssemblyState = cfg.inputAssemblyState.Pin();
                info.pRasterizationState = cfg.rasterizationState.Pin();
                info.pColorBlendState    = colorBlendInfo.Pin();
                info.pMultisampleState   = cfg.multisampleState.Pin();
                info.pViewportState      = cfg.viewportState.Pin();
                info.pDepthStencilState  = cfg.depthStencilState.Pin();
                info.pDynamicState       = dynStatesInfo.Pin();
                info.stageCount          = (uint)cfg.shaders.Count;
                info.pStages             = shaderStages.Pin();
                info.subpass             = cfg.SubpassIndex;

                Utils.CheckResult(vkCreateGraphicsPipelines(Dev.VkDev, Cache == null ? VkPipelineCache.Null : Cache.handle, 1, ref info, IntPtr.Zero, out handle));

                for (int i = 0; i < cfg.shaders.Count; i++)
                {
                    Dev.DestroyShaderModule(shaderStages[i].module);
                }

                vertInputInfo.Unpin();
                cfg.inputAssemblyState.Unpin();
                cfg.rasterizationState.Unpin();
                colorBlendInfo.Unpin();
                cfg.multisampleState.Unpin();
                cfg.viewportState.Unpin();
                cfg.depthStencilState.Unpin();
                dynStatesInfo.Unpin();
                shaderStages.Unpin();

                cfg.vertexAttributes.Unpin();
                cfg.vertexBindings.Unpin();
                cfg.dynamicStates.Unpin();
                cfg.blendAttachments.Unpin();
            }
            base.Activate();
        }
Esempio n. 6
0
        public VkPipeline(VkGraphicsDevice gd, ref PipelineDescription description)
        {
            _gd = gd;

            VkGraphicsPipelineCreateInfo pipelineCI = VkGraphicsPipelineCreateInfo.New();

            // Blend State
            VkPipelineColorBlendStateCreateInfo blendStateCI = VkPipelineColorBlendStateCreateInfo.New();
            int attachmentsCount = description.BlendState.AttachmentStates.Length;
            VkPipelineColorBlendAttachmentState *attachmentsPtr
                = stackalloc VkPipelineColorBlendAttachmentState[attachmentsCount];

            for (int i = 0; i < attachmentsCount; i++)
            {
                BlendAttachmentDescription          vdDesc          = description.BlendState.AttachmentStates[i];
                VkPipelineColorBlendAttachmentState attachmentState = new VkPipelineColorBlendAttachmentState();
                attachmentState.srcColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceColorFactor);
                attachmentState.dstColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationColorFactor);
                attachmentState.colorBlendOp        = VkFormats.VdToVkBlendOp(vdDesc.ColorFunction);
                attachmentState.srcAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceAlphaFactor);
                attachmentState.dstAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationAlphaFactor);
                attachmentState.alphaBlendOp        = VkFormats.VdToVkBlendOp(vdDesc.AlphaFunction);
                attachmentState.blendEnable         = vdDesc.BlendEnabled;
                attachmentState.colorWriteMask      = VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A;
                attachmentsPtr[i] = attachmentState;
            }

            blendStateCI.attachmentCount = (uint)attachmentsCount;
            blendStateCI.pAttachments    = attachmentsPtr;
            RgbaFloat blendFactor = description.BlendState.BlendFactor;

            blendStateCI.blendConstants_0 = blendFactor.R;
            blendStateCI.blendConstants_1 = blendFactor.G;
            blendStateCI.blendConstants_2 = blendFactor.B;
            blendStateCI.blendConstants_3 = blendFactor.A;

            pipelineCI.pColorBlendState = &blendStateCI;

            // Rasterizer State
            RasterizerStateDescription             rsDesc = description.RasterizerState;
            VkPipelineRasterizationStateCreateInfo rsCI   = VkPipelineRasterizationStateCreateInfo.New();

            rsCI.cullMode         = VkFormats.VdToVkCullMode(rsDesc.CullMode);
            rsCI.polygonMode      = VkFormats.VdToVkPolygonMode(rsDesc.FillMode);
            rsCI.depthClampEnable = !rsDesc.DepthClipEnabled;
            rsCI.frontFace        = VkFrontFace.Clockwise;
            rsCI.lineWidth        = 1f;

            pipelineCI.pRasterizationState = &rsCI;

            // Dynamic State
            VkPipelineDynamicStateCreateInfo dynamicStateCI = VkPipelineDynamicStateCreateInfo.New();
            VkDynamicState *dynamicStates = stackalloc VkDynamicState[2];

            dynamicStates[0] = VkDynamicState.Viewport;
            dynamicStates[1] = VkDynamicState.Scissor;
            dynamicStateCI.dynamicStateCount = 2;
            dynamicStateCI.pDynamicStates    = dynamicStates;

            pipelineCI.pDynamicState = &dynamicStateCI;

            // Depth Stencil State
            DepthStencilStateDescription          vdDssDesc = description.DepthStencilState;
            VkPipelineDepthStencilStateCreateInfo dssCI     = VkPipelineDepthStencilStateCreateInfo.New();

            dssCI.depthWriteEnable = vdDssDesc.DepthWriteEnabled;
            dssCI.depthTestEnable  = vdDssDesc.DepthTestEnabled;
            dssCI.depthCompareOp   = VkFormats.VdToVkCompareOp(vdDssDesc.ComparisonKind);

            pipelineCI.pDepthStencilState = &dssCI;

            // Multisample
            VkPipelineMultisampleStateCreateInfo multisampleCI = VkPipelineMultisampleStateCreateInfo.New();

            multisampleCI.rasterizationSamples = VkSampleCountFlags.Count1;

            pipelineCI.pMultisampleState = &multisampleCI;

            // Input Assembly
            VkPipelineInputAssemblyStateCreateInfo inputAssemblyCI = VkPipelineInputAssemblyStateCreateInfo.New();

            inputAssemblyCI.topology = VkFormats.VdToVkPrimitiveTopology(description.PrimitiveTopology);

            pipelineCI.pInputAssemblyState = &inputAssemblyCI;

            // Vertex Input State
            VkPipelineVertexInputStateCreateInfo vertexInputCI = VkPipelineVertexInputStateCreateInfo.New();

            VertexLayoutDescription[] inputDescriptions = description.ShaderSet.VertexLayouts;
            uint bindingCount   = (uint)inputDescriptions.Length;
            uint attributeCount = 0;

            for (int i = 0; i < inputDescriptions.Length; i++)
            {
                attributeCount += (uint)inputDescriptions[i].Elements.Length;
            }
            VkVertexInputBindingDescription *  bindingDescs   = stackalloc VkVertexInputBindingDescription[(int)bindingCount];
            VkVertexInputAttributeDescription *attributeDescs = stackalloc VkVertexInputAttributeDescription[(int)attributeCount];

            int targetIndex    = 0;
            int targetLocation = 0;

            for (int binding = 0; binding < inputDescriptions.Length; binding++)
            {
                VertexLayoutDescription inputDesc = inputDescriptions[binding];
                bindingDescs[targetIndex] = new VkVertexInputBindingDescription()
                {
                    binding   = (uint)binding,
                    inputRate = (inputDesc.Elements[0].InstanceStepRate != 0) ? VkVertexInputRate.Instance : VkVertexInputRate.Vertex,
                    stride    = inputDesc.Stride
                };

                uint currentOffset = 0;
                for (int location = 0; location < inputDesc.Elements.Length; location++)
                {
                    VertexElementDescription inputElement = inputDesc.Elements[location];

                    attributeDescs[targetIndex] = new VkVertexInputAttributeDescription()
                    {
                        format   = VkFormats.VdToVkVertexElementFormat(inputElement.Format),
                        binding  = (uint)binding,
                        location = (uint)(targetLocation + location),
                        offset   = currentOffset
                    };

                    targetIndex   += 1;
                    currentOffset += FormatHelpers.GetSizeInBytes(inputElement.Format);
                }

                targetLocation += inputDesc.Elements.Length;
            }

            vertexInputCI.vertexBindingDescriptionCount   = bindingCount;
            vertexInputCI.pVertexBindingDescriptions      = bindingDescs;
            vertexInputCI.vertexAttributeDescriptionCount = attributeCount;
            vertexInputCI.pVertexAttributeDescriptions    = attributeDescs;

            pipelineCI.pVertexInputState = &vertexInputCI;

            // Shader Stage
            ShaderStageDescription[] stageDescs = description.ShaderSet.ShaderStages;
            StackList <VkPipelineShaderStageCreateInfo> stages = new StackList <VkPipelineShaderStageCreateInfo>();

            foreach (ShaderStageDescription stageDesc in stageDescs)
            {
                VkShader vkShader = Util.AssertSubtype <Shader, VkShader>(stageDesc.Shader);
                VkPipelineShaderStageCreateInfo stageCI = VkPipelineShaderStageCreateInfo.New();
                stageCI.module = vkShader.ShaderModule;
                stageCI.stage  = VkFormats.VdToVkShaderStages(stageDesc.Stage);
                stageCI.pName  = CommonStrings.main; // Meh
                stages.Add(stageCI);
            }

            pipelineCI.stageCount = stages.Count;
            pipelineCI.pStages    = (VkPipelineShaderStageCreateInfo *)stages.Data;

            // ViewportState
            VkPipelineViewportStateCreateInfo viewportStateCI = VkPipelineViewportStateCreateInfo.New();

            viewportStateCI.viewportCount = 1;
            viewportStateCI.scissorCount  = 1;

            pipelineCI.pViewportState = &viewportStateCI;

            // Pipeline Layout
            ResourceLayout[]           resourceLayouts  = description.ResourceLayouts;
            VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New();

            pipelineLayoutCI.setLayoutCount = (uint)resourceLayouts.Length;
            VkDescriptorSetLayout *dsls = stackalloc VkDescriptorSetLayout[resourceLayouts.Length];

            for (int i = 0; i < resourceLayouts.Length; i++)
            {
                dsls[i] = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(resourceLayouts[i]).DescriptorSetLayout;
            }
            pipelineLayoutCI.pSetLayouts = dsls;

            vkCreatePipelineLayout(_gd.Device, ref pipelineLayoutCI, null, out _pipelineLayout);
            pipelineCI.layout = _pipelineLayout;

            // Create fake RenderPass for compatibility.
            VkRenderPassCreateInfo renderPassCI = VkRenderPassCreateInfo.New();
            OutputDescription      outputDesc   = description.Outputs;

            if (outputDesc.ColorAttachments.Length > 1)
            {
                throw new NotImplementedException("Laziness");
            }

            VkAttachmentDescription colorAttachmentDesc = new VkAttachmentDescription();

            colorAttachmentDesc.format = outputDesc.ColorAttachments.Length > 0
                ? VkFormats.VdToVkPixelFormat(outputDesc.ColorAttachments[0].Format) : 0;
            colorAttachmentDesc.samples        = VkSampleCountFlags.Count1;
            colorAttachmentDesc.loadOp         = VkAttachmentLoadOp.Clear;
            colorAttachmentDesc.storeOp        = VkAttachmentStoreOp.Store;
            colorAttachmentDesc.stencilLoadOp  = VkAttachmentLoadOp.DontCare;
            colorAttachmentDesc.stencilStoreOp = VkAttachmentStoreOp.DontCare;
            colorAttachmentDesc.initialLayout  = VkImageLayout.Undefined;
            colorAttachmentDesc.finalLayout    = VkImageLayout.PresentSrcKHR;

            VkAttachmentReference colorAttachmentRef = new VkAttachmentReference();

            colorAttachmentRef.attachment = 0;
            colorAttachmentRef.layout     = VkImageLayout.ColorAttachmentOptimal;

            VkAttachmentDescription depthAttachmentDesc = new VkAttachmentDescription();
            VkAttachmentReference   depthAttachmentRef  = new VkAttachmentReference();

            if (outputDesc.DepthAttachment != null)
            {
                depthAttachmentDesc.format         = VkFormats.VdToVkPixelFormat(outputDesc.DepthAttachment.Value.Format, toDepthFormat: true);
                depthAttachmentDesc.samples        = VkSampleCountFlags.Count1;
                depthAttachmentDesc.loadOp         = VkAttachmentLoadOp.Clear;
                depthAttachmentDesc.storeOp        = VkAttachmentStoreOp.Store;
                depthAttachmentDesc.stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                depthAttachmentDesc.stencilStoreOp = VkAttachmentStoreOp.DontCare;
                depthAttachmentDesc.initialLayout  = VkImageLayout.Undefined;
                depthAttachmentDesc.finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal;

                depthAttachmentRef.attachment = outputDesc.ColorAttachments.Length == 0 ? 0u : 1u;
                depthAttachmentRef.layout     = VkImageLayout.DepthStencilAttachmentOptimal;
            }

            VkSubpassDescription subpass = new VkSubpassDescription();
            StackList <VkAttachmentDescription, Size512Bytes> attachments = new StackList <VkAttachmentDescription, Size512Bytes>();

            subpass.pipelineBindPoint = VkPipelineBindPoint.Graphics;
            if (outputDesc.ColorAttachments.Length > 0)
            {
                subpass.colorAttachmentCount = 1;
                subpass.pColorAttachments    = &colorAttachmentRef;
                attachments.Add(colorAttachmentDesc);
            }

            if (outputDesc.DepthAttachment != null)
            {
                subpass.pDepthStencilAttachment = &depthAttachmentRef;
                attachments.Add(depthAttachmentDesc);
            }

            VkSubpassDependency subpassDependency = new VkSubpassDependency();

            subpassDependency.srcSubpass    = SubpassExternal;
            subpassDependency.srcStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite;
            if (outputDesc.DepthAttachment != null)
            {
                subpassDependency.dstAccessMask |= VkAccessFlags.DepthStencilAttachmentRead | VkAccessFlags.DepthStencilAttachmentWrite;
            }

            renderPassCI.attachmentCount = attachments.Count;
            renderPassCI.pAttachments    = (VkAttachmentDescription *)attachments.Data;
            renderPassCI.subpassCount    = 1;
            renderPassCI.pSubpasses      = &subpass;
            renderPassCI.dependencyCount = 1;
            renderPassCI.pDependencies   = &subpassDependency;

            VkResult creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPass);

            CheckResult(creationResult);

            pipelineCI.renderPass = _renderPass;

            VkResult result = vkCreateGraphicsPipelines(_gd.Device, VkPipelineCache.Null, 1, ref pipelineCI, null, out _devicePipeline);

            CheckResult(result);

            ResourceSetCount = (uint)description.ResourceLayouts.Length;
        }
Esempio n. 7
0
        public FGraphicsPipeline(VkDevice device, VkPhysicalDevice physicalDevice, VkPipelineCache pipelineCache, VkRenderPass renderPass,
                                 string shaderPath, uint swapchainImageCount, FTexture textureArray)
        {
            this.device = device;
            this.swapchainImageCount = swapchainImageCount;
            this.renderPass          = renderPass;

            desclayout     = CreateDescriptorLayout(device, 1);
            descriptorPool = CreateDescriptorPool(device, swapchainImageCount, 7);
            descriptorSets = AllocateDescriptorSets(device, desclayout, descriptorPool,
                                                    swapchainImageCount);

            sampler = CreateSampler(device, textureArray.MipLevels);
            for (int i = 0; i < swapchainImageCount; i++)
            {
                VkDescriptorImageInfo imageInfo = new VkDescriptorImageInfo();
                imageInfo.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
                imageInfo.imageView   = textureArray.imageView;
                imageInfo.sampler     = sampler;

                VkWriteDescriptorSet[] writes = new VkWriteDescriptorSet[1];
                writes[0].dstSet          = descriptorSets[i];
                writes[0].dstBinding      = 0;
                writes[0].dstArrayElement = 0;
                writes[0].descriptorType  = VkDescriptorType.CombinedImageSampler;
                writes[0].descriptorCount = 1;
                writes[0].pImageInfo      = &imageInfo;

                fixed(VkWriteDescriptorSet *ptr = writes)
                vkUpdateDescriptorSets(device, (uint)writes.Length, ptr, 0, null);
            }

            uniformdata = CreateUniformBuffer(device, physicalDevice, 1);

            VkShaderModule vs = LoadShader(device, $"{shaderPath}.vert.spv");
            VkShaderModule fs = LoadShader(device, $"{shaderPath}.frag.spv");


            VkGraphicsPipelineCreateInfo pCreateInfo = VkGraphicsPipelineCreateInfo.New();

            pCreateInfo.flags = VkPipelineCreateFlags.DisableOptimization;

            VkPipelineShaderStageCreateInfo[] shaderStages = new VkPipelineShaderStageCreateInfo[2];
            shaderStages[0]        = VkPipelineShaderStageCreateInfo.New();
            shaderStages[0].stage  = VkShaderStageFlags.Vertex;
            shaderStages[0].module = vs;

            byte[] vsFuncName = Encoding.UTF8.GetBytes("main" + char.MinValue);

            fixed(byte *ptr = &(vsFuncName[0]))
            shaderStages[0].pName = ptr;

            shaderStages[1]        = VkPipelineShaderStageCreateInfo.New();
            shaderStages[1].stage  = VkShaderStageFlags.Fragment;
            shaderStages[1].module = fs;
            byte[] fsFuncName = Encoding.UTF8.GetBytes("main" + char.MinValue);

            fixed(byte *ptr = &(fsFuncName[0]))
            shaderStages[1].pName = ptr;

            fixed(VkPipelineShaderStageCreateInfo *ptr = shaderStages)
            pCreateInfo.pStages = ptr;

            pCreateInfo.stageCount = 2;

            VkVertexInputBindingDescription[] bindings = new VkVertexInputBindingDescription[4];
            bindings[0]           = new VkVertexInputBindingDescription();
            bindings[0].binding   = 0;
            bindings[0].stride    = (uint)sizeof(VoxelRenderer.VoxelVertex);
            bindings[0].inputRate = VkVertexInputRate.Vertex;

            bindings[1]           = new VkVertexInputBindingDescription();
            bindings[1].binding   = 1;
            bindings[1].stride    = (uint)sizeof(VoxelRenderer.VoxelVertex);
            bindings[1].inputRate = VkVertexInputRate.Vertex;

            bindings[2]           = new VkVertexInputBindingDescription();
            bindings[2].binding   = 2;
            bindings[2].stride    = (uint)sizeof(VoxelRenderer.VoxelVertex);
            bindings[2].inputRate = VkVertexInputRate.Vertex;

            bindings[3]           = new VkVertexInputBindingDescription();
            bindings[3].binding   = 3;
            bindings[3].stride    = (uint)sizeof(VoxelRenderer.VoxelVertex);
            bindings[3].inputRate = VkVertexInputRate.Vertex;

            VkVertexInputAttributeDescription[] attribs = new VkVertexInputAttributeDescription[4];
            attribs[0].binding  = 0;
            attribs[0].location = 0;
            attribs[0].format   = VkFormat.R32g32b32Sfloat;
            attribs[0].offset   = 0;

            attribs[1].binding  = 1;
            attribs[1].location = 1;
            attribs[1].format   = VkFormat.R32g32b32Sfloat;
            attribs[1].offset   = 0;

            attribs[2].binding  = 2;
            attribs[2].location = 2;
            attribs[2].format   = VkFormat.R32g32b32Sfloat;
            attribs[2].offset   = 0;

            attribs[3].binding  = 3;
            attribs[3].location = 3;
            attribs[3].format   = VkFormat.R32Uint;
            attribs[3].offset   = 0;

            VkPipelineVertexInputStateCreateInfo vertexInput = VkPipelineVertexInputStateCreateInfo.New();

            fixed(VkVertexInputBindingDescription *ptr = bindings)
            vertexInput.pVertexBindingDescriptions = ptr;

            vertexInput.vertexBindingDescriptionCount = (uint)bindings.Length;

            fixed(VkVertexInputAttributeDescription *ptr = attribs)
            vertexInput.pVertexAttributeDescriptions = ptr;

            vertexInput.vertexAttributeDescriptionCount = (uint)attribs.Length;
            pCreateInfo.pVertexInputState = &vertexInput;

            VkPipelineInputAssemblyStateCreateInfo inputAssembly = VkPipelineInputAssemblyStateCreateInfo.New();

            inputAssembly.topology          = VkPrimitiveTopology.TriangleList;
            pCreateInfo.pInputAssemblyState = &inputAssembly;

            VkPipelineViewportStateCreateInfo viewportState = VkPipelineViewportStateCreateInfo.New();

            viewportState.viewportCount = 1;
            viewportState.scissorCount  = 1;
            pCreateInfo.pViewportState  = &viewportState;

            VkPipelineRasterizationStateCreateInfo rasterizationState = VkPipelineRasterizationStateCreateInfo.New();

            rasterizationState.lineWidth    = 1;
            rasterizationState.frontFace    = VkFrontFace.Clockwise;
            rasterizationState.cullMode     = VkCullModeFlags.Back;
            rasterizationState.polygonMode  = VkPolygonMode.Fill;//TODO add line debug render
            pCreateInfo.pRasterizationState = &rasterizationState;

            VkPipelineMultisampleStateCreateInfo multisampleState = VkPipelineMultisampleStateCreateInfo.New();

            multisampleState.rasterizationSamples = VkSampleCountFlags.Count1;
            pCreateInfo.pMultisampleState         = &multisampleState;

            VkPipelineDepthStencilStateCreateInfo depthState = VkPipelineDepthStencilStateCreateInfo.New();

            depthState.depthTestEnable     = VkBool32.True;
            depthState.depthWriteEnable    = VkBool32.True;
            depthState.depthCompareOp      = VkCompareOp.Less;
            pCreateInfo.pDepthStencilState = &depthState;

            VkPipelineColorBlendAttachmentState colourAttachment = new VkPipelineColorBlendAttachmentState();

            colourAttachment.colorWriteMask = VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A;

            VkPipelineColorBlendStateCreateInfo colourState = VkPipelineColorBlendStateCreateInfo.New();

            colourState.pAttachments     = &colourAttachment;
            colourState.attachmentCount  = 1;
            pCreateInfo.pColorBlendState = &colourState;

            VkDynamicState[] dynamicStates = new VkDynamicState[2];
            dynamicStates[0] = VkDynamicState.Viewport;
            dynamicStates[1] = VkDynamicState.Scissor;

            VkPipelineDynamicStateCreateInfo dynamicState = VkPipelineDynamicStateCreateInfo.New();

            dynamicState.dynamicStateCount = (uint)dynamicStates.Length;

            fixed(VkDynamicState *ptr = &(dynamicStates[0]))
            dynamicState.pDynamicStates = ptr;

            pCreateInfo.pDynamicState = &dynamicState;

            this.pipelineLayout    = CreatePipelineLayout(device, desclayout);
            pCreateInfo.layout     = this.pipelineLayout;
            pCreateInfo.renderPass = renderPass;
            pCreateInfo.subpass    = 0;


            VkPipeline pipeline = VkPipeline.Null;

            Assert(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pCreateInfo, null, &pipeline));
            this.pipeline = pipeline;
        }
        private VkPipeline CreateNewGraphicsPipeline(ref VkPipelineCacheKey cacheKey)
        {
            VkGraphicsPipelineCreateInfo pipelineCI = VkGraphicsPipelineCreateInfo.New();

            // RenderPass
            pipelineCI.renderPass = cacheKey.RenderPass;
            pipelineCI.subpass    = 0;

            pipelineCI.layout = cacheKey.PipelineLayout;

            // DynamicState
            VkPipelineDynamicStateCreateInfo dynamicStateCI = VkPipelineDynamicStateCreateInfo.New();
            VkDynamicState *dynamicStates = stackalloc VkDynamicState[2];

            dynamicStates[0] = VkDynamicState.Viewport;
            dynamicStates[1] = VkDynamicState.Scissor;
            dynamicStateCI.dynamicStateCount = 2;
            dynamicStateCI.pDynamicStates    = dynamicStates;
            pipelineCI.pDynamicState         = &dynamicStateCI;

            // ColorBlendState
            VkPipelineColorBlendAttachmentState colorBlendAttachementState = new VkPipelineColorBlendAttachmentState();

            colorBlendAttachementState.colorWriteMask      = VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A;
            colorBlendAttachementState.blendEnable         = cacheKey.BlendState.IsBlendEnabled;
            colorBlendAttachementState.srcColorBlendFactor = VkFormats.VeldridToVkBlendFactor(cacheKey.BlendState.SourceColorBlend);
            colorBlendAttachementState.dstColorBlendFactor = VkFormats.VeldridToVkBlendFactor(cacheKey.BlendState.DestinationColorBlend);
            colorBlendAttachementState.colorBlendOp        = VkFormats.VeldridToVkBlendOp(cacheKey.BlendState.ColorBlendFunction);
            colorBlendAttachementState.srcAlphaBlendFactor = VkFormats.VeldridToVkBlendFactor(cacheKey.BlendState.SourceAlphaBlend);
            colorBlendAttachementState.dstAlphaBlendFactor = VkFormats.VeldridToVkBlendFactor(cacheKey.BlendState.DestinationAlphaBlend);
            colorBlendAttachementState.alphaBlendOp        = VkFormats.VeldridToVkBlendOp(cacheKey.BlendState.AlphaBlendFunction);

            VkPipelineColorBlendStateCreateInfo colorBlendStateCI = VkPipelineColorBlendStateCreateInfo.New();

            if (cacheKey.Framebuffer.ColorTexture != null)
            {
                colorBlendStateCI.attachmentCount  = 1;
                colorBlendStateCI.pAttachments     = &colorBlendAttachementState;
                colorBlendStateCI.blendConstants_0 = cacheKey.BlendState.BlendFactor.R;
                colorBlendStateCI.blendConstants_1 = cacheKey.BlendState.BlendFactor.G;
                colorBlendStateCI.blendConstants_2 = cacheKey.BlendState.BlendFactor.B;
                colorBlendStateCI.blendConstants_3 = cacheKey.BlendState.BlendFactor.A;
                pipelineCI.pColorBlendState        = &colorBlendStateCI;
            }

            // DepthStencilState
            VkPipelineDepthStencilStateCreateInfo depthStencilStateCI = VkPipelineDepthStencilStateCreateInfo.New();

            depthStencilStateCI.depthCompareOp   = VkFormats.VeldridToVkDepthComparison(cacheKey.DepthStencilState.DepthComparison);
            depthStencilStateCI.depthWriteEnable = cacheKey.DepthStencilState.IsDepthWriteEnabled;
            depthStencilStateCI.depthTestEnable  = cacheKey.DepthStencilState.IsDepthEnabled;
            pipelineCI.pDepthStencilState        = &depthStencilStateCI;

            // MultisampleState
            VkPipelineMultisampleStateCreateInfo multisampleStateCI = VkPipelineMultisampleStateCreateInfo.New();

            multisampleStateCI.rasterizationSamples = VkSampleCountFlags.Count1;
            pipelineCI.pMultisampleState            = &multisampleStateCI;

            // RasterizationState
            VkPipelineRasterizationStateCreateInfo rasterizationStateCI = ((VkRasterizerState)cacheKey.RasterizerState).RasterizerStateCreateInfo;

            rasterizationStateCI.lineWidth = 1f;
            pipelineCI.pRasterizationState = &rasterizationStateCI;

            // ViewportState
            VkPipelineViewportStateCreateInfo viewportStateCI = VkPipelineViewportStateCreateInfo.New();

            viewportStateCI.viewportCount = 1;
            viewportStateCI.scissorCount  = 1;
            pipelineCI.pViewportState     = &viewportStateCI;

            // InputAssemblyState
            VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = VkPipelineInputAssemblyStateCreateInfo.New();

            inputAssemblyStateCI.topology  = cacheKey.PrimitiveTopology;
            pipelineCI.pInputAssemblyState = &inputAssemblyStateCI;

            // VertexInputState
            VkPipelineVertexInputStateCreateInfo vertexInputStateCI = VkPipelineVertexInputStateCreateInfo.New();

            VertexInputDescription[] inputDescriptions = cacheKey.ShaderSet.InputLayout.InputDescriptions;
            uint bindingCount   = (uint)inputDescriptions.Length;
            uint attributeCount = (uint)inputDescriptions.Sum(desc => desc.Elements.Length);
            VkVertexInputBindingDescription *  bindingDescs   = stackalloc VkVertexInputBindingDescription[(int)bindingCount];
            VkVertexInputAttributeDescription *attributeDescs = stackalloc VkVertexInputAttributeDescription[(int)attributeCount];

            int targetIndex    = 0;
            int targetLocation = 0;

            for (int binding = 0; binding < inputDescriptions.Length; binding++)
            {
                VertexInputDescription inputDesc = inputDescriptions[binding];
                bindingDescs[targetIndex] = new VkVertexInputBindingDescription()
                {
                    binding   = (uint)binding,
                    inputRate = (inputDesc.Elements[0].StorageClassifier == VertexElementInputClass.PerInstance) ? VkVertexInputRate.Instance : VkVertexInputRate.Vertex,
                    stride    = ((VkVertexBuffer)cacheKey.VertexBindings[binding]).Stride
                };

                uint currentOffset = 0;
                for (int location = 0; location < inputDesc.Elements.Length; location++)
                {
                    VertexInputElement inputElement = inputDesc.Elements[location];

                    attributeDescs[targetIndex] = new VkVertexInputAttributeDescription()
                    {
                        format   = VkFormats.VeldridToVkVertexElementFormat(inputElement.ElementFormat),
                        binding  = (uint)binding,
                        location = (uint)(targetLocation + location),
                        offset   = currentOffset
                    };

                    targetIndex   += 1;
                    currentOffset += inputElement.SizeInBytes;
                }

                targetLocation += inputDesc.Elements.Length;
            }

            vertexInputStateCI.vertexBindingDescriptionCount   = bindingCount;
            vertexInputStateCI.pVertexBindingDescriptions      = bindingDescs;
            vertexInputStateCI.vertexAttributeDescriptionCount = attributeCount;
            vertexInputStateCI.pVertexAttributeDescriptions    = attributeDescs;
            pipelineCI.pVertexInputState = &vertexInputStateCI;

            // ShaderStage
            StackList <VkPipelineShaderStageCreateInfo> shaderStageCIs = new StackList <VkPipelineShaderStageCreateInfo>();

            VkPipelineShaderStageCreateInfo vertexStage = VkPipelineShaderStageCreateInfo.New();

            vertexStage.stage  = VkShaderStageFlags.Vertex;
            vertexStage.module = cacheKey.ShaderSet.VertexShader.ShaderModule;
            vertexStage.pName  = CommonStrings.main;
            shaderStageCIs.Add(vertexStage);

            VkPipelineShaderStageCreateInfo fragmentStage = VkPipelineShaderStageCreateInfo.New();

            fragmentStage.stage  = VkShaderStageFlags.Fragment;
            fragmentStage.module = cacheKey.ShaderSet.FragmentShader.ShaderModule;
            fragmentStage.pName  = CommonStrings.main;
            shaderStageCIs.Add(fragmentStage);

            if (cacheKey.ShaderSet.TessellationControlShader != null)
            {
                VkPipelineShaderStageCreateInfo tcStage = VkPipelineShaderStageCreateInfo.New();
                tcStage.stage  = VkShaderStageFlags.TessellationControl;
                tcStage.module = cacheKey.ShaderSet.TessellationControlShader.ShaderModule;
                tcStage.pName  = CommonStrings.main;
                shaderStageCIs.Add(tcStage);
            }

            if (cacheKey.ShaderSet.TessellationEvaluationShader != null)
            {
                VkPipelineShaderStageCreateInfo teStage = VkPipelineShaderStageCreateInfo.New();
                teStage.stage  = VkShaderStageFlags.TessellationEvaluation;
                teStage.module = cacheKey.ShaderSet.TessellationEvaluationShader.ShaderModule;
                teStage.pName  = CommonStrings.main;
                shaderStageCIs.Add(teStage);
            }

            if (cacheKey.ShaderSet.GeometryShader != null)
            {
                VkPipelineShaderStageCreateInfo geometryStage = VkPipelineShaderStageCreateInfo.New();
                geometryStage.stage  = VkShaderStageFlags.Geometry;
                geometryStage.module = cacheKey.ShaderSet.GeometryShader.ShaderModule;
                geometryStage.pName  = CommonStrings.main;
                shaderStageCIs.Add(geometryStage);
            }

            pipelineCI.stageCount = shaderStageCIs.Count;
            pipelineCI.pStages    = (VkPipelineShaderStageCreateInfo *)shaderStageCIs.Data;

            VkResult result = vkCreateGraphicsPipelines(_device, VkPipelineCache.Null, 1, ref pipelineCI, null, out VkPipeline ret);

            CheckResult(result);
            return(ret);
        }
Esempio n. 9
0
        public void CreateGraphicsPipeline(string[] fileShaders, Framebuffer framebuffer)
        {
            VkShaderModule vertexShader   = NativeDevice.LoadSPIR_V_Shader(fileShaders[0], ShaderCompiler.ShaderCompiler.Stage.vertex_shader);
            VkShaderModule fragmentShader = NativeDevice.LoadSPIR_V_Shader(fileShaders[1], ShaderCompiler.ShaderCompiler.Stage.fragment_shader);

            VkPipelineShaderStageCreateInfo vertCreateInfo = new VkPipelineShaderStageCreateInfo()
            {
                sType  = VkStructureType.PipelineShaderStageCreateInfo,
                pNext  = null,
                stage  = VkShaderStageFlags.Vertex,
                module = vertexShader,
                pName  = Interop.String.ToPointer("main"),
            };


            VkPipelineShaderStageCreateInfo fragCreateInfo = new VkPipelineShaderStageCreateInfo
            {
                sType  = VkStructureType.PipelineShaderStageCreateInfo,
                pNext  = null,
                flags  = 0,
                stage  = VkShaderStageFlags.Fragment,
                module = fragmentShader,
                pName  = Interop.String.ToPointer("main"),
            };


            VkPipelineShaderStageCreateInfo *shaderStageCreateInfos = stackalloc VkPipelineShaderStageCreateInfo[2];

            shaderStageCreateInfos[0] = vertCreateInfo;
            shaderStageCreateInfos[1] = fragCreateInfo;

            VkPipelineVertexInputStateCreateInfo vertexInputStateCI = VkPipelineVertexInputStateCreateInfo.New();

            //var vertexBindingDesc = Vertex.GetBindingDescription();
            vertexInputStateCI.vertexBindingDescriptionCount = 0;
            //vertexInputStateCI.pVertexBindingDescriptions = Interop.Struct.AllocToPointer(ref vertexBindingDesc);


            vertexInputStateCI.vertexAttributeDescriptionCount = 0;
            //vertexInputStateCI.pVertexAttributeDescriptions = Interop.Struct.AllocToPointer(Vertex.GetAttributeDescriptions());
            //vertexInputStateCI.pVertexAttributeDescriptions = Interop.Struct.AllocToPointer(Vertex.GetAttributeDescriptions().AsSpan());

            VkPipelineInputAssemblyStateCreateInfo inputAssemblyCI = VkPipelineInputAssemblyStateCreateInfo.New();

            inputAssemblyCI.primitiveRestartEnable = false;
            inputAssemblyCI.topology = VkPrimitiveTopology.TriangleList;



            VkPipelineRasterizationStateCreateInfo rasterizerStateCI = VkPipelineRasterizationStateCreateInfo.New();

            rasterizerStateCI.cullMode    = VkCullModeFlags.None;
            rasterizerStateCI.polygonMode = VkPolygonMode.Fill;
            rasterizerStateCI.lineWidth   = 2.5f;
            rasterizerStateCI.frontFace   = VkFrontFace.CounterClockwise;

            VkPipelineMultisampleStateCreateInfo multisampleStateCI = VkPipelineMultisampleStateCreateInfo.New();

            multisampleStateCI.rasterizationSamples = VkSampleCountFlags.Count1;
            multisampleStateCI.minSampleShading     = 1f;

            VkPipelineColorBlendAttachmentState colorBlendAttachementState = new VkPipelineColorBlendAttachmentState();

            colorBlendAttachementState.colorWriteMask = VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A;
            colorBlendAttachementState.blendEnable    = false;

            VkPipelineColorBlendStateCreateInfo colorBlendStateCI = VkPipelineColorBlendStateCreateInfo.New();

            colorBlendStateCI.attachmentCount = 1;
            colorBlendStateCI.pAttachments    = &colorBlendAttachementState;

            //VkDescriptorSetLayout dsl = _descriptoSetLayout;
            VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New();

            pipelineLayoutCI.setLayoutCount = 0;
            //pipelineLayoutCI.pSetLayouts = &dsl;
            vkCreatePipelineLayout(NativeDevice.Device, ref pipelineLayoutCI, null, out pipelineLayout);

            VkGraphicsPipelineCreateInfo graphicsPipelineCI = VkGraphicsPipelineCreateInfo.New();

            graphicsPipelineCI.stageCount = 2;
            graphicsPipelineCI.pStages    = shaderStageCreateInfos;

            graphicsPipelineCI.pVertexInputState   = &vertexInputStateCI;
            graphicsPipelineCI.pInputAssemblyState = &inputAssemblyCI;
            graphicsPipelineCI.pRasterizationState = &rasterizerStateCI;
            graphicsPipelineCI.pMultisampleState   = &multisampleStateCI;
            graphicsPipelineCI.pColorBlendState    = &colorBlendStateCI;
            graphicsPipelineCI.layout     = pipelineLayout;
            graphicsPipelineCI.renderPass = framebuffer.NativeRenderPass;
            graphicsPipelineCI.subpass    = 0;

            vkCreateGraphicsPipelines(NativeDevice.Device, VkPipelineCache.Null, 1, ref graphicsPipelineCI, null, out graphicsPipeline);
        }