Beispiel #1
0
        private unsafe VkPipelineShaderStageCreateInfo[] CreateShaderStages(PipelineStateDescription pipelineStateDescription, out Dictionary <int, string> inputAttributeNames)
        {
            var stages       = pipelineStateDescription.EffectBytecode.Stages;
            var nativeStages = new VkPipelineShaderStageCreateInfo[stages.Length];

            inputAttributeNames = null;

            for (int i = 0; i < stages.Length; i++)
            {
                var shaderBytecode = BinarySerialization.Read <ShaderInputBytecode>(stages[i].Data);
                if (stages[i].Stage == ShaderStage.Vertex)
                    inputAttributeNames = shaderBytecode.InputAttributeNames;

                fixed(byte *entryPointPointer = &defaultEntryPoint[0])
                {
                    // Create stage
                    nativeStages[i] = new VkPipelineShaderStageCreateInfo
                    {
                        sType = VkStructureType.PipelineShaderStageCreateInfo,
                        stage = VulkanConvertExtensions.Convert(stages[i].Stage),
                        pName = entryPointPointer,
                    };
                    vkCreateShaderModule(GraphicsDevice.NativeDevice, shaderBytecode.Data, null, out nativeStages[i].module);
                }
            }
            ;

            return(nativeStages);
        }
Beispiel #2
0
        private void Vkctrl_VulkanInitialized(object sender, SharpVulkanWpf.VulkanEventArgs args)
        {
            var device = args.Device;
            var commandPoolCreateInfo = new VkCommandPoolCreateInfo()
            {
                queueFamilyIndex = args.GraphicsQueueIndex,
                flags            = VkCommandPoolCreateFlags.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
            };

            VulkanAPI.vkCreateCommandPool(device, ref commandPoolCreateInfo, out m_commandPool);

            var allocateInfo = new VkCommandBufferAllocateInfo()
            {
                commandBufferCount = 1,
                commandPool        = m_commandPool,
            };

            VulkanAPI.vkAllocateCommandBuffers(device, ref allocateInfo, out m_commandBuffers);

            // 頂点入力情報の構築.
            m_vertexInputState = CreateVertexInputState();
            // プリミティブの情報 トライアングルリストでデータが生成されている.
            m_inputAssemblyState = new VkPipelineInputAssemblyStateCreateInfo()
            {
                topology = VkPrimitiveTopology.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
            };
            // シェーダーステージ情報の構築.
            m_shaderStages = new VkPipelineShaderStageCreateInfo[2]
            {
                SampleHelpers.CreateShader(device, "resource/simpleVS.spv", VkShaderStageFlagBits.VK_SHADER_STAGE_VERTEX_BIT),
                SampleHelpers.CreateShader(device, "resource/simpleFS.spv", VkShaderStageFlagBits.VK_SHADER_STAGE_FRAGMENT_BIT),
            };
            // ラスタライザーステートの構築.
            m_rasterizationState = new VkPipelineRasterizationStateCreateInfo();
            // デプスステンシルステートの構築.
            m_depthStencilState = new VkPipelineDepthStencilStateCreateInfo();
            // カラーブレンドステートの構築.
            m_colorBlendState = new VkPipelineColorBlendStateCreateInfo();
            var colorBlendAttachment = new VkPipelineColorBlendAttachmentState();

            m_colorBlendState.attachments = new[] { colorBlendAttachment };

            // マルチサンプルステートの構築.
            m_multisampleState = new VkPipelineMultisampleStateCreateInfo();

            // パイプラインレイアウトの構築.
            m_pipelineLayout = CreatePipelineLayout(device);

            // ビューポートステートの構築.
            m_viewportState = CreateViewportState();

            // グラフィックスパイプラインを構築.
            m_graphicsPipeline = CreateGraphicsPipeline(device, vkctrl.GetControlRenderPass());

            // 頂点バッファの作成.
            CreateVertexBuffer(device, args.PhysicalDevice);
        }
Beispiel #3
0
        public VkPipelineShaderStageCreateInfo GetVertPipeline()
        {
            VkPipelineShaderStageCreateInfo shaderStage = VkPipelineShaderStageCreateInfo.New();

            shaderStage.stage  = VkShaderStageFlags.Vertex;
            shaderStage.module = vkVert;
            shaderStage.pName  = entryPoint;
            Debug.Assert(shaderStage.module.Handle != 0);
            return(shaderStage);
        }
Beispiel #4
0
        protected VkPipelineShaderStageCreateInfo loadShader(string fileName, VkShaderStageFlags stage)
        {
            VkPipelineShaderStageCreateInfo shaderStage = VkPipelineShaderStageCreateInfo.New();

            shaderStage.stage  = stage;
            shaderStage.module = Tools.loadShader(fileName, device, stage);
            shaderStage.pName  = Strings.main; // todo : make param
            Debug.Assert(shaderStage.module.Handle != 0);
            shaderModules.Add(shaderStage.module);
            return(shaderStage);
        }
        public static CompiledShaderModule Compile(VkPipelineShaderStageCreateInfo stageCreateInfo)
        {
            SoftwareShaderModule module = (SoftwareShaderModule)stageCreateInfo.module;
            string entryPointName       = stageCreateInfo.pName;

            CompiledShaderModule ret = new CompiledShaderModule();

            ret.instance   = module.GetNewInstance();
            ret.entryPoint = IntrospectionUtil.GetMethodCallExpression(ret.instance, entryPointName);
            return(ret);
        }
Beispiel #6
0
        protected VkPipelineShaderStageCreateInfo loadShader(string fileName, VkShaderStageFlagBits stage)
        {
            VkPipelineShaderStageCreateInfo shaderStage = new VkPipelineShaderStageCreateInfo();

            shaderStage.sType  = PipelineShaderStageCreateInfo;
            shaderStage.stage  = stage;
            shaderStage.module = Tools.loadShader(fileName, device, stage);
            shaderStage.pName  = Strings.main;
            Debug.Assert(shaderStage.module.handle != 0);
            shaderModules.Add(shaderStage.module);
            return(shaderStage);
        }
Beispiel #7
0
        public VkPipeline(VkGraphicsDevice gd, ref ComputePipelineDescription description)
            : base(ref description)
        {
            _gd = gd;
            IsComputePipeline = true;

            VkComputePipelineCreateInfo pipelineCI = VkComputePipelineCreateInfo.New();

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

            // Shader Stage
            Shader   shader   = description.ComputeShader;
            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
            pipelineCI.stage = stageCI;

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

            CheckResult(result);

            ResourceSetCount = (uint)description.ResourceLayouts.Length;
        }
Beispiel #8
0
            internal ShaderStageBuilder(GraphicsPipelineBuilder builder, VkShaderModule handle,
                                        VkShaderStageFlag stage, string entryPoint)
            {
                _builder = builder;
                unsafe
                {
                    _shaderInfo = new VkPipelineShaderStageCreateInfo()
                    {
                        SType  = VkStructureType.PipelineShaderStageCreateInfo,
                        PNext  = IntPtr.Zero,
                        Module = handle,
                        Flags  = 0,
                        Stage  = stage,
                        PSpecializationInfo = (VkSpecializationInfo *)0
                    };
                }

                _entryPoint = entryPoint;
            }
        internal VkPipelineShaderStageCreateInfo GetNative(DisposableList <IDisposable> marshalled)
        {
            var result = new VkPipelineShaderStageCreateInfo();

            result.sType  = VkStructureType.PipelineShaderStageCreateInfo;
            result.stage  = stage;
            result.module = module.Native;

            var strInterop = new InteropString(name);

            result.pName = strInterop.Address;
            marshalled.Add(strInterop);

            if (specializationInfo != null)
            {
                result.pSpecializationInfo = specializationInfo.GetNative(marshalled);
            }

            return(result);
        }
        /// <summary>
        /// SPVシェーダーファイルを読み込んで VkPipelineShaderStageCreateInfo を作成します.
        /// </summary>
        /// <param name="device"></param>
        /// <param name="shaderFile"></param>
        /// <param name="stageFlag"></param>
        /// <returns></returns>
        public static VkPipelineShaderStageCreateInfo CreateShader(VkDevice device, string shaderFile, VkShaderStageFlagBits stageFlag)
        {
            var stageCreateInfo = new VkPipelineShaderStageCreateInfo();

            using (var fs = new FileStream(shaderFile, FileMode.Open, FileAccess.Read))
            {
                var code = new byte[fs.Length];
                fs.Read(code, 0, (int)fs.Length);

                var shaderModuleCreateInfo = new VkShaderModuleCreateInfo()
                {
                    shaderCodeBinary = code,
                };

                VkShaderModule shaderModule;
                VulkanAPI.vkCreateShaderModule(device, ref shaderModuleCreateInfo, out shaderModule);

                stageCreateInfo.flags  = 0;
                stageCreateInfo.stage  = stageFlag;
                stageCreateInfo.pName  = "main";
                stageCreateInfo.module = shaderModule;
            }
            return(stageCreateInfo);
        }
