public static VkPipeline CreateGraphicsPipeline(ref VkGraphicsPipelineCreateInfo pCreateInfos) { VkPipeline pPipelines; VulkanUtil.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, Utilities.AsPtr(ref pCreateInfos), null, &pPipelines)); return(pPipelines); }
public static VkGraphicsPipelineCreateInfo pipelineCreateInfo( VkPipelineLayout layout, VkRenderPass renderPass, VkPipelineCreateFlags flags = 0) { VkGraphicsPipelineCreateInfo pipelineCreateInfo = VkGraphicsPipelineCreateInfo.New(); pipelineCreateInfo.layout = layout; pipelineCreateInfo.renderPass = renderPass; pipelineCreateInfo.flags = flags; pipelineCreateInfo.basePipelineIndex = -1; pipelineCreateInfo.basePipelineHandle = new VkPipeline(); return(pipelineCreateInfo); }
private VkPipeline CreateGraphicsPipeline(VkDevice device, VkRenderPass renderPass) { VkPipeline pipeline = null; var createInfo = new VkGraphicsPipelineCreateInfo() { inputAssemblyState = m_inputAssemblyState, vertexInputState = m_vertexInputState, pRasterizationState = m_rasterizationState, pDepthStencilState = m_depthStencilState, pColorBlendState = m_colorBlendState, pMultisampleState = m_multisampleState, pStages = m_shaderStages, viewportState = m_viewportState, layout = m_pipelineLayout, renderPass = renderPass }; VulkanAPI.vkCreateGraphicsPipelines(device, null, 1, ref createInfo, out pipeline); return(pipeline); }
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; } }
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); }
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(); }
protected void init(GraphicPipelineConfig cfg) { if (state != ActivableState.Activated) { Layout.Activate(); RenderPass.Activate(); Cache?.Activate(); List <VkPipelineShaderStageCreateInfo> shaderStages = new List <VkPipelineShaderStageCreateInfo> (); foreach (ShaderInfo shader in cfg.Shaders) { shaderStages.Add(shader.Info); } using (PinnedObjects pctx = new PinnedObjects()) { VkPipelineColorBlendStateCreateInfo colorBlendInfo = VkPipelineColorBlendStateCreateInfo.New(); colorBlendInfo.logicOpEnable = cfg.ColorBlendLogicOpEnable; colorBlendInfo.logicOp = cfg.ColorBlendLogicOp; unsafe { colorBlendInfo.blendConstants[0] = cfg.ColorBlendConstants.X; colorBlendInfo.blendConstants[1] = cfg.ColorBlendConstants.Y; colorBlendInfo.blendConstants[2] = cfg.ColorBlendConstants.Z; colorBlendInfo.blendConstants[3] = cfg.ColorBlendConstants.W; } colorBlendInfo.attachmentCount = (uint)cfg.blendAttachments.Count; colorBlendInfo.pAttachments = cfg.blendAttachments.Pin(pctx); VkPipelineDynamicStateCreateInfo dynStatesInfo = VkPipelineDynamicStateCreateInfo.New(); dynStatesInfo.dynamicStateCount = (uint)cfg.dynamicStates.Count; dynStatesInfo.pDynamicStates = cfg.dynamicStates.Cast <int> ().ToArray().Pin(pctx); VkPipelineVertexInputStateCreateInfo vertInputInfo = VkPipelineVertexInputStateCreateInfo.New(); vertInputInfo.vertexBindingDescriptionCount = (uint)cfg.vertexBindings.Count; vertInputInfo.pVertexBindingDescriptions = cfg.vertexBindings.Pin(pctx); vertInputInfo.vertexAttributeDescriptionCount = (uint)cfg.vertexAttributes.Count; vertInputInfo.pVertexAttributeDescriptions = cfg.vertexAttributes.Pin(pctx); VkPipelineViewportStateCreateInfo viewportState = VkPipelineViewportStateCreateInfo.New(); if (cfg.Viewports.Count > 0) { viewportState.viewportCount = (uint)cfg.Viewports.Count; viewportState.pViewports = cfg.Viewports.Pin(pctx); } else { viewportState.viewportCount = 1; } if (cfg.Scissors.Count > 0) { viewportState.scissorCount = (uint)cfg.Scissors.Count; viewportState.pScissors = cfg.Scissors.Pin(pctx); } else { viewportState.scissorCount = 1; } VkGraphicsPipelineCreateInfo info = VkGraphicsPipelineCreateInfo.New(); info.renderPass = RenderPass.handle; info.layout = Layout.handle; info.pVertexInputState = vertInputInfo.Pin(pctx); info.pInputAssemblyState = cfg.inputAssemblyState.Pin(pctx); info.pRasterizationState = cfg.rasterizationState.Pin(pctx); info.pColorBlendState = colorBlendInfo.Pin(pctx); info.pMultisampleState = cfg.multisampleState.Pin(pctx); info.pViewportState = viewportState.Pin(pctx); info.pDepthStencilState = cfg.depthStencilState.Pin(pctx); info.pDynamicState = dynStatesInfo.Pin(pctx); info.stageCount = (uint)cfg.Shaders.Count; info.pStages = shaderStages.Pin(pctx); info.subpass = cfg.SubpassIndex; Utils.CheckResult(vkCreateGraphicsPipelines(Dev.VkDev, Cache == null ? VkPipelineCache.Null : Cache.handle, 1, ref info, IntPtr.Zero, out handle)); } } base.Activate(); }
private unsafe void Recreate() { if (Description.RootSignature == null) { return; } CreateRenderPass(Description); CreatePipelineLayout(Description); // Create shader stages Dictionary <int, string> inputAttributeNames; // Note: important to pin this so that stages[x].Name is valid during this whole function void *defaultEntryPointData = Core.Interop.Fixed(defaultEntryPoint); var stages = CreateShaderStages(Description, out inputAttributeNames); var inputAttributes = new VkVertexInputAttributeDescription[Description.InputElements.Length]; int inputAttributeCount = 0; var inputBindings = new VkVertexInputBindingDescription[inputAttributes.Length]; int inputBindingCount = 0; for (int inputElementIndex = 0; inputElementIndex < inputAttributes.Length; inputElementIndex++) { var inputElement = Description.InputElements[inputElementIndex]; var slotIndex = inputElement.InputSlot; if (inputElement.InstanceDataStepRate > 1) { throw new NotImplementedException(); } VkFormat format; int size; bool isCompressed; VulkanConvertExtensions.ConvertPixelFormat(inputElement.Format, out format, out size, out isCompressed); var location = inputAttributeNames.FirstOrDefault(x => x.Value == inputElement.SemanticName && inputElement.SemanticIndex == 0 || x.Value == inputElement.SemanticName + inputElement.SemanticIndex); if (location.Value != null) { inputAttributes[inputAttributeCount++] = new VkVertexInputAttributeDescription { format = format, offset = (uint)inputElement.AlignedByteOffset, binding = (uint)inputElement.InputSlot, location = (uint)location.Key }; } inputBindings[slotIndex].binding = (uint)slotIndex; inputBindings[slotIndex].inputRate = inputElement.InputSlotClass == InputClassification.Vertex ? VkVertexInputRate.Vertex : VkVertexInputRate.Instance; // TODO VULKAN: This is currently an argument to Draw() overloads. if (inputBindings[slotIndex].stride < inputElement.AlignedByteOffset + size) { inputBindings[slotIndex].stride = (uint)(inputElement.AlignedByteOffset + size); } if (inputElement.InputSlot >= inputBindingCount) { inputBindingCount = inputElement.InputSlot + 1; } } var inputAssemblyState = new VkPipelineInputAssemblyStateCreateInfo { sType = VkStructureType.PipelineInputAssemblyStateCreateInfo, topology = VulkanConvertExtensions.ConvertPrimitiveType(Description.PrimitiveType), primitiveRestartEnable = VulkanConvertExtensions.ConvertPrimitiveRestart(Description.PrimitiveType), }; // TODO VULKAN: Tessellation and multisampling var multisampleState = new VkPipelineMultisampleStateCreateInfo { sType = VkStructureType.PipelineMultisampleStateCreateInfo, rasterizationSamples = VkSampleCountFlags.Count1, }; var tessellationState = new VkPipelineTessellationStateCreateInfo { sType = VkStructureType.PipelineTessellationStateCreateInfo, }; var rasterizationState = CreateRasterizationState(Description.RasterizerState); var depthStencilState = CreateDepthStencilState(Description); var description = Description.BlendState; var renderTargetCount = Description.Output.RenderTargetCount; var colorBlendAttachments = new VkPipelineColorBlendAttachmentState[renderTargetCount]; var renderTargetBlendState = &description.RenderTarget0; for (int i = 0; i < renderTargetCount; i++) { colorBlendAttachments[i] = new VkPipelineColorBlendAttachmentState { blendEnable = renderTargetBlendState->BlendEnable, alphaBlendOp = VulkanConvertExtensions.ConvertBlendFunction(renderTargetBlendState->AlphaBlendFunction), colorBlendOp = VulkanConvertExtensions.ConvertBlendFunction(renderTargetBlendState->ColorBlendFunction), dstAlphaBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->AlphaDestinationBlend), dstColorBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->ColorDestinationBlend), srcAlphaBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->AlphaSourceBlend), srcColorBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->ColorSourceBlend), colorWriteMask = VulkanConvertExtensions.ConvertColorWriteChannels(renderTargetBlendState->ColorWriteChannels), }; if (description.IndependentBlendEnable) { renderTargetBlendState++; } } var viewportState = new VkPipelineViewportStateCreateInfo { sType = VkStructureType.PipelineViewportStateCreateInfo, scissorCount = 1, viewportCount = 1, }; fixed(VkDynamicState *dynamicStatesPointer = &dynamicStates[0]) { var vertexInputState = new VkPipelineVertexInputStateCreateInfo { sType = VkStructureType.PipelineVertexInputStateCreateInfo, vertexAttributeDescriptionCount = (uint)inputAttributeCount, pVertexAttributeDescriptions = inputAttributes.Length > 0 ? (VkVertexInputAttributeDescription *)Core.Interop.Fixed(inputAttributes) : null, vertexBindingDescriptionCount = (uint)inputBindingCount, pVertexBindingDescriptions = inputBindings.Length > 0 ? (VkVertexInputBindingDescription *)Core.Interop.Fixed(inputBindings) : null, }; var colorBlendState = new VkPipelineColorBlendStateCreateInfo { sType = VkStructureType.PipelineColorBlendStateCreateInfo, attachmentCount = (uint)renderTargetCount, pAttachments = colorBlendAttachments.Length > 0 ? (VkPipelineColorBlendAttachmentState *)Core.Interop.Fixed(colorBlendAttachments) : null, }; var dynamicState = new VkPipelineDynamicStateCreateInfo { sType = VkStructureType.PipelineDynamicStateCreateInfo, dynamicStateCount = (uint)dynamicStates.Length, pDynamicStates = dynamicStatesPointer, }; var createInfo = new VkGraphicsPipelineCreateInfo { sType = VkStructureType.GraphicsPipelineCreateInfo, layout = NativeLayout, stageCount = (uint)stages.Length, pStages = stages.Length > 0 ? (VkPipelineShaderStageCreateInfo *)Core.Interop.Fixed(stages) : null, //tessellationState = &tessellationState, pVertexInputState = &vertexInputState, pInputAssemblyState = &inputAssemblyState, pRasterizationState = &rasterizationState, pMultisampleState = &multisampleState, pDepthStencilState = &depthStencilState, pColorBlendState = &colorBlendState, pDynamicState = &dynamicState, pViewportState = &viewportState, renderPass = NativeRenderPass, subpass = 0, }; fixed(VkPipeline *nativePipelinePtr = &NativePipeline) vkCreateGraphicsPipelines(GraphicsDevice.NativeDevice, VkPipelineCache.Null, 1, &createInfo, null, nativePipelinePtr); } // Cleanup shader modules foreach (var stage in stages) { vkDestroyShaderModule(GraphicsDevice.NativeDevice, stage.module, null); } }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = Initializers.pipelineInputAssemblyStateCreateInfo( VkPrimitiveTopology.TriangleList, 0, False); VkPipelineRasterizationStateCreateInfo rasterizationState = Initializers.pipelineRasterizationStateCreateInfo( VkPolygonMode.Fill, VkCullModeFlags.Back, VkFrontFace.Clockwise, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = Initializers.pipelineColorBlendAttachmentState( 0xf, False); VkPipelineColorBlendStateCreateInfo colorBlendState = Initializers.pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = Initializers.pipelineDepthStencilStateCreateInfo( True, True, VkCompareOp.LessOrEqual); VkPipelineViewportStateCreateInfo viewportState = Initializers.pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = Initializers.pipelineMultisampleStateCreateInfo( VkSampleCountFlags.Count1, 0); FixedArray2 <VkDynamicState> dynamicStateEnables = new FixedArray2 <VkDynamicState>( VkDynamicState.Viewport, VkDynamicState.Scissor); VkPipelineDynamicStateCreateInfo dynamicState = Initializers.pipelineDynamicStateCreateInfo( &dynamicStateEnables.First, dynamicStateEnables.Count, 0); // Solid rendering pipeline // Load shaders FixedArray2 <VkPipelineShaderStageCreateInfo> shaderStages = new FixedArray2 <VkPipelineShaderStageCreateInfo>( loadShader(getAssetPath() + "shaders/mesh/mesh.vert.spv", VkShaderStageFlags.Vertex), loadShader(getAssetPath() + "shaders/mesh/mesh.frag.spv", VkShaderStageFlags.Fragment)); VkGraphicsPipelineCreateInfo pipelineCreateInfo = Initializers.pipelineCreateInfo( pipelineLayout, renderPass, 0); var via = vertices_inputState; pipelineCreateInfo.pVertexInputState = &via; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = shaderStages.Count; pipelineCreateInfo.pStages = &shaderStages.First; Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_solid)); // Wire frame rendering pipeline if (DeviceFeatures.fillModeNonSolid == 1) { rasterizationState.polygonMode = VkPolygonMode.Line; rasterizationState.lineWidth = 1.0f; Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_wireframe)); } }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = Initializers.pipelineInputAssemblyStateCreateInfo( VkPrimitiveTopology.TriangleList, 0, False); VkPipelineRasterizationStateCreateInfo rasterizationState = Initializers.pipelineRasterizationStateCreateInfo( VkPolygonMode.Fill, VkCullModeFlags.None, VkFrontFace.CounterClockwise, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = Initializers.pipelineColorBlendAttachmentState( (VkColorComponentFlags)0xf, False); VkPipelineColorBlendStateCreateInfo colorBlendState = Initializers.pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = Initializers.pipelineDepthStencilStateCreateInfo( True, True, VkCompareOp.LessOrEqual); VkPipelineViewportStateCreateInfo viewportState = Initializers.pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = Initializers.pipelineMultisampleStateCreateInfo( VkSampleCountFlags.Count1, 0); FixedArray2 <VkDynamicState> dynamicStateEnables = new FixedArray2 <VkDynamicState>( VkDynamicState.Viewport, VkDynamicState.Scissor); VkPipelineDynamicStateCreateInfo dynamicState = Initializers.pipelineDynamicStateCreateInfo( (VkDynamicState *)Unsafe.AsPointer(ref dynamicStateEnables), dynamicStateEnables.Count, 0); // Load shaders FixedArray2 <VkPipelineShaderStageCreateInfo> shaderStages = new FixedArray2 <VkPipelineShaderStageCreateInfo>(); shaderStages.First = loadShader(getAssetPath() + "shaders/texture/texture.vert.spv", VkShaderStageFlags.Vertex); shaderStages.Second = loadShader(getAssetPath() + "shaders/texture/texture.frag.spv", VkShaderStageFlags.Fragment); VkGraphicsPipelineCreateInfo pipelineCreateInfo = Initializers.pipelineCreateInfo( pipelineLayout, renderPass, 0); var vertexInputState = vertices.inputState; pipelineCreateInfo.pVertexInputState = &vertexInputState; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = shaderStages.Count; pipelineCreateInfo.pStages = (VkPipelineShaderStageCreateInfo *)Unsafe.AsPointer(ref shaderStages); Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_solid)); }
public static VkResult vkCreateGraphicsPipeline(VkDevice device, VkPipelineCache pipelineCache, VkGraphicsPipelineCreateInfo createInfo, out VkPipeline pipeline) { return(vkCreateGraphicsPipelines(device, pipelineCache, 1, &createInfo, null, out pipeline)); }
static internal VkPipeline[] CreatePipelinesInternal(Device device, GraphicsPipelineCreateInfo[] mInfos, VkPipelineCache cache) { int count = mInfos.Length; var infosMarshalled = new MarshalledArray <VkGraphicsPipelineCreateInfo>(count); var pipelineResults = new VkPipeline[count]; var marshalledArrays = new DisposableList <IDisposable>(count); for (int i = 0; i < count; i++) { VkGraphicsPipelineCreateInfo info = new VkGraphicsPipelineCreateInfo(); var mInfo = mInfos[i]; info.sType = VkStructureType.GraphicsPipelineCreateInfo; info.flags = mInfo.flags; int stagesCount = mInfo.stages.Count; var stagesMarshalled = new MarshalledArray <VkPipelineShaderStageCreateInfo>(stagesCount); for (int j = 0; j < stagesCount; j++) { stagesMarshalled[j] = mInfo.stages[j].GetNative(marshalledArrays); } info.stageCount = (uint)stagesCount; info.pStages = stagesMarshalled.Address; marshalledArrays.Add(stagesMarshalled); if (mInfo.vertexInputState != null) { var m = new Marshalled <VkPipelineVertexInputStateCreateInfo>(mInfo.vertexInputState.GetNative(marshalledArrays)); info.pVertexInputState = m.Address; marshalledArrays.Add(m); } if (mInfo.inputAssemblyState != null) { var m = new Marshalled <VkPipelineInputAssemblyStateCreateInfo>(mInfo.inputAssemblyState.GetNative()); info.pInputAssemblyState = m.Address; marshalledArrays.Add(m); } if (mInfo.tessellationState != null) { var m = new Marshalled <VkPipelineTessellationStateCreateInfo>(mInfo.tessellationState.GetNative()); info.pTessellationState = m.Address; marshalledArrays.Add(m); } if (mInfo.viewportState != null) { var m = new Marshalled <VkPipelineViewportStateCreateInfo>(mInfo.viewportState.GetNative(marshalledArrays)); info.pViewportState = m.Address; } if (mInfo.rasterizationState != null) { var m = new Marshalled <VkPipelineRasterizationStateCreateInfo>(mInfo.rasterizationState.GetNative()); info.pRasterizationState = m.Address; marshalledArrays.Add(m); } if (mInfo.multisampleState != null) { var m = new Marshalled <VkPipelineMultisampleStateCreateInfo>(mInfo.multisampleState.GetNative()); info.pMultisampleState = m.Address; marshalledArrays.Add(m); } if (mInfo.depthStencilState != null) { var m = new Marshalled <VkPipelineDepthStencilStateCreateInfo>(mInfo.depthStencilState.GetNative()); info.pDepthStencilState = m.Address; marshalledArrays.Add(m); } if (mInfo.colorBlendState != null) { var m = new Marshalled <VkPipelineColorBlendStateCreateInfo>(mInfo.colorBlendState.GetNative(marshalledArrays)); info.pColorBlendState = m.Address; marshalledArrays.Add(m); } if (mInfo.dynamicState != null) { var m = new Marshalled <VkPipelineDynamicStateCreateInfo>(mInfo.dynamicState.GetNative(marshalledArrays)); info.pDynamicState = m.Address; marshalledArrays.Add(m); } info.layout = mInfo.layout.Native; if (mInfo.renderPass != null) { info.renderPass = mInfo.renderPass.Native; } info.subpass = mInfo.subpass; if (mInfo.basePipelineHandle != null) { info.basePipelineHandle = mInfo.basePipelineHandle.Native; } info.basePipelineIndex = mInfo.basePipelineIndex; infosMarshalled[i] = info; } using (infosMarshalled) using (marshalledArrays) using (var pipelinesMarshalled = new PinnedArray <VkPipeline>(pipelineResults)) { var result = device.Commands.createGraphicsPiplines( device.Native, cache, (uint)count, infosMarshalled.Address, device.Instance.AllocationCallbacks, pipelinesMarshalled.Address); if (result != VkResult.Success) { throw new PipelineException(string.Format("Error creating pipeline: {0}", result)); } return(pipelineResults); } }
public static VkResult Create(SoftwareDevice softwareDevice, VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo, out VkPipeline pipeline) { pipeline = new SoftwareGraphicsPipeline(softwareDevice, graphicsPipelineCreateInfo); return(VkResult.VK_SUCCESS); }
private SoftwareGraphicsPipeline(SoftwareDevice softwareDevice, VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo) { this.m_softwareDevice = softwareDevice; this.m_graphicsPipelineCreateInfo = graphicsPipelineCreateInfo; }
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; } }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = Initializers.pipelineInputAssemblyStateCreateInfo( VkPrimitiveTopology.TriangleList, 0, False); VkPipelineRasterizationStateCreateInfo rasterizationState = Initializers.pipelineRasterizationStateCreateInfo( VkPolygonMode.Fill, VkCullModeFlags.Back, VkFrontFace.Clockwise, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = Initializers.pipelineColorBlendAttachmentState( (VkColorComponentFlags)0xf, False); VkPipelineColorBlendStateCreateInfo colorBlendState = Initializers.pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = Initializers.pipelineDepthStencilStateCreateInfo( True, True, VkCompareOp.LessOrEqual); VkPipelineViewportStateCreateInfo viewportState = Initializers.pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = Initializers.pipelineMultisampleStateCreateInfo(VkSampleCountFlags._1); FixedArray3 <VkDynamicState> dynamicStateEnables = new FixedArray3 <VkDynamicState>( VkDynamicState.Viewport, VkDynamicState.Scissor, VkDynamicState.LineWidth); VkPipelineDynamicStateCreateInfo dynamicState = Initializers.pipelineDynamicStateCreateInfo((VkDynamicState *)Unsafe.AsPointer(ref dynamicStateEnables), dynamicStateEnables.Count); VkGraphicsPipelineCreateInfo pipelineCreateInfo = Initializers.pipelineCreateInfo(pipelineLayout, RenderPass); FixedArray2 <VkPipelineShaderStageCreateInfo> shaderStages = new FixedArray2 <VkPipelineShaderStageCreateInfo>(); shaderStages.First = loadShader(getAssetPath() + "shaders/pipelines/phong.vert.spv", VkShaderStageFlags.Vertex); shaderStages.Second = loadShader(getAssetPath() + "shaders/pipelines/phong.frag.spv", VkShaderStageFlags.Fragment); pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = shaderStages.Count; pipelineCreateInfo.pStages = (VkPipelineShaderStageCreateInfo *)Unsafe.AsPointer(ref shaderStages); // Shared vertex bindings and attributes used by all pipelines // Binding description VkVertexInputBindingDescription vertexInputBindings = Initializers.vertexInputBindingDescription(VERTEX_BUFFER_BIND_ID, vertexLayout.GetStride(), VkVertexInputRate.Vertex); // Attribute descriptions FixedArray4 <VkVertexInputAttributeDescription> vertexInputAttributes = new FixedArray4 <VkVertexInputAttributeDescription> { First = Initializers.vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 0, VkFormat.R32g32b32Sfloat, 0), // Location 0: Position Second = Initializers.vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 1, VkFormat.R32g32b32Sfloat, sizeof(float) * 3), // Location 1: Color Third = Initializers.vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 2, VkFormat.R32g32Sfloat, sizeof(float) * 6), // Location 2 : Texture coordinates Fourth = Initializers.vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 3, VkFormat.R32g32b32Sfloat, sizeof(float) * 8), // Location 3 : Normal }; VkPipelineVertexInputStateCreateInfo vertexInputState = VkPipelineVertexInputStateCreateInfo.New(); vertexInputState.vertexBindingDescriptionCount = 1; vertexInputState.pVertexBindingDescriptions = &vertexInputBindings; vertexInputState.vertexAttributeDescriptionCount = vertexInputAttributes.Count; vertexInputState.pVertexAttributeDescriptions = (VkVertexInputAttributeDescription *)Unsafe.AsPointer(ref vertexInputAttributes); pipelineCreateInfo.pVertexInputState = &vertexInputState; // Create the graphics pipeline state objects // We are using this pipeline as the base for the other pipelines (derivatives) // Pipeline derivatives can be used for pipelines that share most of their state // Depending on the implementation this may result in better performance for pipeline // switchting and faster creation time pipelineCreateInfo.flags = VkPipelineCreateFlags.AllowDerivatives; // Textured pipeline // Phong shading pipeline shaderStages.First = loadShader(getAssetPath() + "shaders/pipelines/phong.vert.spv", VkShaderStageFlags.Vertex); shaderStages.Second = loadShader(getAssetPath() + "shaders/pipelines/phong.frag.spv", VkShaderStageFlags.Fragment); Util.CheckResult(vkCreateGraphicsPipelines(Device, PipelineCache, 1, ref pipelineCreateInfo, null, out pipelines_phong)); // All pipelines created after the base pipeline will be derivatives pipelineCreateInfo.flags = VkPipelineCreateFlags.Derivative; // Base pipeline will be our first created pipeline pipelineCreateInfo.basePipelineHandle = pipelines_phong; // It's only allowed to either use a handle or index for the base pipeline // As we use the handle, we must set the index to -1 (see section 9.5 of the specification) pipelineCreateInfo.basePipelineIndex = -1; // Toon shading pipeline shaderStages.First = loadShader(getAssetPath() + "shaders/pipelines/toon.vert.spv", VkShaderStageFlags.Vertex); shaderStages.Second = loadShader(getAssetPath() + "shaders/pipelines/toon.frag.spv", VkShaderStageFlags.Fragment); Util.CheckResult(vkCreateGraphicsPipelines(Device, PipelineCache, 1, ref pipelineCreateInfo, null, out pipelines_toon)); // Pipeline for wire frame rendering // Non solid rendering is not a mandatory Vulkan feature if (DeviceFeatures.fillModeNonSolid != 0) { rasterizationState.polygonMode = VkPolygonMode.Line; shaderStages.First = loadShader(getAssetPath() + "shaders/pipelines/wireframe.vert.spv", VkShaderStageFlags.Vertex); shaderStages.Second = loadShader(getAssetPath() + "shaders/pipelines/wireframe.frag.spv", VkShaderStageFlags.Fragment); Util.CheckResult(vkCreateGraphicsPipelines(Device, PipelineCache, 1, ref pipelineCreateInfo, null, out pipelines_wireframe)); } }
public override VkResult CreateGraphicsPipelines(VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo, out VkPipeline pipeline) { pipeline = new DummyGraphicsPipeline(this, graphicsPipelineCreateInfo); return(VkResult.VK_SUCCESS); }
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); }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = Initializers.pipelineInputAssemblyStateCreateInfo( VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationState = Initializers.pipelineRasterizationStateCreateInfo( VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = Initializers.pipelineColorBlendAttachmentState( 0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendState = Initializers.pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = Initializers.pipelineDepthStencilStateCreateInfo( VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportState = Initializers.pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = Initializers.pipelineMultisampleStateCreateInfo( VK_SAMPLE_COUNT_1_BIT, 0); NativeList <VkDynamicState> dynamicStateEnables = new NativeList <VkDynamicState> { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicState = Initializers.pipelineDynamicStateCreateInfo( (VkDynamicState *)dynamicStateEnables.Data, dynamicStateEnables.Count, 0); FixedArray2 <VkPipelineShaderStageCreateInfo> shaderStages = new FixedArray2 <VkPipelineShaderStageCreateInfo>(); VkGraphicsPipelineCreateInfo pipelineCreateInfo = Initializers.pipelineCreateInfo( pipelineLayouts_radialBlur, renderPass, 0); pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = shaderStages.Count; pipelineCreateInfo.pStages = &shaderStages.First; // Radial blur pipeline shaderStages.First = loadShader(getAssetPath() + "shaders/radialblur/radialblur.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages.Second = loadShader(getAssetPath() + "shaders/radialblur/radialblur.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); // Empty vertex input state VkPipelineVertexInputStateCreateInfo emptyInputState = Initializers.pipelineVertexInputStateCreateInfo(); pipelineCreateInfo.pVertexInputState = &emptyInputState; pipelineCreateInfo.layout = pipelineLayouts_radialBlur; // Additive blending blendAttachmentState.colorWriteMask = (VkColorComponentFlags)0xF; blendAttachmentState.blendEnable = VK_TRUE; blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD; blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE; blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD; blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_DST_ALPHA; Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_radialBlur)); // No blending (for debug display) blendAttachmentState.blendEnable = VK_FALSE; Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_offscreenDisplay)); // Phong pass pipelineCreateInfo.layout = pipelineLayouts_scene; shaderStages.First = loadShader(getAssetPath() + "shaders/radialblur/phongpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages.Second = loadShader(getAssetPath() + "shaders/radialblur/phongpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); var vis = vertices_inputState; pipelineCreateInfo.pVertexInputState = &vis; blendAttachmentState.blendEnable = VK_FALSE; depthStencilState.depthWriteEnable = VK_TRUE; Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_phongPass)); // Color only pass (offscreen blur base) shaderStages.First = loadShader(getAssetPath() + "shaders/radialblur/colorpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages.Second = loadShader(getAssetPath() + "shaders/radialblur/colorpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); pipelineCreateInfo.renderPass = offscreenPass.renderPass; Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_colorPass)); }
//[HandleProcessCorruptedStateExceptionsAttribute, SecurityCriticalAttribute] private unsafe void Recreate() { errorDuringCreate = false; if (Description.RootSignature == null) { return; } VkPipelineShaderStageCreateInfo[] stages; // create render pass bool hasDepthStencilAttachment = Description.Output.DepthStencilFormat != PixelFormat.None; var renderTargetCount = Description.Output.RenderTargetCount; var attachmentCount = renderTargetCount; if (hasDepthStencilAttachment) { attachmentCount++; } var attachments = new VkAttachmentDescription[attachmentCount]; var colorAttachmentReferences = new VkAttachmentReference[renderTargetCount]; fixed(PixelFormat *renderTargetFormat = &Description.Output.RenderTargetFormat0) fixed(BlendStateRenderTargetDescription * blendDescription = &Description.BlendState.RenderTarget0) { for (int i = 0; i < renderTargetCount; i++) { var currentBlendDesc = Description.BlendState.IndependentBlendEnable ? (blendDescription + i) : blendDescription; attachments[i] = new VkAttachmentDescription { format = VulkanConvertExtensions.ConvertPixelFormat(*(renderTargetFormat + i)), samples = VkSampleCountFlags.Count1, loadOp = currentBlendDesc->BlendEnable ? VkAttachmentLoadOp.Load : VkAttachmentLoadOp.DontCare, // TODO VULKAN: Only if any destination blend? storeOp = VkAttachmentStoreOp.Store, stencilLoadOp = VkAttachmentLoadOp.DontCare, stencilStoreOp = VkAttachmentStoreOp.DontCare, initialLayout = VkImageLayout.ColorAttachmentOptimal, finalLayout = VkImageLayout.ColorAttachmentOptimal, }; colorAttachmentReferences[i] = new VkAttachmentReference { attachment = (uint)i, layout = VkImageLayout.ColorAttachmentOptimal, }; } } if (hasDepthStencilAttachment) { attachments[attachmentCount - 1] = new VkAttachmentDescription { format = Texture.GetFallbackDepthStencilFormat(GraphicsDevice, VulkanConvertExtensions.ConvertPixelFormat(Description.Output.DepthStencilFormat)), samples = VkSampleCountFlags.Count1, loadOp = VkAttachmentLoadOp.Load, // TODO VULKAN: Only if depth read enabled? storeOp = VkAttachmentStoreOp.Store, // TODO VULKAN: Only if depth write enabled? stencilLoadOp = VkAttachmentLoadOp.DontCare, // TODO VULKAN: Handle stencil stencilStoreOp = VkAttachmentStoreOp.DontCare, initialLayout = VkImageLayout.DepthStencilAttachmentOptimal, finalLayout = VkImageLayout.DepthStencilAttachmentOptimal, }; } var depthAttachmentReference = new VkAttachmentReference { attachment = (uint)attachments.Length - 1, layout = VkImageLayout.DepthStencilAttachmentOptimal, }; var subpass = new VkSubpassDescription { pipelineBindPoint = VkPipelineBindPoint.Graphics, colorAttachmentCount = (uint)renderTargetCount, pColorAttachments = colorAttachmentReferences.Length > 0 ? (VkAttachmentReference *)Core.Interop.Fixed(colorAttachmentReferences) : null, pDepthStencilAttachment = hasDepthStencilAttachment ? &depthAttachmentReference : null, }; var renderPassCreateInfo = new VkRenderPassCreateInfo { sType = VkStructureType.RenderPassCreateInfo, attachmentCount = (uint)attachmentCount, pAttachments = attachments.Length > 0 ? (VkAttachmentDescription *)Core.Interop.Fixed(attachments) : null, subpassCount = 1, pSubpasses = &subpass, }; // create pipeline layout // Remap descriptor set indices to those in the shader. This ordering generated by the ShaderCompiler var resourceGroups = Description.EffectBytecode.Reflection.ResourceBindings.Select(x => x.ResourceGroup ?? "Globals").Distinct().ToList(); ResourceGroupCount = resourceGroups.Count; var layouts = Description.RootSignature.EffectDescriptorSetReflection.Layouts; // Get binding indices used by the shader var destinationBindings = Description.EffectBytecode.Stages .SelectMany(x => BinarySerialization.Read <ShaderInputBytecode>(x.Data).ResourceBindings) .GroupBy(x => x.Key, x => x.Value) .ToDictionary(x => x.Key, x => x.First()); var maxBindingIndex = destinationBindings.Max(x => x.Value); var destinationEntries = new DescriptorSetLayoutBuilder.Entry[maxBindingIndex + 1]; DescriptorBindingMapping = new List <DescriptorSetInfo>(); for (int i = 0; i < resourceGroups.Count; i++) { var resourceGroupName = resourceGroups[i] == "Globals" ? Description.RootSignature.EffectDescriptorSetReflection.DefaultSetSlot : resourceGroups[i]; var layoutIndex = resourceGroups[i] == null ? 0 : layouts.FindIndex(x => x.Name == resourceGroupName); // Check if the resource group is used by the shader if (layoutIndex == -1) { continue; } var sourceEntries = layouts[layoutIndex].Layout.Entries; for (int sourceBinding = 0; sourceBinding < sourceEntries.Count; sourceBinding++) { var sourceEntry = sourceEntries[sourceBinding]; int destinationBinding; if (destinationBindings.TryGetValue(sourceEntry.Key.Name, out destinationBinding)) { destinationEntries[destinationBinding] = sourceEntry; // No need to umpdate immutable samplers if (sourceEntry.Class == EffectParameterClass.Sampler && sourceEntry.ImmutableSampler != null) { continue; } DescriptorBindingMapping.Add(new DescriptorSetInfo { SourceSet = layoutIndex, SourceBinding = sourceBinding, DestinationBinding = destinationBinding, DescriptorType = VulkanConvertExtensions.ConvertDescriptorType(sourceEntry.Class, sourceEntry.Type) }); } } } // Create default sampler, used by texture and buffer loads destinationEntries[0] = new DescriptorSetLayoutBuilder.Entry { Class = EffectParameterClass.Sampler, Type = EffectParameterType.Sampler, ImmutableSampler = GraphicsDevice.SamplerStates.PointWrap, ArraySize = 1, }; // Create descriptor set layout NativeDescriptorSetLayout = DescriptorSetLayout.CreateNativeDescriptorSetLayout(GraphicsDevice, destinationEntries, out DescriptorTypeCounts); // Create pipeline layout var nativeDescriptorSetLayout = NativeDescriptorSetLayout; var pipelineLayoutCreateInfo = new VkPipelineLayoutCreateInfo { sType = VkStructureType.PipelineLayoutCreateInfo, setLayoutCount = 1, pSetLayouts = &nativeDescriptorSetLayout, }; // Create shader stages Dictionary <int, string> inputAttributeNames; // Note: important to pin this so that stages[x].Name is valid during this whole function void *defaultEntryPointData = Core.Interop.Fixed(defaultEntryPoint); stages = CreateShaderStages(Description, out inputAttributeNames); var inputAttributes = new VkVertexInputAttributeDescription[Description.InputElements.Length]; int inputAttributeCount = 0; var inputBindings = new VkVertexInputBindingDescription[inputAttributes.Length]; int inputBindingCount = 0; for (int inputElementIndex = 0; inputElementIndex < inputAttributes.Length; inputElementIndex++) { var inputElement = Description.InputElements[inputElementIndex]; var slotIndex = inputElement.InputSlot; if (inputElement.InstanceDataStepRate > 1) { throw new NotImplementedException(); } VkFormat format; int size; bool isCompressed; VulkanConvertExtensions.ConvertPixelFormat(inputElement.Format, out format, out size, out isCompressed); var location = inputAttributeNames.FirstOrDefault(x => x.Value == inputElement.SemanticName && inputElement.SemanticIndex == 0 || x.Value == inputElement.SemanticName + inputElement.SemanticIndex); if (location.Value != null) { inputAttributes[inputAttributeCount++] = new VkVertexInputAttributeDescription { format = format, offset = (uint)inputElement.AlignedByteOffset, binding = (uint)inputElement.InputSlot, location = (uint)location.Key }; } inputBindings[slotIndex].binding = (uint)slotIndex; inputBindings[slotIndex].inputRate = inputElement.InputSlotClass == InputClassification.Vertex ? VkVertexInputRate.Vertex : VkVertexInputRate.Instance; // TODO VULKAN: This is currently an argument to Draw() overloads. if (inputBindings[slotIndex].stride < inputElement.AlignedByteOffset + size) { inputBindings[slotIndex].stride = (uint)(inputElement.AlignedByteOffset + size); } if (inputElement.InputSlot >= inputBindingCount) { inputBindingCount = inputElement.InputSlot + 1; } } var inputAssemblyState = new VkPipelineInputAssemblyStateCreateInfo { sType = VkStructureType.PipelineInputAssemblyStateCreateInfo, topology = VulkanConvertExtensions.ConvertPrimitiveType(Description.PrimitiveType), primitiveRestartEnable = VulkanConvertExtensions.ConvertPrimitiveRestart(Description.PrimitiveType) ? (uint)1 : (uint)0, }; // TODO VULKAN: Tessellation and multisampling var multisampleState = new VkPipelineMultisampleStateCreateInfo { sType = VkStructureType.PipelineMultisampleStateCreateInfo, rasterizationSamples = VkSampleCountFlags.Count1, }; var rasterizationState = new VkPipelineRasterizationStateCreateInfo { sType = VkStructureType.PipelineRasterizationStateCreateInfo, cullMode = VulkanConvertExtensions.ConvertCullMode(Description.RasterizerState.CullMode), frontFace = Description.RasterizerState.FrontFaceCounterClockwise ? VkFrontFace.CounterClockwise : VkFrontFace.Clockwise, polygonMode = VulkanConvertExtensions.ConvertFillMode(Description.RasterizerState.FillMode), depthBiasEnable = 1, // TODO VULKAN depthBiasConstantFactor = Description.RasterizerState.DepthBias, depthBiasSlopeFactor = Description.RasterizerState.SlopeScaleDepthBias, depthBiasClamp = Description.RasterizerState.DepthBiasClamp, lineWidth = 1.0f, depthClampEnable = Description.RasterizerState.DepthClipEnable ? (uint)0 : (uint)1, rasterizerDiscardEnable = 0, }; var depthStencilState = new VkPipelineDepthStencilStateCreateInfo { sType = VkStructureType.PipelineDepthStencilStateCreateInfo, depthTestEnable = Description.DepthStencilState.DepthBufferEnable ? (uint)1 : (uint)0, stencilTestEnable = Description.DepthStencilState.StencilEnable ? (uint)1 : (uint)0, depthWriteEnable = Description.DepthStencilState.DepthBufferWriteEnable ? (uint)1 : (uint)0, minDepthBounds = 0.0f, maxDepthBounds = 1.0f, depthCompareOp = VulkanConvertExtensions.ConvertComparisonFunction(Description.DepthStencilState.DepthBufferFunction), front = { compareOp = VulkanConvertExtensions.ConvertComparisonFunction(Description.DepthStencilState.FrontFace.StencilFunction), depthFailOp = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.FrontFace.StencilDepthBufferFail), failOp = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.FrontFace.StencilFail), passOp = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.FrontFace.StencilPass), compareMask = Description.DepthStencilState.StencilMask, writeMask = Description.DepthStencilState.StencilWriteMask }, back = { compareOp = VulkanConvertExtensions.ConvertComparisonFunction(Description.DepthStencilState.BackFace.StencilFunction), depthFailOp = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.BackFace.StencilDepthBufferFail), failOp = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.BackFace.StencilFail), passOp = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.BackFace.StencilPass), compareMask = Description.DepthStencilState.StencilMask, writeMask = Description.DepthStencilState.StencilWriteMask } }; var description = Description.BlendState; var colorBlendAttachments = new VkPipelineColorBlendAttachmentState[renderTargetCount]; var renderTargetBlendState = &description.RenderTarget0; for (int i = 0; i < renderTargetCount; i++) { colorBlendAttachments[i] = new VkPipelineColorBlendAttachmentState { blendEnable = renderTargetBlendState->BlendEnable ? (uint)1 : (uint)0, alphaBlendOp = VulkanConvertExtensions.ConvertBlendFunction(renderTargetBlendState->AlphaBlendFunction), colorBlendOp = VulkanConvertExtensions.ConvertBlendFunction(renderTargetBlendState->ColorBlendFunction), dstAlphaBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->AlphaDestinationBlend), dstColorBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->ColorDestinationBlend), srcAlphaBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->AlphaSourceBlend), srcColorBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->ColorSourceBlend), colorWriteMask = VulkanConvertExtensions.ConvertColorWriteChannels(renderTargetBlendState->ColorWriteChannels), }; if (description.IndependentBlendEnable) { renderTargetBlendState++; } } var viewportState = new VkPipelineViewportStateCreateInfo { sType = VkStructureType.PipelineViewportStateCreateInfo, scissorCount = 1, viewportCount = 1, }; fixed(void *dynamicStatesPointer = dynamicStates.Length == 0?null : dynamicStates, inputAttributesPointer = inputAttributes.Length == 0?null : inputAttributes, inputBindingsPointer = inputBindings.Length == 0?null : inputBindings, colorBlendAttachmentsPointer = colorBlendAttachments.Length == 0?null : colorBlendAttachments, stagesPointer = stages.Length == 0?null : stages) { var vertexInputState = new VkPipelineVertexInputStateCreateInfo { sType = VkStructureType.PipelineVertexInputStateCreateInfo, vertexAttributeDescriptionCount = (uint)inputAttributeCount, pVertexAttributeDescriptions = (Vortice.Vulkan.VkVertexInputAttributeDescription *)inputAttributesPointer, vertexBindingDescriptionCount = (uint)inputBindingCount, pVertexBindingDescriptions = (Vortice.Vulkan.VkVertexInputBindingDescription *)inputBindingsPointer, }; var colorBlendState = new VkPipelineColorBlendStateCreateInfo { sType = VkStructureType.PipelineColorBlendStateCreateInfo, attachmentCount = (uint)renderTargetCount, pAttachments = (Vortice.Vulkan.VkPipelineColorBlendAttachmentState *)colorBlendAttachmentsPointer, }; var dynamicState = new VkPipelineDynamicStateCreateInfo { sType = VkStructureType.PipelineDynamicStateCreateInfo, dynamicStateCount = (uint)dynamicStates.Length, pDynamicStates = (Vortice.Vulkan.VkDynamicState *)dynamicStatesPointer, }; var createInfo = new VkGraphicsPipelineCreateInfo { sType = VkStructureType.GraphicsPipelineCreateInfo, layout = NativeLayout, stageCount = (uint)stages.Length, pVertexInputState = &vertexInputState, pInputAssemblyState = &inputAssemblyState, pRasterizationState = &rasterizationState, pMultisampleState = &multisampleState, pDepthStencilState = &depthStencilState, pColorBlendState = &colorBlendState, pDynamicState = &dynamicState, pStages = (Vortice.Vulkan.VkPipelineShaderStageCreateInfo *)stagesPointer, pViewportState = &viewportState, renderPass = NativeRenderPass, subpass = 0, }; using (GraphicsDevice.QueueLock.ReadLock()) { vkCreateRenderPass(GraphicsDevice.NativeDevice, &renderPassCreateInfo, null, out NativeRenderPass); vkCreatePipelineLayout(GraphicsDevice.NativeDevice, &pipelineLayoutCreateInfo, null, out NativeLayout); createInfo.layout = NativeLayout; createInfo.renderPass = NativeRenderPass; try { fixed(VkPipeline *nativePipelinePtr = &NativePipeline) vkCreateGraphicsPipelines(GraphicsDevice.NativeDevice, VkPipelineCache.Null, 1, &createInfo, null, nativePipelinePtr); } catch (Exception e) { errorDuringCreate = true; NativePipeline = VkPipeline.Null; } } } // Cleanup shader modules for (int i = 0; i < stages.Length; i++) { vkDestroyShaderModule(GraphicsDevice.NativeDevice, stages[i].module, null); } }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = Initializers.pipelineInputAssemblyStateCreateInfo( VkPrimitiveTopology.TriangleList, 0, False); VkPipelineRasterizationStateCreateInfo rasterizationState = Initializers.pipelineRasterizationStateCreateInfo( VkPolygonMode.Fill, VkCullModeFlags.Back, VkFrontFace.CounterClockwise, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = Initializers.pipelineColorBlendAttachmentState( (VkColorComponentFlags)0xf, False); VkPipelineColorBlendStateCreateInfo colorBlendState = Initializers.pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = Initializers.pipelineDepthStencilStateCreateInfo( False, False, VkCompareOp.LessOrEqual); VkPipelineViewportStateCreateInfo viewportState = Initializers.pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = Initializers.pipelineMultisampleStateCreateInfo( VkSampleCountFlags.Count1, 0); FixedArray2<VkDynamicState> dynamicStateEnables = new FixedArray2<VkDynamicState>( VkDynamicState.Viewport, VkDynamicState.Scissor); VkPipelineDynamicStateCreateInfo dynamicState = Initializers.pipelineDynamicStateCreateInfo( &dynamicStateEnables.First, dynamicStateEnables.Count, 0); // Skybox pipeline (background cube) FixedArray2<VkPipelineShaderStageCreateInfo> shaderStages = new FixedArray2<VkPipelineShaderStageCreateInfo>( loadShader(getAssetPath() + "shaders/cubemap/skybox.vert.spv", VkShaderStageFlags.Vertex), loadShader(getAssetPath() + "shaders/cubemap/skybox.frag.spv", VkShaderStageFlags.Fragment)); VkGraphicsPipelineCreateInfo pipelineCreateInfo = Initializers.pipelineCreateInfo( pipelineLayout, renderPass, 0); var inputState = vertices.inputState; pipelineCreateInfo.pVertexInputState = &inputState; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = shaderStages.Count; pipelineCreateInfo.pStages = &shaderStages.First; Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_skybox)); // Cube map reflect pipeline shaderStages.First = loadShader(getAssetPath() + "shaders/cubemap/reflect.vert.spv", VkShaderStageFlags.Vertex); shaderStages.Second = loadShader(getAssetPath() + "shaders/cubemap/reflect.frag.spv", VkShaderStageFlags.Fragment); // Enable depth test and write depthStencilState.depthWriteEnable = True; depthStencilState.depthTestEnable = True; // Flip cull mode rasterizationState.cullMode = VkCullModeFlags.Front; Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_reflect)); }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = Initializers.pipelineInputAssemblyStateCreateInfo( VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, False); VkPipelineRasterizationStateCreateInfo rasterizationState = Initializers.pipelineRasterizationStateCreateInfo( VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = Initializers.pipelineColorBlendAttachmentState( 0xf, False); VkPipelineColorBlendStateCreateInfo colorBlendState = Initializers.pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = Initializers.pipelineDepthStencilStateCreateInfo( True, True, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportState = Initializers.pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = Initializers.pipelineMultisampleStateCreateInfo( VK_SAMPLE_COUNT_1_BIT, 0); FixedArray3 <VkDynamicState> dynamicStateEnables = new FixedArray3 <VkDynamicState>( VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH); VkPipelineDynamicStateCreateInfo dynamicState = Initializers.pipelineDynamicStateCreateInfo( &dynamicStateEnables.First, dynamicStateEnables.Count, 0); FixedArray2 <VkPipelineShaderStageCreateInfo> shaderStages = new FixedArray2 <VkPipelineShaderStageCreateInfo>(); VkGraphicsPipelineCreateInfo pipelineCreateInfo = Initializers.pipelineCreateInfo( pipelineLayout, renderPass, 0); var vis = vertices_inputState; pipelineCreateInfo.pVertexInputState = &vis; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = shaderStages.Count; pipelineCreateInfo.pStages = &shaderStages.First; // Prepare specialization data SpecializationData specializationData = SpecializationData.Default; // Each shader constant of a shader stage corresponds to one map entry FixedArray2 <VkSpecializationMapEntry> specializationMapEntries = new FixedArray2 <VkSpecializationMapEntry>(); // Shader bindings based on specialization constants are marked by the new "constant_id" layout qualifier: // layout (constant_id = 0) const int LIGHTING_MODEL = 0; // layout (constant_id = 1) const float PARAM_TOON_DESATURATION = 0.0f; // Map entry for the lighting model to be used by the fragment shader specializationMapEntries.First.constantID = 0; specializationMapEntries.First.size = (UIntPtr)sizeof(uint); specializationMapEntries.First.offset = 0; // Map entry for the toon shader parameter specializationMapEntries.Second.constantID = 1; specializationMapEntries.Second.size = (UIntPtr)sizeof(float); specializationMapEntries.Second.offset = (sizeof(uint)); // Prepare specialization info block for the shader stage VkSpecializationInfo specializationInfo = new VkSpecializationInfo(); specializationInfo.dataSize = (UIntPtr)sizeof(SpecializationData); specializationInfo.mapEntryCount = specializationMapEntries.Count; specializationInfo.pMapEntries = &specializationMapEntries.First; specializationInfo.pData = &specializationData; // Create pipelines // All pipelines will use the same "uber" shader and specialization constants to change branching and parameters of that shader shaderStages.First = loadShader(getAssetPath() + "shaders/specializationconstants/uber.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages.Second = loadShader(getAssetPath() + "shaders/specializationconstants/uber.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); // Specialization info is assigned is part of the shader stage (modul) and must be set after creating the module and before creating the pipeline shaderStages.Second.pSpecializationInfo = &specializationInfo; // Solid phong shading specializationData.lightingModel = 0; Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_phong)); // Phong and textured specializationData.lightingModel = 1; Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_toon)); // Textured discard specializationData.lightingModel = 2; Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_textured)); }
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 DummyGraphicsPipeline(DummyDevice device, VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo) { this.m_device = device; this.m_graphicsPipelineCreateInfo = graphicsPipelineCreateInfo; }
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); }
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(); }
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; } }
public static VkResult vkCreateGraphicsPipeline(VkDevice device, VkPipelineCache pipelineCache, VkGraphicsPipelineCreateInfo createInfo, out VkPipeline pipeline) { VkPipeline pinPipeline; var result = vkCreateGraphicsPipelines(device, pipelineCache, 1, &createInfo, null, &pinPipeline); pipeline = pinPipeline; return(result); }
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); }
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); }