Beispiel #11
0
        private void CreateGraphicsPipeline()
        {
            byte[] vertShaderCode = File.ReadAllBytes("Shaders/vert.spv");
            byte[] fragShaderCode = File.ReadAllBytes("Shaders/frag.spv");

            VkShaderModule vertShaderModule = this.CreateShaderModule(vertShaderCode);
            VkShaderModule fragShaderModule = this.CreateShaderModule(fragShaderCode);

            VkPipelineShaderStageCreateInfo vertShaderStageInfo = new VkPipelineShaderStageCreateInfo()
            {
                sType  = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
                stage  = VkShaderStageFlags.VK_SHADER_STAGE_VERTEX_BIT,
                module = vertShaderModule,
                pName  = "main".ToPointer(),
            };

            VkPipelineShaderStageCreateInfo fragShaderStageInfo = new VkPipelineShaderStageCreateInfo()
            {
                sType  = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
                stage  = VkShaderStageFlags.VK_SHADER_STAGE_FRAGMENT_BIT,
                module = fragShaderModule,
                pName  = "main".ToPointer(),
            };

            VkPipelineShaderStageCreateInfo *shaderStages = stackalloc VkPipelineShaderStageCreateInfo[] { vertShaderStageInfo, fragShaderStageInfo };

            // Vertex Input
            VkPipelineVertexInputStateCreateInfo vertexInputInfo = new VkPipelineVertexInputStateCreateInfo()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
                vertexBindingDescriptionCount   = 0,
                pVertexBindingDescriptions      = null, // Optional
                vertexAttributeDescriptionCount = 0,
                pVertexAttributeDescriptions    = null, // Optional
            };

            // Input assembly
            VkPipelineInputAssemblyStateCreateInfo inputAssembly = new VkPipelineInputAssemblyStateCreateInfo()
            {
                sType    = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
                topology = VkPrimitiveTopology.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
                primitiveRestartEnable = false,
            };

            // Viewports and scissors
            VkViewport viewport = new VkViewport()
            {
                x        = 0.0f,
                y        = 0.0f,
                width    = (float)swapChainExtent.width,
                height   = (float)swapChainExtent.height,
                minDepth = 0.0f,
                maxDepth = 1.0f,
            };

            VkRect2D scissor = new VkRect2D()
            {
                offset = new VkOffset2D(0, 0),
                extent = swapChainExtent,
            };

            VkPipelineViewportStateCreateInfo viewportState = new VkPipelineViewportStateCreateInfo()
            {
                sType         = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
                viewportCount = 1,
                pViewports    = &viewport,
                scissorCount  = 1,
                pScissors     = &scissor,
            };

            // Rasterizer
            VkPipelineRasterizationStateCreateInfo rasterizer = new VkPipelineRasterizationStateCreateInfo()
            {
                sType                   = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
                depthClampEnable        = false,
                rasterizerDiscardEnable = false,
                polygonMode             = VkPolygonMode.VK_POLYGON_MODE_FILL,
                lineWidth               = 1.0f,
                cullMode                = VkCullModeFlags.VK_CULL_MODE_BACK_BIT,
                frontFace               = VkFrontFace.VK_FRONT_FACE_CLOCKWISE,
                depthBiasEnable         = false,
                depthBiasConstantFactor = 0.0f, // Optional
                depthBiasClamp          = 0.0f, // Optional
                depthBiasSlopeFactor    = 0.0f, // Optional
            };

            VkPipelineMultisampleStateCreateInfo multisampling = new VkPipelineMultisampleStateCreateInfo()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
                sampleShadingEnable   = false,
                rasterizationSamples  = VkSampleCountFlags.VK_SAMPLE_COUNT_1_BIT,
                minSampleShading      = 1.0f,  // Optional
                pSampleMask           = null,  // Optional
                alphaToCoverageEnable = false, // Optional
                alphaToOneEnable      = false, // Optional
            };

            // Depth and Stencil testing
            //VkPipelineDepthStencilStateCreateInfo

            // Color blending
            VkPipelineColorBlendAttachmentState colorBlendAttachment = new VkPipelineColorBlendAttachmentState()
            {
                colorWriteMask = VkColorComponentFlags.VK_COLOR_COMPONENT_R_BIT |
                                 VkColorComponentFlags.VK_COLOR_COMPONENT_G_BIT |
                                 VkColorComponentFlags.VK_COLOR_COMPONENT_B_BIT |
                                 VkColorComponentFlags.VK_COLOR_COMPONENT_A_BIT,
                blendEnable         = false,
                srcColorBlendFactor = VkBlendFactor.VK_BLEND_FACTOR_ONE,  // Optional
                dstColorBlendFactor = VkBlendFactor.VK_BLEND_FACTOR_ZERO, // Optional
                colorBlendOp        = VkBlendOp.VK_BLEND_OP_ADD,          // Optional
                srcAlphaBlendFactor = VkBlendFactor.VK_BLEND_FACTOR_ONE,  // Optional
                dstAlphaBlendFactor = VkBlendFactor.VK_BLEND_FACTOR_ZERO, // Optional
                alphaBlendOp        = VkBlendOp.VK_BLEND_OP_ADD,          // Optional
            };

            VkPipelineColorBlendStateCreateInfo colorBlending = new VkPipelineColorBlendStateCreateInfo()
            {
                sType            = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
                logicOpEnable    = false,
                logicOp          = VkLogicOp.VK_LOGIC_OP_COPY, // Optional
                attachmentCount  = 1,
                pAttachments     = &colorBlendAttachment,
                blendConstants_0 = 0.0f, // Optional
                blendConstants_1 = 0.0f, // Optional
                blendConstants_2 = 0.0f, // Optional
                blendConstants_3 = 0.0f, // Optional
            };

            VkPipelineLayoutCreateInfo pipelineLayoutInfo = new VkPipelineLayoutCreateInfo()
            {
                sType                  = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
                setLayoutCount         = 0,    // Optional
                pSetLayouts            = null, // Optional
                pushConstantRangeCount = 0,    // Optional
                pPushConstantRanges    = null, // Optional
            };

            fixed(VkPipelineLayout *pipelineLayoutPtr = &pipelineLayout)
            {
                Helpers.CheckErrors(VulkanNative.vkCreatePipelineLayout(device, &pipelineLayoutInfo, null, pipelineLayoutPtr));
            }

            VkGraphicsPipelineCreateInfo pipelineInfo = new VkGraphicsPipelineCreateInfo()
            {
                sType               = VkStructureType.VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
                stageCount          = 2,
                pStages             = shaderStages,
                pVertexInputState   = &vertexInputInfo,
                pInputAssemblyState = &inputAssembly,
                pViewportState      = &viewportState,
                pRasterizationState = &rasterizer,
                pMultisampleState   = &multisampling,
                pDepthStencilState  = null, // Optional
                pColorBlendState    = &colorBlending,
                pDynamicState       = null, // Optional
                layout              = this.pipelineLayout,
                renderPass          = this.renderPass,
                subpass             = 0,
                basePipelineHandle  = 0,  // Optional
                basePipelineIndex   = -1, // Optional
            };

            fixed(VkPipeline *graphicsPipelinePtr = &this.graphicsPipeline)
            {
                Helpers.CheckErrors(VulkanNative.vkCreateGraphicsPipelines(this.device, 0, 1, &pipelineInfo, null, graphicsPipelinePtr));
            }

            VulkanNative.vkDestroyShaderModule(device, fragShaderModule, null);
            VulkanNative.vkDestroyShaderModule(device, vertShaderModule, null);
        }
        void preparePipelines()
        {
            var inputAssemblyState = new VkPipelineInputAssemblyStateCreateInfo();

            inputAssemblyState.sType    = PipelineInputAssemblyStateCreateInfo;
            inputAssemblyState.topology = VkPrimitiveTopology.TriangleList;
            inputAssemblyState.primitiveRestartEnable = false;

            var rasterizationState = new VkPipelineRasterizationStateCreateInfo();

            rasterizationState.sType       = PipelineRasterizationStateCreateInfo;
            rasterizationState.polygonMode = VkPolygonMode.Fill;
            rasterizationState.cullMode    = VkCullModeFlagBits.None;
            rasterizationState.frontFace   = VkFrontFace.CounterClockwise;

            var blendAttachmentState = new VkPipelineColorBlendAttachmentState(
                (VkColorComponentFlagBits)0xf, false);

            var colorBlendState = new VkPipelineColorBlendStateCreateInfo();

            colorBlendState.sType       = PipelineColorBlendStateCreateInfo;
            colorBlendState.attachments = blendAttachmentState;

            var depthStencilState = new VkPipelineDepthStencilStateCreateInfo();

            depthStencilState.sType            = PipelineDepthStencilStateCreateInfo;
            depthStencilState.depthTestEnable  = true;
            depthStencilState.depthWriteEnable = true;
            depthStencilState.depthCompareOp   = VkCompareOp.LessOrEqual;

            var viewportState = new VkPipelineViewportStateCreateInfo();

            viewportState.sType           = PipelineViewportStateCreateInfo;
            viewportState.viewports.count = 1;
            viewportState.scissors.count  = 1;

            var multisampleState = new VkPipelineMultisampleStateCreateInfo();

            multisampleState.sType = PipelineMultisampleStateCreateInfo;
            multisampleState.rasterizationSamples = VkSampleCountFlagBits._1;

            var dynamicStateEnables = new VkDynamicState[] {
                VkDynamicState.Viewport,
                VkDynamicState.Scissor,
            };

            var dynamicState = new VkPipelineDynamicStateCreateInfo();

            dynamicState.sType         = PipelineDynamicStateCreateInfo;
            dynamicState.dynamicStates = dynamicStateEnables;

            // Load shaders
            var shaderStages = new VkPipelineShaderStageCreateInfo[] {
                loadShader(getAssetPath() + "shaders/dynamicuniformbuffer/base.vert.spv", VkShaderStageFlagBits.Vertex),
                loadShader(getAssetPath() + "shaders/dynamicuniformbuffer/base.frag.spv", VkShaderStageFlagBits.Fragment)
            };

            var info = new VkGraphicsPipelineCreateInfo();

            info.sType               = GraphicsPipelineCreateInfo;
            info.layout              = pipelineLayout;
            info.renderPass          = renderPass;
            info.pVertexInputState   = vertices_inputState;
            info.pInputAssemblyState = &inputAssemblyState;
            info.pRasterizationState = &rasterizationState;
            info.pColorBlendState    = &colorBlendState;
            info.pMultisampleState   = &multisampleState;
            info.pViewportState      = &viewportState;
            info.pDepthStencilState  = &depthStencilState;
            info.pDynamicState       = &dynamicState;
            info.stages              = shaderStages;

            VkPipeline pipeline;

            vkCreateGraphicsPipelines(device, pipelineCache, 1, &info, null, &pipeline);
            this.pipeline = pipeline;
        }
        private VkPipeline CreateVulkanPipeline()
        {
            var  pipelineShaderStageCreateInfos      = stackalloc VkPipelineShaderStageCreateInfo[2];
            uint pipelineShaderStageCreateInfosCount = 0;

            try
            {
                VkPipeline vulkanPipeline;

                var device  = Device;
                var surface = device.Surface;

                var vertexInputBindingDescription = new VkVertexInputBindingDescription {
                    inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
                };

                var vertexInputAttributeDescriptions = Array.Empty <VkVertexInputAttributeDescription>();

                var pipelineVertexInputStateCreateInfo = new VkPipelineVertexInputStateCreateInfo {
                    sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
                    vertexBindingDescriptionCount = 1,
                    pVertexBindingDescriptions    = &vertexInputBindingDescription,
                };

                var pipelineInputAssemblyStateCreateInfo = new VkPipelineInputAssemblyStateCreateInfo {
                    sType    = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
                    topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
                };

                var pipelineViewportStateCreateInfo = new VkPipelineViewportStateCreateInfo {
                    sType         = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
                    viewportCount = 1,
                    scissorCount  = 1,
                };

                var pipelineRasterizationStateCreateInfo = new VkPipelineRasterizationStateCreateInfo {
                    sType     = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
                    frontFace = VK_FRONT_FACE_CLOCKWISE,
                    cullMode  = VK_CULL_MODE_BACK_BIT,
                    lineWidth = 1.0f,
                };

                var pipelineMultisampleStateCreateInfo = new VkPipelineMultisampleStateCreateInfo {
                    sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
                    rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
                };

                var pipelineDepthStencilStateCreateInfo = new VkPipelineDepthStencilStateCreateInfo {
                    sType          = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
                    depthCompareOp = VK_COMPARE_OP_ALWAYS,
                    front          = new VkStencilOpState {
                        compareOp = VK_COMPARE_OP_ALWAYS,
                    },
                    back = new VkStencilOpState {
                        compareOp = VK_COMPARE_OP_ALWAYS,
                    },
                };

                var pipelineColorBlendAttachmentState = new VkPipelineColorBlendAttachmentState {
                    colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_R_BIT,
                };

                var pipelineColorBlendStateCreateInfo = new VkPipelineColorBlendStateCreateInfo {
                    sType           = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
                    attachmentCount = 1,
                    pAttachments    = &pipelineColorBlendAttachmentState,
                };

                var dynamicStates = stackalloc VkDynamicState[2] {
                    VK_DYNAMIC_STATE_VIEWPORT,
                    VK_DYNAMIC_STATE_SCISSOR,
                };

                var pipelineDynamicStateCreateInfo = new VkPipelineDynamicStateCreateInfo {
                    sType             = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
                    dynamicStateCount = 2,
                    pDynamicStates    = dynamicStates,
                };

                var pipelineCreateInfo = new VkGraphicsPipelineCreateInfo {
                    sType               = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
                    pViewportState      = &pipelineViewportStateCreateInfo,
                    pRasterizationState = &pipelineRasterizationStateCreateInfo,
                    pMultisampleState   = &pipelineMultisampleStateCreateInfo,
                    pDepthStencilState  = &pipelineDepthStencilStateCreateInfo,
                    pColorBlendState    = &pipelineColorBlendStateCreateInfo,
                    pDynamicState       = &pipelineDynamicStateCreateInfo,
                    layout              = Signature.VulkanPipelineLayout,
                    renderPass          = device.VulkanRenderPass,
                };

                var vertexShader = VertexShader;

                if (vertexShader != null)
                {
                    var shaderIndex = pipelineShaderStageCreateInfosCount++;

                    var entryPointName       = vertexShader.EntryPointName.GetUtf8Span();
                    var entryPointNameLength = (nuint)entryPointName.Length + 1;

                    pipelineShaderStageCreateInfos[shaderIndex] = new VkPipelineShaderStageCreateInfo {
                        sType  = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
                        stage  = VK_SHADER_STAGE_VERTEX_BIT,
                        module = vertexShader.VulkanShaderModule,
                        pName  = AllocateArray <sbyte>(entryPointNameLength),
                    };

                    var destination = new Span <sbyte>(pipelineShaderStageCreateInfos[shaderIndex].pName, (int)entryPointNameLength);
                    entryPointName.CopyTo(destination);
                    destination[entryPointName.Length] = 0x00;

                    var inputs       = Signature.Inputs;
                    var inputsLength = inputs.Length;

                    var inputElementsCount = GetInputElementsCount(inputs);
                    var inputElementsIndex = 0;

                    if (inputElementsCount != 0)
                    {
                        vertexInputAttributeDescriptions = new VkVertexInputAttributeDescription[inputElementsCount];

                        for (var inputIndex = 0; inputIndex < inputsLength; inputIndex++)
                        {
                            var input = inputs[inputIndex];

                            var inputElements       = input.Elements;
                            var inputElementsLength = inputElements.Length;

                            uint inputBindingStride = 0;

                            for (var inputElementIndex = 0; inputElementIndex < inputElementsLength; inputElementIndex++)
                            {
                                var inputElement = inputElements[inputElementIndex];

                                vertexInputAttributeDescriptions[inputElementsIndex] = new VkVertexInputAttributeDescription {
                                    location = unchecked ((uint)inputElementIndex),
                                    binding  = unchecked ((uint)inputIndex),
                                    format   = GetInputElementFormat(inputElement.Type),
                                    offset   = inputBindingStride,
                                };

                                inputBindingStride += inputElement.Size;
                                inputElementsIndex++;
                            }

                            vertexInputBindingDescription.stride = inputBindingStride;
                        }
                    }

                    pipelineCreateInfo.pVertexInputState   = &pipelineVertexInputStateCreateInfo;
                    pipelineCreateInfo.pInputAssemblyState = &pipelineInputAssemblyStateCreateInfo;
                }

                var pixelShader = PixelShader;

                if (pixelShader != null)
                {
                    var shaderIndex = pipelineShaderStageCreateInfosCount++;

                    var entryPointName       = pixelShader.EntryPointName.GetUtf8Span();
                    var entryPointNameLength = (nuint)entryPointName.Length + 1;

                    pipelineShaderStageCreateInfos[shaderIndex] = new VkPipelineShaderStageCreateInfo {
                        sType  = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
                        stage  = VK_SHADER_STAGE_FRAGMENT_BIT,
                        module = pixelShader.VulkanShaderModule,
                        pName  = AllocateArray <sbyte>(entryPointNameLength),
                    };

                    var destination = new Span <sbyte>(pipelineShaderStageCreateInfos[shaderIndex].pName, (int)entryPointNameLength);
                    entryPointName.CopyTo(destination);
                    destination[entryPointName.Length] = 0x00;
                }

                if (pipelineShaderStageCreateInfosCount != 0)
                {
                    pipelineCreateInfo.stageCount = pipelineShaderStageCreateInfosCount;
                    pipelineCreateInfo.pStages    = pipelineShaderStageCreateInfos;
                }

                fixed(VkVertexInputAttributeDescription *pVertexInputAttributeDescriptions = vertexInputAttributeDescriptions)
                {
                    pipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount = unchecked ((uint)vertexInputAttributeDescriptions.Length);
                    pipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions    = pVertexInputAttributeDescriptions;

                    ThrowExternalExceptionIfNotSuccess(vkCreateGraphicsPipelines(device.VulkanDevice, pipelineCache: VK_NULL_HANDLE, 1, &pipelineCreateInfo, pAllocator: null, (ulong *)&vulkanPipeline), nameof(vkCreateGraphicsPipelines));
                }

                return(vulkanPipeline);
            }
            finally
            {
                for (uint index = 0; index < pipelineShaderStageCreateInfosCount; index++)
                {
                    var entryPointName = pipelineShaderStageCreateInfos[index].pName;
                    Free(entryPointName);
                }
            }
        public void Build(int deviceIndex)
        {
            if (!locked)
            {
                unsafe
                {
                    //create pipeline shader stages
                    var shaderStages                   = new VkPipelineShaderStageCreateInfo[Shaders.Length];
                    var shaderSpecializations          = new ManagedPtr <VkSpecializationInfo> [Shaders.Length];
                    var shaderSpecializationBufferPtrs = new MemoryHandle[Shaders.Length];
                    for (int i = 0; i < shaderStages.Length; i++)
                    {
                        if (SpecializationData != null)
                        {
                            shaderSpecializationBufferPtrs[i] = SpecializationData[i].Pin();

                            shaderSpecializations[i] = new VkSpecializationInfo()
                            {
                                mapEntryCount = (uint)SpecializationData[i].Length,
                                pMapEntries   = Shaders[i].Specialize(),
                                dataSize      = (uint)SpecializationData[i].Length * sizeof(int),
                                pData         = (IntPtr)shaderSpecializationBufferPtrs[i].Pointer
                            }.Pointer();
                        }

                        shaderStages[i].sType  = VkStructureType.StructureTypePipelineShaderStageCreateInfo;
                        shaderStages[i].stage  = (VkShaderStageFlags)Shaders[i].ShaderType;
                        shaderStages[i].module = Shaders[i].ids[deviceIndex];
                        shaderStages[i].pName  = "main";
                        shaderStages[i].pSpecializationInfo = shaderSpecializations[i] != null ? shaderSpecializations[i] : IntPtr.Zero;
                    }
                    var shaderStages_ptr = shaderStages.Pointer();

                    //VkPipelineVertexInputStateCreateInfo - dummy, engine doesn't support fix function vertex input
                    var vertexInputInfo = new VkPipelineVertexInputStateCreateInfo()
                    {
                        sType = VkStructureType.StructureTypePipelineVertexInputStateCreateInfo,
                        vertexBindingDescriptionCount   = 0,
                        vertexAttributeDescriptionCount = 0,
                    };
                    var vertexInputInfo_ptr = vertexInputInfo.Pointer();

                    //VkPipelineInputAssemblyStateCreateInfo - state
                    var inputAssembly = new VkPipelineInputAssemblyStateCreateInfo()
                    {
                        sType    = VkStructureType.StructureTypePipelineInputAssemblyStateCreateInfo,
                        topology = (VkPrimitiveTopology)Topology,
                        primitiveRestartEnable = false,
                    };
                    var inputAssembly_ptr = inputAssembly.Pointer();

                    //VkPipelineViewportStateCreateInfo - dynamic state, no scissor
                    var viewport = new VkViewport()
                    {
                        x        = ViewportX,
                        y        = ViewportY,
                        width    = ViewportWidth,
                        height   = ViewportHeight,
                        minDepth = ViewportMinDepth,
                        maxDepth = ViewportMaxDepth,
                    };

                    var scissor = new VkRect2D()
                    {
                        offset = new VkOffset2D()
                        {
                            x = (int)ViewportX,
                            y = (int)ViewportY
                        },
                        extent = new VkExtent2D()
                        {
                            width  = ViewportWidth,
                            height = ViewportHeight
                        }
                    };

                    var viewport_ptr       = viewport.Pointer();
                    var scissor_ptr        = scissor.Pointer();
                    var viewportCreateInfo = new VkPipelineViewportStateCreateInfo()
                    {
                        sType         = VkStructureType.StructureTypePipelineViewportStateCreateInfo,
                        viewportCount = 1,
                        pViewports    = viewport_ptr,
                        scissorCount  = 1,
                        pScissors     = scissor_ptr
                    };
                    var viewportCreateInfo_ptr = viewportCreateInfo.Pointer();

                    //VkPipelineRasterizationStateCreateInfo - state
                    var rasterizer = new VkPipelineRasterizationStateCreateInfo()
                    {
                        sType                   = VkStructureType.StructureTypePipelineRasterizationStateCreateInfo,
                        depthClampEnable        = DepthClamp,
                        rasterizerDiscardEnable = RasterizerDiscard,
                        polygonMode             = (VkPolygonMode)Fill,
                        lineWidth               = LineWidth,
                        cullMode                = (VkCullModeFlags)CullMode,
                        frontFace               = VkFrontFace.FrontFaceCounterClockwise, //OpenGL default
                        depthBiasEnable         = false,
                        depthBiasConstantFactor = 0,
                        depthBiasClamp          = 0,
                        depthBiasSlopeFactor    = 0,
                    };
                    var rasterizer_ptr = rasterizer.Pointer();

                    //VkPipelineMultisampleStateCreateInfo - don't support for now
                    var multisampling = new VkPipelineMultisampleStateCreateInfo()
                    {
                        sType = VkStructureType.StructureTypePipelineMultisampleStateCreateInfo,
                        sampleShadingEnable   = false,
                        rasterizationSamples  = VkSampleCountFlags.SampleCount1Bit,
                        minSampleShading      = 1,
                        pSampleMask           = null,
                        alphaToCoverageEnable = false,
                        alphaToOneEnable      = false
                    };
                    var multisampling_ptr = multisampling.Pointer();

                    //VkPipelineDepthStencilStateCreateInfo - state
                    var depthStencil = new VkPipelineDepthStencilStateCreateInfo()
                    {
                        sType                 = VkStructureType.StructureTypePipelineDepthStencilStateCreateInfo,
                        depthTestEnable       = true,
                        depthCompareOp        = (VkCompareOp)DepthTest,
                        depthWriteEnable      = DepthWrite,
                        depthBoundsTestEnable = false,
                        stencilTestEnable     = false,
                        maxDepthBounds        = ViewportMaxDepth,
                        minDepthBounds        = ViewportMinDepth,
                    };
                    var depthStencil_ptr = depthStencil.Pointer();


                    //VkPipelineColorBlendStateCreateInfo - state
                    var colorBlendStates = new VkPipelineColorBlendAttachmentState[RenderPass.ColorAttachments == null ? 0 : RenderPass.ColorAttachments.Length];
                    for (int i = 0; i < colorBlendStates.Length; i++)
                    {
                        colorBlendStates[i] = new VkPipelineColorBlendAttachmentState()
                        {
                            colorWriteMask = VkColorComponentFlags.ColorComponentRBit | VkColorComponentFlags.ColorComponentGBit | VkColorComponentFlags.ColorComponentBBit | VkColorComponentFlags.ColorComponentABit,
                            blendEnable    = false,
                        };
                    }
                    var colorBlendStates_ptr = colorBlendStates.Pointer();

                    var colorBlend = new VkPipelineColorBlendStateCreateInfo()
                    {
                        sType           = VkStructureType.StructureTypePipelineColorBlendStateCreateInfo,
                        logicOpEnable   = false,
                        logicOp         = VkLogicOp.LogicOpCopy,
                        attachmentCount = (uint)colorBlendStates.Length,
                        pAttachments    = colorBlendStates_ptr,
                    };
                    colorBlend.blendConstants[0] = 0;
                    colorBlend.blendConstants[1] = 0;
                    colorBlend.blendConstants[2] = 0;
                    colorBlend.blendConstants[3] = 0;
                    var colorBlend_ptr = colorBlend.Pointer();

                    var dynamicStates = stackalloc VkDynamicState[]
                    {
                        VkDynamicState.DynamicStateViewport
                    };

                    var dynamicState = new VkPipelineDynamicStateCreateInfo()
                    {
                        sType             = VkStructureType.StructureTypePipelineDynamicStateCreateInfo,
                        dynamicStateCount = ViewportDynamic ? 1u : 0u,
                        pDynamicStates    = dynamicStates
                    };
                    var dynamicState_ptr = dynamicState.Pointer();

                    //Setup graphics pipeline
                    var pipelineInfo = new VkGraphicsPipelineCreateInfo()
                    {
                        sType               = VkStructureType.StructureTypeGraphicsPipelineCreateInfo,
                        stageCount          = (uint)shaderStages.Length,
                        pStages             = shaderStages_ptr,
                        pVertexInputState   = vertexInputInfo_ptr,
                        pInputAssemblyState = inputAssembly_ptr,
                        pViewportState      = viewportCreateInfo_ptr,
                        pRasterizationState = rasterizer_ptr,
                        pMultisampleState   = multisampling_ptr,
                        pDepthStencilState  = depthStencil_ptr,
                        pColorBlendState    = colorBlend_ptr,
                        pDynamicState       = dynamicState_ptr,
                        layout              = PipelineLayout.hndl,
                        renderPass          = RenderPass.hndl,
                        subpass             = 0,
                        basePipelineHandle  = IntPtr.Zero,
                        basePipelineIndex   = -1,
                    };

                    IntPtr pipeline_l = IntPtr.Zero;
                    if (vkCreateGraphicsPipelines(GraphicsDevice.GetDeviceInfo(deviceIndex).Device, IntPtr.Zero, 1, pipelineInfo.Pointer(), null, &pipeline_l) != VkResult.Success)
                    {
                        throw new Exception("Failed to create graphics pipeline.");
                    }
                    hndl = pipeline_l;

                    if (GraphicsDevice.EnableValidation)
                    {
                        var objName = new VkDebugUtilsObjectNameInfoEXT()
                        {
                            sType        = VkStructureType.StructureTypeDebugUtilsObjectNameInfoExt,
                            pObjectName  = Name,
                            objectType   = VkObjectType.ObjectTypePipeline,
                            objectHandle = (ulong)hndl
                        };
                        GraphicsDevice.SetDebugUtilsObjectNameEXT(GraphicsDevice.GetDeviceInfo(deviceIndex).Device, objName.Pointer());
                    }

                    devID  = deviceIndex;
                    locked = true;
                }
            }
            else
            {
                throw new Exception("Pipeline is locked.");
            }
        }
Beispiel #15
0
        void CreateGraphicsPipeline()
        {
            VkShaderModule vert = CreateShaderModule(File.ReadAllBytes("vert.spv"));
            VkShaderModule frag = CreateShaderModule(File.ReadAllBytes("frag.spv"));

            InteropString entry = new InteropString("main");

            var vertInfo = new VkPipelineShaderStageCreateInfo();

            vertInfo.sType  = CSGL.Vulkan.VkStructureType.PipelineShaderStageCreateInfo;
            vertInfo.stage  = CSGL.Vulkan.VkShaderStageFlags.VertexBit;
            vertInfo.module = vert;
            vertInfo.pName  = entry.Address;

            var fragInfo = new VkPipelineShaderStageCreateInfo();

            fragInfo.sType  = CSGL.Vulkan.VkStructureType.PipelineShaderStageCreateInfo;
            fragInfo.stage  = CSGL.Vulkan.VkShaderStageFlags.FragmentBit;
            fragInfo.module = frag;
            fragInfo.pName  = entry.Address;

            var shaderStages = new NativeArray <VkPipelineShaderStageCreateInfo>(2);

            shaderStages[0] = vertInfo;
            shaderStages[1] = fragInfo;

            var vertexInputInfo = new VkPipelineVertexInputStateCreateInfo();

            vertexInputInfo.sType = CSGL.Vulkan.VkStructureType.PipelineVertexInputStateCreateInfo;

            var vertexInputNative = new Native <VkPipelineVertexInputStateCreateInfo>(vertexInputInfo);

            var inputAssembly = new VkPipelineInputAssemblyStateCreateInfo();

            inputAssembly.sType    = CSGL.Vulkan.VkStructureType.PipelineInputAssemblyStateCreateInfo;
            inputAssembly.topology = CSGL.Vulkan.VkPrimitiveTopology.TriangleList;

            var inputAssemblyNative = new Native <VkPipelineInputAssemblyStateCreateInfo>(inputAssembly);

            var viewport = new VkViewport();

            viewport.width    = swapchainExtent.width;
            viewport.height   = swapchainExtent.height;
            viewport.minDepth = 0f;
            viewport.maxDepth = 1f;

            var viewportNative = new Native <VkViewport>(viewport);

            var scissor = new VkRect2D();

            scissor.extent = swapchainExtent;

            var scissorNative = new Native <VkRect2D>(scissor);

            var viewportState = new VkPipelineViewportStateCreateInfo();

            viewportState.sType         = CSGL.Vulkan.VkStructureType.PipelineViewportStateCreateInfo;
            viewportState.viewportCount = 1;
            viewportState.pViewports    = viewportNative.Address;
            viewportState.scissorCount  = 1;
            viewportState.pScissors     = scissorNative.Address;

            var viewportStateNative = new Native <VkPipelineViewportStateCreateInfo>(viewportState);

            var rasterizer = new VkPipelineRasterizationStateCreateInfo();

            rasterizer.sType       = CSGL.Vulkan.VkStructureType.PipelineRasterizationStateCreateInfo;
            rasterizer.polygonMode = CSGL.Vulkan.VkPolygonMode.Fill;
            rasterizer.lineWidth   = 1f;
            rasterizer.cullMode    = CSGL.Vulkan.VkCullModeFlags.BackBit;
            rasterizer.frontFace   = CSGL.Vulkan.VkFrontFace.Clockwise;

            var rasterizerNative = new Native <VkPipelineRasterizationStateCreateInfo>(rasterizer);

            var multisampling = new VkPipelineMultisampleStateCreateInfo();

            multisampling.sType = CSGL.Vulkan.VkStructureType.PipelineMultisampleStateCreateInfo;
            multisampling.rasterizationSamples = CSGL.Vulkan.VkSampleCountFlags._1_Bit;
            multisampling.minSampleShading     = 1f;

            var multisamplingNative = new Native <VkPipelineMultisampleStateCreateInfo>(multisampling);

            var colorBlendAttachment = new VkPipelineColorBlendAttachmentState();

            colorBlendAttachment.colorWriteMask = CSGL.Vulkan.VkColorComponentFlags.RBit
                                                  | CSGL.Vulkan.VkColorComponentFlags.GBit
                                                  | CSGL.Vulkan.VkColorComponentFlags.BBit
                                                  | CSGL.Vulkan.VkColorComponentFlags.ABit;
            colorBlendAttachment.srcColorBlendFactor = CSGL.Vulkan.VkBlendFactor.One;
            colorBlendAttachment.dstColorBlendFactor = CSGL.Vulkan.VkBlendFactor.Zero;
            colorBlendAttachment.colorBlendOp        = CSGL.Vulkan.VkBlendOp.Add;
            colorBlendAttachment.srcAlphaBlendFactor = CSGL.Vulkan.VkBlendFactor.One;
            colorBlendAttachment.dstAlphaBlendFactor = CSGL.Vulkan.VkBlendFactor.Zero;
            colorBlendAttachment.alphaBlendOp        = CSGL.Vulkan.VkBlendOp.Add;

            var colorBlendAttachmentNative = new Native <VkPipelineColorBlendAttachmentState>(colorBlendAttachment);

            var colorBlending = new VkPipelineColorBlendStateCreateInfo();

            colorBlending.sType           = CSGL.Vulkan.VkStructureType.PipelineColorBlendStateCreateInfo;
            colorBlending.logicOp         = CSGL.Vulkan.VkLogicOp.Copy;
            colorBlending.attachmentCount = 1;
            colorBlending.pAttachments    = colorBlendAttachmentNative.Address;

            var colorBlendingNative = new Native <VkPipelineColorBlendStateCreateInfo>(colorBlending);

            var pipelineLayoutInfo = new VkPipelineLayoutCreateInfo();

            pipelineLayoutInfo.sType = CSGL.Vulkan.VkStructureType.PipelineLayoutCreateInfo;

            if (pipelineLayout != VkPipelineLayout.Null)
            {
                VK.DestroyPipelineLayout(device, pipelineLayout, alloc);
            }
            var result = VK.CreatePipelineLayout(device, ref pipelineLayoutInfo, alloc, out pipelineLayout);

            var info = new VkGraphicsPipelineCreateInfo();

            info.sType               = CSGL.Vulkan.VkStructureType.GraphicsPipelineCreateInfo;
            info.stageCount          = 2;
            info.pStages             = shaderStages.Address;
            info.pVertexInputState   = vertexInputNative.Address;
            info.pInputAssemblyState = inputAssemblyNative.Address;
            info.pViewportState      = viewportStateNative.Address;
            info.pRasterizationState = rasterizerNative.Address;
            info.pMultisampleState   = multisamplingNative.Address;
            info.pColorBlendState    = colorBlendingNative.Address;
            info.layout              = pipelineLayout;
            info.renderPass          = renderPass;
            info.subpass             = 0;
            info.basePipelineHandle  = VkPipeline.Null;
            info.basePipelineIndex   = -1;

            var infoNative = new Native <VkGraphicsPipelineCreateInfo>(info);
            var temp       = new Native <VkPipeline>();

            if (pipeline != VkPipeline.Null)
            {
                VK.DestroyPipeline(device, pipeline, alloc);
            }

            result   = VK.CreateGraphicsPipelines(device, VkPipelineCache.Null, 1, infoNative.Address, alloc, temp.Address);
            pipeline = temp.Value;

            infoNative.Dispose();
            temp.Dispose();

            entry.Dispose();
            shaderStages.Dispose();
            vertexInputNative.Dispose();
            inputAssemblyNative.Dispose();
            viewportNative.Dispose();
            scissorNative.Dispose();
            viewportStateNative.Dispose();
            rasterizerNative.Dispose();
            multisamplingNative.Dispose();
            colorBlendingNative.Dispose();
            colorBlendAttachmentNative.Dispose();
            VK.DestroyShaderModule(device, vert, alloc);
            VK.DestroyShaderModule(device, frag, alloc);
        }
        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);
        }
Beispiel #17
0
        public VkPipeline(VkGraphicsDevice gd, ref ComputePipelineDescription description)
            : base(ref description)
        {
            _gd = gd;
            IsComputePipeline = true;
            RefCount          = new ResourceRefCount(DisposeCore);

            VkComputePipelineCreateInfo pipelineCI = VkComputePipelineCreateInfo.New();

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

            // Shader Stage

            VkSpecializationInfo specializationInfo;

            SpecializationConstant[] specDescs = description.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   shader   = description.ComputeShader;
            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.pSpecializationInfo = &specializationInfo;
            pipelineCI.stage            = stageCI;

            VkResult result = vkCreateComputePipelines(
                _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;
            }
        }
Beispiel #18
0
        void preparePipelines()
        {
            var inputAssemblyState = new VkPipelineInputAssemblyStateCreateInfo();

            inputAssemblyState.sType    = PipelineInputAssemblyStateCreateInfo;
            inputAssemblyState.topology = VkPrimitiveTopology.TriangleList;
            inputAssemblyState.flags    = 0;
            inputAssemblyState.primitiveRestartEnable = false;

            var rasterizationState = new VkPipelineRasterizationStateCreateInfo();

            rasterizationState.sType       = PipelineRasterizationStateCreateInfo;
            rasterizationState.polygonMode = VkPolygonMode.Fill;
            rasterizationState.cullMode    = VkCullModeFlagBits.Back;
            rasterizationState.frontFace   = VkFrontFace.Clockwise;
            rasterizationState.flags       = 0;

            var blendAttachmentState = new VkPipelineColorBlendAttachmentState();

            blendAttachmentState.colorWriteMask = (VkColorComponentFlagBits)0xf;
            blendAttachmentState.blendEnable    = false;

            var colorBlendState = new VkPipelineColorBlendStateCreateInfo();

            colorBlendState.sType       = PipelineColorBlendStateCreateInfo;
            colorBlendState.attachments = blendAttachmentState;

            var depthStencilState = new VkPipelineDepthStencilStateCreateInfo();

            depthStencilState.sType            = PipelineDepthStencilStateCreateInfo;
            depthStencilState.depthTestEnable  = true;
            depthStencilState.depthWriteEnable = true;
            depthStencilState.depthCompareOp   = VkCompareOp.LessOrEqual;

            var viewportState = new VkPipelineViewportStateCreateInfo();

            viewportState.sType           = PipelineViewportStateCreateInfo;
            viewportState.viewports.count = 1;
            viewportState.scissors.count  = 1;
            viewportState.flags           = 0;

            var multisampleState = new VkPipelineMultisampleStateCreateInfo();

            multisampleState.sType = PipelineMultisampleStateCreateInfo;
            multisampleState.rasterizationSamples = VkSampleCountFlagBits._1;
            multisampleState.flags = 0;

            var dynamicStateEnables = new VkDynamicState[2];

            dynamicStateEnables[0] = VkDynamicState.Viewport;
            dynamicStateEnables[1] = VkDynamicState.Scissor;
            VkPipelineDynamicStateCreateInfo dynamicState = new VkPipelineDynamicStateCreateInfo();

            dynamicState.sType         = PipelineDynamicStateCreateInfo;
            dynamicState.dynamicStates = dynamicStateEnables;
            dynamicState.flags         = 0;

            // Solid rendering pipeline
            // Load shaders
            var shaderStages = new VkPipelineShaderStageCreateInfo[2];

            shaderStages[0] = loadShader(getAssetPath() + "shaders/mesh/mesh.vert.spv", VkShaderStageFlagBits.Vertex);
            shaderStages[1] = loadShader(getAssetPath() + "shaders/mesh/mesh.frag.spv", VkShaderStageFlagBits.Fragment);

            var info = new VkGraphicsPipelineCreateInfo();

            info.sType      = GraphicsPipelineCreateInfo;
            info.layout     = pipelineLayout;
            info.renderPass = renderPass;
            info.flags      = 0;

            var via = vInputStateInfo;

            info.pVertexInputState   = via;
            info.pInputAssemblyState = &inputAssemblyState;
            info.pRasterizationState = &rasterizationState;
            info.pColorBlendState    = &colorBlendState;
            info.pMultisampleState   = &multisampleState;
            info.pViewportState      = &viewportState;
            info.pDepthStencilState  = &depthStencilState;
            info.pDynamicState       = &dynamicState;
            info.stages = shaderStages;
            {
                VkPipeline pipeline;
                vkCreateGraphicsPipelines(device, pipelineCache, 1, &info, null, &pipeline);
                this.pipelines_solid = pipeline;
            }

            // Wire frame rendering pipeline
            if (DeviceFeatures.fillModeNonSolid == true)
            {
                rasterizationState.polygonMode = VkPolygonMode.Line;
                rasterizationState.lineWidth   = 1.0f;
                VkPipeline pipeline;
                vkCreateGraphicsPipelines(device, pipelineCache, 1, &info, null, &pipeline);
                this.pipelines_wireframe = pipeline;
            }
        }
        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);
        }
Beispiel #20
0
        private void CreateGraphicsPipeline()
        {
            // Shader stages
            var vertShaderCode = System.IO.File.ReadAllBytes("Shaders/vert.spv");
            var fragShaderCode = System.IO.File.ReadAllBytes("Shaders/frag.spv");

            var vertShaderModule = CreateShaderModule(vertShaderCode);
            var fragShaderModule = CreateShaderModule(fragShaderCode);

            string name      = "main";
            int    byteCount = System.Text.Encoding.UTF8.GetByteCount(name);
            byte * utf8Ptr   = stackalloc byte[byteCount];

            fixed(char *namePtr = name)
            {
                System.Text.Encoding.UTF8.GetBytes(namePtr, name.Length, utf8Ptr, byteCount);
            }

            var vertShaderStageInfo = new VkPipelineShaderStageCreateInfo()
            {
                sType  = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
                stage  = VkShaderStageFlagBits.VK_SHADER_STAGE_VERTEX_BIT,
                module = vertShaderModule,
                pName  = utf8Ptr,
            };

            var fragShaderStageInfo = new VkPipelineShaderStageCreateInfo()
            {
                sType  = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
                stage  = VkShaderStageFlagBits.VK_SHADER_STAGE_FRAGMENT_BIT,
                module = fragShaderModule,
                pName  = utf8Ptr,
            };

            var shaderStages = stackalloc VkPipelineShaderStageCreateInfo[] { vertShaderStageInfo, fragShaderStageInfo };

            // VertexInput
            var vertexInputInfo = new VkPipelineVertexInputStateCreateInfo()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
                vertexBindingDescriptionCount   = 0,
                pVertexBindingDescriptions      = null,
                vertexAttributeDescriptionCount = 0,
                pVertexAttributeDescriptions    = null,
            };

            var inputAssembly = new VkPipelineInputAssemblyStateCreateInfo()
            {
                sType    = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
                topology = VkPrimitiveTopology.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
                primitiveRestartEnable = false,
            };

            var viewport = new VkViewport()
            {
                x        = 0f,
                y        = 0f,
                width    = (float)vkSwapChainExtent.width,
                height   = (float)vkSwapChainExtent.height,
                minDepth = 0f,
                maxDepth = 1f,
            };

            var scissor = new VkRect2D()
            {
                offset = new VkOffset2D()
                {
                    x = 0, y = 0
                },
                extent = vkSwapChainExtent,
            };

            var viewportState = new VkPipelineViewportStateCreateInfo()
            {
                sType         = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
                viewportCount = 1,
                pViewports    = &viewport,
                scissorCount  = 1,
                pScissors     = &scissor,
            };

            var rasterizer = new VkPipelineRasterizationStateCreateInfo()
            {
                sType                   = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
                depthClampEnable        = false,
                rasterizerDiscardEnable = false,
                polygonMode             = VkPolygonMode.VK_POLYGON_MODE_FILL,
                lineWidth               = 1f,
                cullMode                = VkCullModeFlagBits.VK_CULL_MODE_BACK_BIT,
                frontFace               = VkFrontFace.VK_FRONT_FACE_CLOCKWISE,
                depthBiasEnable         = false,
                depthBiasConstantFactor = 0f,
                depthBiasClamp          = 0f,
                depthBiasSlopeFactor    = 0f,
            };

            var multisampling = new VkPipelineMultisampleStateCreateInfo()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
                sampleShadingEnable   = false,
                rasterizationSamples  = VkSampleCountFlagBits.VK_SAMPLE_COUNT_1_BIT,
                minSampleShading      = 1f,
                pSampleMask           = null,
                alphaToCoverageEnable = false,
                alphaToOneEnable      = false,
            };

            var colorBlendAttachment = new VkPipelineColorBlendAttachmentState()
            {
                colorWriteMask = VkColorComponentFlagBits.VK_COLOR_COMPONENT_R_BIT | VkColorComponentFlagBits.VK_COLOR_COMPONENT_G_BIT | VkColorComponentFlagBits.VK_COLOR_COMPONENT_B_BIT | VkColorComponentFlagBits.VK_COLOR_COMPONENT_A_BIT,
                blendEnable    = false,
            };


            var colorBlending = new VkPipelineColorBlendStateCreateInfo()
            {
                sType            = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
                logicOpEnable    = false,
                logicOp          = VkLogicOp.VK_LOGIC_OP_COPY,
                pAttachments     = &colorBlendAttachment,
                attachmentCount  = 1,
                blendConstants_0 = 0f,
                blendConstants_1 = 0f,
                blendConstants_2 = 0f,
                blendConstants_3 = 0f,
            };

            var pipelineLayoutInfo = new VkPipelineLayoutCreateInfo()
            {
                sType                  = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
                setLayoutCount         = 0,
                pushConstantRangeCount = 0,
            };

            VkPipelineLayout newPipelineLayout;
            var result = VulkanNative.vkCreatePipelineLayout(vkDevice, &pipelineLayoutInfo, null, &newPipelineLayout);

            vkPipelineLayout = newPipelineLayout;
            Helpers.CheckErrors(result);

            var pipelineInfo = new VkGraphicsPipelineCreateInfo()
            {
                sType               = VkStructureType.VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
                stageCount          = 2,
                pStages             = shaderStages,
                pVertexInputState   = &vertexInputInfo,
                pInputAssemblyState = &inputAssembly,
                pViewportState      = &viewportState,
                pRasterizationState = &rasterizer,
                pMultisampleState   = &multisampling,
                pDepthStencilState  = null,
                pColorBlendState    = &colorBlending,
                pDynamicState       = null,
                layout              = vkPipelineLayout,
                renderPass          = vkRenderPass,
                subpass             = 0,
                basePipelineHandle  = 0,
                basePipelineIndex   = -1,
            };

            VkPipeline newPipeline;

            result             = VulkanNative.vkCreateGraphicsPipelines(vkDevice, 0, 1, &pipelineInfo, null, &newPipeline);
            vkGraphicsPipeline = newPipeline;
            Helpers.CheckErrors(result);

            VulkanNative.vkDestroyShaderModule(vkDevice, vertShaderModule, null);
            VulkanNative.vkDestroyShaderModule(vkDevice, fragShaderModule, null);
        }
Beispiel #21
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;
        }
        void preparePipelines()
        {
            var inputAssemblyState = VkPipelineInputAssemblyStateCreateInfo.Alloc();

            inputAssemblyState->topology = VkPrimitiveTopology.TriangleList;
            inputAssemblyState->primitiveRestartEnable = false;

            var rasterizationState = VkPipelineRasterizationStateCreateInfo.Alloc();

            rasterizationState->polygonMode = VkPolygonMode.Fill;
            rasterizationState->cullMode    = VkCullModeFlagBits.None;
            rasterizationState->frontFace   = VkFrontFace.CounterClockwise;
            rasterizationState->lineWidth   = 1.0f;

            var blendAttachmentState = VkPipelineColorBlendAttachmentState.Alloc();

            blendAttachmentState->colorWriteMask = (VkColorComponentFlagBits)0xf;
            blendAttachmentState->blendEnable    = false;

            var colorBlendState = VkPipelineColorBlendStateCreateInfo.Alloc();

            colorBlendState->attachments.count   = 1;
            colorBlendState->attachments.pointer = blendAttachmentState;

            var depthStencilState = VkPipelineDepthStencilStateCreateInfo.Alloc();

            depthStencilState->depthTestEnable  = true;
            depthStencilState->depthWriteEnable = true;
            depthStencilState->depthCompareOp   = VkCompareOp.LessOrEqual;
            depthStencilState->front            = depthStencilState->back;
            depthStencilState->back.compareOp   = VkCompareOp.Always;

            var viewportState = VkPipelineViewportStateCreateInfo.Alloc();

            viewportState[0].viewports.count = 1;
            viewportState[0].scissors.count  = 1;

            var multisampleState = VkPipelineMultisampleStateCreateInfo.Alloc();

            multisampleState->rasterizationSamples = VkSampleCountFlagBits._1;

            var dynamicStateEnables = new VkDynamicState[] { VkDynamicState.Viewport, VkDynamicState.Scissor };
            var dynamicState        = VkPipelineDynamicStateCreateInfo.Alloc();

            dynamicState[0].dynamicStates = dynamicStateEnables;

            var shaderStages = VkPipelineShaderStageCreateInfo.Alloc(2);

            var pipelineCreateInfo = VkGraphicsPipelineCreateInfo.Alloc();

            pipelineCreateInfo->layout              = pipelineLayoutRadialBlur;
            pipelineCreateInfo->renderPass          = renderPass;
            pipelineCreateInfo->basePipelineIndex   = -1;
            pipelineCreateInfo->pInputAssemblyState = inputAssemblyState;
            pipelineCreateInfo->pRasterizationState = rasterizationState;
            pipelineCreateInfo->pColorBlendState    = colorBlendState;
            pipelineCreateInfo->pMultisampleState   = multisampleState;
            pipelineCreateInfo->pViewportState      = viewportState;
            pipelineCreateInfo->pDepthStencilState  = depthStencilState;
            pipelineCreateInfo->pDynamicState       = dynamicState;
            pipelineCreateInfo->stages.count        = 2;
            pipelineCreateInfo->stages.pointer      = shaderStages;

            // Radial blur pipeline
            shaderStages[0] = loadShader(getAssetPath() + "shaders/radialblur/radialblur.vert.spv", VkShaderStageFlagBits.Vertex);
            shaderStages[1] = loadShader(getAssetPath() + "shaders/radialblur/radialblur.frag.spv", VkShaderStageFlagBits.Fragment);
            // Empty vertex input state
            var emptyInputState = VkPipelineVertexInputStateCreateInfo.Alloc();

            pipelineCreateInfo->pVertexInputState = emptyInputState;
            pipelineCreateInfo->layout            = pipelineLayoutRadialBlur;
            // Additive blending
            blendAttachmentState->colorWriteMask      = (VkColorComponentFlagBits)0xF;
            blendAttachmentState->blendEnable         = true;
            blendAttachmentState->colorBlendOp        = VkBlendOp.Add;
            blendAttachmentState->srcColorBlendFactor = VkBlendFactor.One;
            blendAttachmentState->dstColorBlendFactor = VkBlendFactor.One;
            blendAttachmentState->alphaBlendOp        = VkBlendOp.Add;
            blendAttachmentState->srcAlphaBlendFactor = VkBlendFactor.SrcAlpha;
            blendAttachmentState->dstAlphaBlendFactor = VkBlendFactor.DstAlpha;
            {
                VkPipeline pipeline;
                vkCreateGraphicsPipelines(device, pipelineCache, 1, pipelineCreateInfo, null, &pipeline);
                this.pipelineRadialBlur = pipeline;
            }

            // No blending (for debug display)
            blendAttachmentState->blendEnable = false;
            {
                VkPipeline pipeline;
                vkCreateGraphicsPipelines(device, pipelineCache, 1, pipelineCreateInfo, null, &pipeline);
                this.pipelineOffscreenDisplay = pipeline;
            }

            // Phong pass
            pipelineCreateInfo->layout            = pipelineLayoutScene;
            shaderStages[0]                       = loadShader(getAssetPath() + "shaders/radialblur/phongpass.vert.spv", VkShaderStageFlagBits.Vertex);
            shaderStages[1]                       = loadShader(getAssetPath() + "shaders/radialblur/phongpass.frag.spv", VkShaderStageFlagBits.Fragment);
            pipelineCreateInfo->pVertexInputState = inputInfo;
            blendAttachmentState->blendEnable     = false;
            depthStencilState->depthWriteEnable   = true;
            {
                VkPipeline pipeline;
                vkCreateGraphicsPipelines(device, pipelineCache, 1, pipelineCreateInfo, null, &pipeline);
                this.pipelinePhongPass = pipeline;
            }

            // Color only pass (offscreen blur base)
            shaderStages[0] = loadShader(getAssetPath() + "shaders/radialblur/colorpass.vert.spv", VkShaderStageFlagBits.Vertex);
            shaderStages[1] = loadShader(getAssetPath() + "shaders/radialblur/colorpass.frag.spv", VkShaderStageFlagBits.Fragment);
            pipelineCreateInfo->renderPass = offscreenPass.renderPass;
            {
                VkPipeline pipeline;
                vkCreateGraphicsPipelines(device, pipelineCache, 1, pipelineCreateInfo, null, &pipeline);
                this.pipelineColorPass = pipeline;
            }
        }
Beispiel #23
0
        void CreateGraphicsPipeline()
        {
            var vert = CreateShaderModule(File.ReadAllBytes("vert.spv"));
            var frag = CreateShaderModule(File.ReadAllBytes("frag.spv"));

            var vertInfo = new VkPipelineShaderStageCreateInfo();

            vertInfo.stage  = VkShaderStageFlags.VertexBit;
            vertInfo.module = vert;
            vertInfo.name   = "main";

            var fragInfo = new VkPipelineShaderStageCreateInfo();

            fragInfo.stage  = VkShaderStageFlags.FragmentBit;
            fragInfo.module = frag;
            fragInfo.name   = "main";

            var shaderStages = new List <VkPipelineShaderStageCreateInfo> {
                vertInfo, fragInfo
            };

            var vertexInputInfo = new VkPipelineVertexInputStateCreateInfo();

            var inputAssembly = new VkPipelineInputAssemblyStateCreateInfo();

            inputAssembly.topology = VkPrimitiveTopology.TriangleList;

            var viewport = new VkViewport();

            viewport.width    = swapchainExtent.width;
            viewport.height   = swapchainExtent.height;
            viewport.minDepth = 0f;
            viewport.maxDepth = 1f;

            var scissor = new VkRect2D();

            scissor.extent = swapchainExtent;

            var viewportState = new VkPipelineViewportStateCreateInfo();

            viewportState.viewports = new List <VkViewport> {
                viewport
            };
            viewportState.scissors = new List <VkRect2D> {
                scissor
            };

            var rasterizer = new VkPipelineRasterizationStateCreateInfo();

            rasterizer.polygonMode = VkPolygonMode.Fill;
            rasterizer.lineWidth   = 1f;
            rasterizer.cullMode    = VkCullModeFlags.BackBit;
            rasterizer.frontFace   = VkFrontFace.Clockwise;

            var multisampling = new VkPipelineMultisampleStateCreateInfo();

            multisampling.rasterizationSamples = VkSampleCountFlags._1_Bit;
            multisampling.minSampleShading     = 1f;

            var colorBlendAttachment = new VkPipelineColorBlendAttachmentState();

            colorBlendAttachment.colorWriteMask = VkColorComponentFlags.RBit
                                                  | VkColorComponentFlags.GBit
                                                  | VkColorComponentFlags.BBit
                                                  | VkColorComponentFlags.ABit;
            colorBlendAttachment.srcColorBlendFactor = VkBlendFactor.One;
            colorBlendAttachment.dstColorBlendFactor = VkBlendFactor.Zero;
            colorBlendAttachment.colorBlendOp        = VkBlendOp.Add;
            colorBlendAttachment.srcAlphaBlendFactor = VkBlendFactor.One;
            colorBlendAttachment.dstAlphaBlendFactor = VkBlendFactor.Zero;
            colorBlendAttachment.alphaBlendOp        = VkBlendOp.Add;

            var colorBlending = new VkPipelineColorBlendStateCreateInfo();

            colorBlending.logicOp     = VkLogicOp.Copy;
            colorBlending.attachments = new List <VkPipelineColorBlendAttachmentState> {
                colorBlendAttachment
            };

            var pipelineLayoutInfo = new VkPipelineLayoutCreateInfo();

            pipelineLayout?.Dispose();

            pipelineLayout = new VkPipelineLayout(device, pipelineLayoutInfo);

            var info = new VkGraphicsPipelineCreateInfo();

            info.stages             = shaderStages;
            info.vertexInputState   = vertexInputInfo;
            info.inputAssemblyState = inputAssembly;
            info.viewportState      = viewportState;
            info.rasterizationState = rasterizer;
            info.multisampleState   = multisampling;
            info.colorBlendState    = colorBlending;
            info.layout             = pipelineLayout;
            info.renderPass         = renderPass;
            info.subpass            = 0;
            info.basePipelineHandle = null;
            info.basePipelineIndex  = -1;

            pipeline?.Dispose();

            pipeline = new VkGraphicsPipeline(device, info, null);

            vert.Dispose();
            frag.Dispose();
        }
Beispiel #24
0
        private void createGraphicsPipeline()
        {
            var vertShaderModule = createShaderModule(typeof(Shader_Vert_03));
            var fragShaderModule = createShaderModule(typeof(Shader_Frag_03));

            VkPipelineShaderStageCreateInfo vertShaderStageInfo = new VkPipelineShaderStageCreateInfo();

            vertShaderStageInfo.sType  = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
            vertShaderStageInfo.stage  = VkShaderStageFlagBits.VK_SHADER_STAGE_VERTEX_BIT;
            vertShaderStageInfo.module = vertShaderModule;
            vertShaderStageInfo.pName  = "main";

            VkPipelineShaderStageCreateInfo fragShaderStageInfo = new VkPipelineShaderStageCreateInfo();

            fragShaderStageInfo.sType  = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
            fragShaderStageInfo.stage  = VkShaderStageFlagBits.VK_SHADER_STAGE_FRAGMENT_BIT;
            fragShaderStageInfo.module = fragShaderModule;
            fragShaderStageInfo.pName  = "main";

            VkPipelineShaderStageCreateInfo[] shaderStages = new VkPipelineShaderStageCreateInfo[2] {
                vertShaderStageInfo, fragShaderStageInfo
            };

            VkPipelineVertexInputStateCreateInfo vertexInputInfo = new VkPipelineVertexInputStateCreateInfo();

            vertexInputInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;

            var bindingDescription    = Vertex.getBindingDescription();
            var attributeDescriptions = Vertex.getAttributeDescriptions();

            vertexInputInfo.vertexBindingDescriptionCount   = 1;
            vertexInputInfo.vertexAttributeDescriptionCount = attributeDescriptions.Length;
            vertexInputInfo.pVertexBindingDescriptions      = new VkVertexInputBindingDescription[] { bindingDescription };
            vertexInputInfo.pVertexAttributeDescriptions    = attributeDescriptions;

            VkPipelineInputAssemblyStateCreateInfo inputAssembly = new VkPipelineInputAssemblyStateCreateInfo();

            inputAssembly.sType    = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
            inputAssembly.topology = VkPrimitiveTopology.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
            inputAssembly.primitiveRestartEnable = VkBool32.VK_FALSE;

            VkViewport viewport = new VkViewport();

            viewport.x        = 0.0f;
            viewport.y        = 0.0f;
            viewport.width    = (float)swapChainExtent.width;
            viewport.height   = (float)swapChainExtent.height;
            viewport.minDepth = 0.0f;
            viewport.maxDepth = 1.0f;

            VkRect2D scissor = new VkRect2D();

            scissor.offset = new VkOffset2D()
            {
                x = 0, y = 0
            };
            scissor.extent = swapChainExtent;

            VkPipelineViewportStateCreateInfo viewportState = new VkPipelineViewportStateCreateInfo();

            viewportState.sType         = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
            viewportState.viewportCount = 1;
            viewportState.pViewports    = new VkViewport[] { viewport };
            viewportState.scissorCount  = 1;
            viewportState.pSicssors     = new VkRect2D[] { scissor };

            VkPipelineRasterizationStateCreateInfo rasterizer = new VkPipelineRasterizationStateCreateInfo();

            rasterizer.sType                   = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
            rasterizer.depthClampEnable        = VkBool32.VK_FALSE;
            rasterizer.rasterizerDiscardEnable = VkBool32.VK_FALSE;
            rasterizer.polygonMode             = VkPolygonMode.VK_POLYGON_MODE_FILL;
            rasterizer.lineWidth               = 1.0f;
            rasterizer.cullMode                = VkCullModeFlagBits.VK_CULL_MODE_BACK_BIT;
            rasterizer.frontFace               = VkFrontFace.VK_FRONT_FACE_CLOCKWISE;
            rasterizer.depthBiasEnable         = VkBool32.VK_FALSE;

            VkPipelineMultisampleStateCreateInfo multisampling = new VkPipelineMultisampleStateCreateInfo();

            multisampling.sType = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
            multisampling.sampleShadingEnable  = VkBool32.VK_FALSE;
            multisampling.rasterizationSamples = VkSampleCountFlagBits.VK_SAMPLE_COUNT_1_BIT;

            VkPipelineColorBlendAttachmentState colorBlendAttachment = new VkPipelineColorBlendAttachmentState();

            colorBlendAttachment.colorWriteMask = VkColorComponentFlagBits.VK_COLOR_COMPONENT_R_BIT | VkColorComponentFlagBits.VK_COLOR_COMPONENT_G_BIT | VkColorComponentFlagBits.VK_COLOR_COMPONENT_B_BIT | VkColorComponentFlagBits.VK_COLOR_COMPONENT_A_BIT;
            colorBlendAttachment.blendEnable    = VkBool32.VK_FALSE;

            VkPipelineColorBlendStateCreateInfo colorBlending = VkPipelineColorBlendStateCreateInfo.Create();

            colorBlending.sType             = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
            colorBlending.logicOpEnable     = VkBool32.VK_FALSE;
            colorBlending.logicOp           = VkLogicOp.VK_LOGIC_OP_COPY;
            colorBlending.attachmentCount   = 1;
            colorBlending.pAttachments      = new VkPipelineColorBlendAttachmentState[] { colorBlendAttachment };
            colorBlending.blendConstants[0] = 0.0f;
            colorBlending.blendConstants[1] = 0.0f;
            colorBlending.blendConstants[2] = 0.0f;
            colorBlending.blendConstants[3] = 0.0f;

            VkPipelineLayoutCreateInfo pipelineLayoutInfo = new VkPipelineLayoutCreateInfo();

            pipelineLayoutInfo.sType                  = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
            pipelineLayoutInfo.setLayoutCount         = 0;
            pipelineLayoutInfo.pushConstantRangeCount = 0;

            VkResult result = Vulkan.vkCreatePipelineLayout(device, pipelineLayoutInfo, null, out pipelineLayout);

            if (result != VkResult.VK_SUCCESS)
            {
                throw Program.Throw("failed to create pipeline layout!");
            }

            VkGraphicsPipelineCreateInfo pipelineInfo = new VkGraphicsPipelineCreateInfo();

            pipelineInfo.sType               = VkStructureType.VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
            pipelineInfo.stageCount          = shaderStages.Length;
            pipelineInfo.pStages             = shaderStages;
            pipelineInfo.pVertexInputState   = vertexInputInfo;
            pipelineInfo.pInputAssemblyState = inputAssembly;
            pipelineInfo.pViewportState      = viewportState;
            pipelineInfo.pRasterizationState = rasterizer;
            pipelineInfo.pMultisampleState   = multisampling;
            pipelineInfo.pColorBlendState    = colorBlending;
            pipelineInfo.layout              = pipelineLayout;
            pipelineInfo.renderPass          = renderPass;
            pipelineInfo.subpass             = 0;
            pipelineInfo.basePipelineHandle  = null;

            VkPipeline[] pipelineResult = new VkPipeline[1];
            result = Vulkan.vkCreateGraphicsPipelines(device, null, 1, new VkGraphicsPipelineCreateInfo[] { pipelineInfo }, null, pipelineResult);
            if (result != VkResult.VK_SUCCESS)
            {
                throw Program.Throw("failed to create graphics pipeline!", result);
            }

            graphicsPipeline = pipelineResult[0];

            Vulkan.vkDestroyShaderModule(device, fragShaderModule, null);
            Vulkan.vkDestroyShaderModule(device, vertShaderModule, null);
        }
Beispiel #25
0
        private void CreateGraphicsPipeline()
        {
            var vertShaderModule = CreateShaderModule(File.ReadAllBytes("../../Resources/Shaders/vert.spv"));
            var fragShaderModule = CreateShaderModule(File.ReadAllBytes("../../Resources/Shaders/frag.spv"));

            var vertShaderStageInfo = new VkPipelineShaderStageCreateInfo()
            {
                Stage  = VkShaderStage.Vertex,
                Module = vertShaderModule,
                Name   = "main"
            };

            var fragShaderStageInfo = new VkPipelineShaderStageCreateInfo()
            {
                Stage  = VkShaderStage.Fragment,
                Module = fragShaderModule,
                Name   = "main"
            };

            var shaderStages    = new[] { vertShaderStageInfo, fragShaderStageInfo };
            var vertexInputInfo = new VkPipelineVertexInputStateCreateInfo
            {
                VertexBindingDescriptions   = new[] { Vertex.GetBindingDescription(0) },
                VertexAttributeDescriptions = Vertex.GetAttributeDescriptions(0)
            };
            var inputAssemblyInfo = new VkPipelineInputAssemblyStateCreateInfo
            {
                Topology = VkPrimitiveTopology.TriangleList,
                PrimitiveRestartEnable = false
            };
            var viewport = new VkViewport
            {
                X        = 0,
                Y        = 0,
                Width    = swapChainExtent.Width,
                Height   = swapChainExtent.Height,
                MinDepth = 0,
                MaxDepth = 1
            };
            var scissor           = new VkRect2D(new VkOffset2D(0, 0), swapChainExtent);
            var viewportStateInfo = new VkPipelineViewportStateCreateInfo
            {
                Viewports = new [] { viewport },
                Scissors  = new [] { scissor }
            };
            var rasterizerInfo = new VkPipelineRasterizationStateCreateInfo
            {
                DepthClampEnable        = false,
                RasterizerDiscardEnable = false,
                PolygonMode             = VkPolygonMode.Fill,
                LineWidth               = 1f,
                CullMode                = VkCullMode.Back,
                FrontFace               = VkFrontFace.Clockwise,
                DepthBiasEnable         = false,
                DepthBiasConstantFactor = 0f,
                DepthBiasClamp          = 0f,
                DepthBiasSlopeFactor    = 0f
            };
            var multisamplingInfo = new VkPipelineMultisampleStateCreateInfo
            {
                SampleShadingEnable   = false,
                RasterizationSamples  = VkSampleCount.B1,
                MinSampleShading      = 1f,
                SampleMask            = null,
                AlphaToCoverageEnable = false,
                AlphaToOneEnable      = false
            };
            var colorBlendAttachment = new VkPipelineColorBlendAttachmentState
            {
                ColorWriteMask      = VkColorComponent.R | VkColorComponent.G | VkColorComponent.B | VkColorComponent.A,
                BlendEnable         = (VkBool32)false,
                SrcColorBlendFactor = VkBlendFactor.One,
                SrcAlphaBlendFactor = VkBlendFactor.One,
                ColorBlendOp        = VkBlendOp.Add,
                AlphaBlendOp        = VkBlendOp.Add,
                DstColorBlendFactor = VkBlendFactor.Zero,
                DstAlphaBlendFactor = VkBlendFactor.Zero
            };
            var colorBlendingInfo = new VkPipelineColorBlendStateCreateInfo
            {
                LogicOpEnable  = false,
                LogicOp        = VkLogicOp.Copy,
                Attachments    = new[] { colorBlendAttachment },
                BlendConstants = new VkColor4(0, 0, 0, 0)
            };
            var dynamicStates = new[]
            {
                VkDynamicState.Viewport,
                VkDynamicState.LineWidth,
            };
            var dynamicStateInfo = new VkPipelineDynamicStateCreateInfo
            {
                DynamicStates = dynamicStates
            };
            var pipelineLayoutInfo = new VkPipelineLayoutCreateInfo
            {
                SetLayouts         = null,
                PushConstantRanges = null
            };

            pipelineLayout = device.CreatePipelineLayout(pipelineLayoutInfo, null).Object;

            var pipelineInfo = new VkGraphicsPipelineCreateInfo
            {
                Stages             = shaderStages,
                VertexInputState   = vertexInputInfo,
                InputAssemblyState = inputAssemblyInfo,
                TessellationState  = null,
                ViewportState      = viewportStateInfo,
                RasterizationState = rasterizerInfo,
                MultisampleState   = multisamplingInfo,
                DepthStencilState  = null,
                ColorBlendState    = colorBlendingInfo,
                DynamicState       = null,
                Layout             = pipelineLayout,
                RenderPass         = renderPass,
                Subpass            = 0,
                BasePipelineHandle = null,
                BasePipelineIndex  = -1,
                Flags = VkPipelineCreateFlags.None
            };

            graphicsPipeline = device.CreateGraphicsPipelines(null, new[] { pipelineInfo }, null).Object.Single();

            vertShaderModule.Dispose();
            fragShaderModule.Dispose();
        }
Beispiel #26
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;
            }
        }
Beispiel #27
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;
        }
Beispiel #28
0
        VkPipeline CreatePipeline(VkDevice device, VkSurfaceCapabilitiesKHR surfaceCapabilities,
                                  VkRenderPass renderPass, VkPipelineLayout pipelineLayout)
        {
            //VkShaderModule vertexShaderModule = device.CreateShaderModule(LoadResource(@"Shaders\shader.vert.spv"));
            VkShaderModule vsModule;
            {
                var info = new VkShaderModuleCreateInfo {
                    sType = VkStructureType.ShaderModuleCreateInfo
                };
                byte[] bytes = LoadResource(@"Shaders\shader.vert.spv");
                info.code = bytes;
                //vkAPI.vkCreateShaderModule(device, bytes);
                vkAPI.vkCreateShaderModule(device, &info, null, &vsModule).Check();
                info.Free();
            }
            //VkShaderModule fragmentShaderModule = device.CreateShaderModule(LoadResource(@"Shaders\shader.frag.spv"));
            VkShaderModule fsModule;
            {
                var info = new VkShaderModuleCreateInfo {
                    sType = VkStructureType.ShaderModuleCreateInfo
                };
                byte[] bytes = LoadResource(@"Shaders\shader.frag.spv");
                info.code = bytes;
                //vkAPI.vkCreateShaderModule(device, bytes);
                vkAPI.vkCreateShaderModule(device, &info, null, &fsModule).Check();
                info.Free();
            }
            var shaderStages = new VkPipelineShaderStageCreateInfo[2];
            {
                shaderStages[0].sType  = VkStructureType.PipelineShaderStageCreateInfo;
                shaderStages[0].stage  = VkShaderStageFlagBits.Vertex;
                shaderStages[0].module = vsModule;
                //"main".Set(ref shaderStages[0].pName);
                shaderStages[0].pName  = "main";
                shaderStages[1].sType  = VkStructureType.PipelineShaderStageCreateInfo;
                shaderStages[1].stage  = VkShaderStageFlagBits.Fragment;
                shaderStages[1].module = fsModule;
                //"main".Set(ref shaderStages[1].pName);
                shaderStages[1].pName = "main";
            }
            var viewport = new VkPipelineViewportStateCreateInfo {
                sType = VkStructureType.PipelineViewportStateCreateInfo
            };

            viewport.viewports = new VkViewport(surfaceCapabilities.currentExtent, 0.0f, 1.0f);
            viewport.scissors  = new VkRect2D(surfaceCapabilities.currentExtent);

            var multisample = new VkPipelineMultisampleStateCreateInfo {
                sType = VkStructureType.PipelineMultisampleStateCreateInfo
            };

            multisample.rasterizationSamples = VkSampleCountFlagBits._1;

            var colorBlend = new VkPipelineColorBlendStateCreateInfo {
                sType = VkStructureType.PipelineColorBlendStateCreateInfo
            };

            colorBlend.logicOp = VkLogicOp.Copy;
            var blend = new VkPipelineColorBlendAttachmentState(
                colorWriteMask: VkColorComponentFlagBits.R | VkColorComponentFlagBits.G
                | VkColorComponentFlagBits.B | VkColorComponentFlagBits.A,
                blendEnable: false);

            colorBlend.attachments = blend;

            var rasterization = new VkPipelineRasterizationStateCreateInfo {
                sType = VkStructureType.PipelineRasterizationStateCreateInfo
            };

            rasterization.polygonMode = VkPolygonMode.Fill;
            rasterization.cullMode    = VkCullModeFlagBits.None;
            rasterization.frontFace   = VkFrontFace.Clockwise;
            rasterization.lineWidth   = 1.0f;

            var inputAssem = new VkPipelineInputAssemblyStateCreateInfo {
                sType = VkStructureType.PipelineInputAssemblyStateCreateInfo
            };

            inputAssem.topology = VkPrimitiveTopology.TriangleList;

            var input = new VkPipelineVertexInputStateCreateInfo {
                sType = VkStructureType.PipelineVertexInputStateCreateInfo
            };

            // static readonly float[] Vertices = { .. }
            input.vertexBindingDescriptions = new VkVertexInputBindingDescription(
                binding: 0,
                stride: 2 * sizeof(float),
                inputRate: VkVertexInputRate.Vertex);
            // layout(location = 0) in vec2 inPos;
            input.vertexAttributeDescriptions = new VkVertexInputAttributeDescription(
                location: 0,
                binding: 0,
                format: VkFormat.R32g32Sfloat,
                offset: 0);

            //VkPipelineCache cache = device.CreatePipelineCache(ref cacheInfo);
            VkPipelineCache cache;
            {
                var info = VkPipelineCacheCreateInfo.Alloc();
                vkAPI.vkCreatePipelineCache(device, info, null, &cache).Check();
                Marshal.FreeHGlobal((IntPtr)info);
            }
            //var infos = new VkGraphicsPipelineCreateInfo[] { pipelineCreateInfo };
            //return device.CreateGraphicsPipelines(ref cache, infos);
            VkPipeline pipeline;

            {
                var info = new VkGraphicsPipelineCreateInfo {
                    sType = VkStructureType.GraphicsPipelineCreateInfo
                };
                info.layout              = pipelineLayout;
                info.pViewportState      = &viewport;
                info.stages              = shaderStages;
                info.pMultisampleState   = &multisample;
                info.pColorBlendState    = &colorBlend;
                info.pRasterizationState = &rasterization;
                info.pInputAssemblyState = &inputAssem;
                info.pVertexInputState   = &input;
                info.renderPass          = renderPass;
                vkAPI.vkCreateGraphicsPipelines(device, cache, 1, &info, null, &pipeline).Check();
                info.Free();
            }

            shaderStages[0].Free();
            shaderStages[1].Free();
            viewport.Free();
            colorBlend.Free();
            input.Free();

            return(pipeline);
        }
Beispiel #29
0
        void preparePipelines()
        {
            var inputAssemblyState = VkPipelineInputAssemblyStateCreateInfo.Alloc();

            inputAssemblyState[0].topology = VkPrimitiveTopology.TriangleList;
            inputAssemblyState[0].primitiveRestartEnable = false;

            var rasterizationState = VkPipelineRasterizationStateCreateInfo.Alloc();

            rasterizationState[0].polygonMode      = VkPolygonMode.Fill;
            rasterizationState[0].cullMode         = VkCullModeFlagBits.None;
            rasterizationState[0].frontFace        = VkFrontFace.CounterClockwise;
            rasterizationState[0].depthClampEnable = false;
            rasterizationState[0].lineWidth        = 1.0f;

            var blendAttachmentState = VkPipelineColorBlendAttachmentState.Alloc();

            blendAttachmentState[0].colorWriteMask = (VkColorComponentFlagBits)0xf;
            blendAttachmentState[0].blendEnable    = false;

            var colorBlendState = VkPipelineColorBlendStateCreateInfo.Alloc();

            colorBlendState[0].attachments.count   = 1;
            colorBlendState[0].attachments.pointer = blendAttachmentState;

            var depthStencilState = VkPipelineDepthStencilStateCreateInfo.Alloc();

            depthStencilState[0].depthTestEnable  = true;
            depthStencilState[0].depthWriteEnable = true;
            depthStencilState[0].depthCompareOp   = VkCompareOp.LessOrEqual;
            depthStencilState[0].front            = depthStencilState[0].back;
            depthStencilState[0].back.compareOp   = VkCompareOp.Always;

            var viewportState = VkPipelineViewportStateCreateInfo.Alloc();

            viewportState[0].viewports.count = 1;
            viewportState[0].scissors.count  = 1;

            var multisampleState = VkPipelineMultisampleStateCreateInfo.Alloc();

            multisampleState[0].rasterizationSamples = VkSampleCountFlagBits._1;

            var dynamicStateEnables = new VkDynamicState[] {
                VkDynamicState.Viewport,
                VkDynamicState.Scissor
            };
            var dynamicState = VkPipelineDynamicStateCreateInfo.Alloc();

            dynamicState[0].dynamicStates = dynamicStateEnables;

            // Load shaders
            var shaderStages = VkPipelineShaderStageCreateInfo.Alloc(2);

            shaderStages[0] = loadShader(getAssetPath() + "shaders/texture/texture.vert.spv", VkShaderStageFlagBits.Vertex);
            shaderStages[1] = loadShader(getAssetPath() + "shaders/texture/texture.frag.spv", VkShaderStageFlagBits.Fragment);

            var pipelineCreateInfo = VkGraphicsPipelineCreateInfo.Alloc();

            pipelineCreateInfo[0].layout            = pipelineLayout;
            pipelineCreateInfo[0].renderPass        = renderPass;
            pipelineCreateInfo[0].basePipelineIndex = -1;

            var vertexInputState = vDescription.inputState;

            pipelineCreateInfo[0].pVertexInputState   = vertexInputState;
            pipelineCreateInfo[0].pInputAssemblyState = inputAssemblyState;
            pipelineCreateInfo[0].pRasterizationState = rasterizationState;
            pipelineCreateInfo[0].pColorBlendState    = colorBlendState;
            pipelineCreateInfo[0].pMultisampleState   = multisampleState;
            pipelineCreateInfo[0].pViewportState      = viewportState;
            pipelineCreateInfo[0].pDepthStencilState  = depthStencilState;
            pipelineCreateInfo[0].pDynamicState       = dynamicState;
            pipelineCreateInfo[0].stages.count        = 2;
            pipelineCreateInfo[0].stages.pointer      = shaderStages;
            {
                VkPipeline pipeline;
                vkCreateGraphicsPipelines(device, pipelineCache, 1, pipelineCreateInfo, null, &pipeline);
                this.pipeline = pipeline;
            }
        }