protected virtual void SetupInstancedVertexDescriptions() { // Binding description vertices_bindingDescriptions.Count = 2; vertices_bindingDescriptions[0] = Initializers.vertexInputBindingDescription( Pipeline.VERTEX_DATA_BUFFER_BIND_ID, (uint)sizeof(Vertex), VkVertexInputRate.Vertex); vertices_bindingDescriptions[1] = Initializers.vertexInputBindingDescription( Pipeline.VERTEX_INSTANCE_BUFFER_BIND_ID, (uint)sizeof(ObjectToWorld), VkVertexInputRate.Instance); // Attribute descriptions // Describes memory layout and shader positions vertices_attributeDescriptions.Count = 10; // Location 0 : Position vertices_attributeDescriptions[0] = Initializers.vertexInputAttributeDescription( Pipeline.VERTEX_DATA_BUFFER_BIND_ID, 0, VkFormat.R32g32b32Sfloat, 0); // Location 1 : Normal vertices_attributeDescriptions[1] = Initializers.vertexInputAttributeDescription( Pipeline.VERTEX_DATA_BUFFER_BIND_ID, 1, VkFormat.R32g32b32Sfloat, 12); // Location 2 : Texture coordinates vertices_attributeDescriptions[2] = Initializers.vertexInputAttributeDescription( Pipeline.VERTEX_DATA_BUFFER_BIND_ID, 2, VkFormat.R32g32Sfloat, 24); // Location 3 : Color //vertices_attributeDescriptions[3] = // Initializers.vertexInputAttributeDescription( // Pipeline.VERTEX_DATA_BUFFER_BIND_ID, // 3, // VkFormat.R32g32b32Sfloat, // 32); //Location 3-9 Instance model matrix and normal matrix vertices_attributeDescriptions[3] = Initializers.vertexInputAttributeDescription( Pipeline.VERTEX_INSTANCE_BUFFER_BIND_ID, 3, VkFormat.R32g32b32a32Sfloat, 0); vertices_attributeDescriptions[4] = Initializers.vertexInputAttributeDescription( Pipeline.VERTEX_INSTANCE_BUFFER_BIND_ID, 4, VkFormat.R32g32b32a32Sfloat, 16); vertices_attributeDescriptions[5] = Initializers.vertexInputAttributeDescription( Pipeline.VERTEX_INSTANCE_BUFFER_BIND_ID, 5, VkFormat.R32g32b32a32Sfloat, 32); vertices_attributeDescriptions[6] = Initializers.vertexInputAttributeDescription( Pipeline.VERTEX_INSTANCE_BUFFER_BIND_ID, 6, VkFormat.R32g32b32a32Sfloat, 48); vertices_attributeDescriptions[7] = Initializers.vertexInputAttributeDescription( Pipeline.VERTEX_INSTANCE_BUFFER_BIND_ID, 7, VkFormat.R32g32b32Sfloat, 64); vertices_attributeDescriptions[8] = Initializers.vertexInputAttributeDescription( Pipeline.VERTEX_INSTANCE_BUFFER_BIND_ID, 8, VkFormat.R32g32b32Sfloat, 76); vertices_attributeDescriptions[9] = Initializers.vertexInputAttributeDescription( Pipeline.VERTEX_INSTANCE_BUFFER_BIND_ID, 9, VkFormat.R32g32b32Sfloat, 88); vertices_inputState = Initializers.pipelineVertexInputStateCreateInfo(); vertices_inputState.vertexBindingDescriptionCount = (vertices_bindingDescriptions.Count); vertices_inputState.pVertexBindingDescriptions = (VkVertexInputBindingDescription *)vertices_bindingDescriptions.Data; vertices_inputState.vertexAttributeDescriptionCount = (vertices_attributeDescriptions.Count); vertices_inputState.pVertexAttributeDescriptions = (VkVertexInputAttributeDescription *)vertices_attributeDescriptions.Data; }
private void createGraphicsPipeline() { var vertShaderModule = createShaderModule(typeof(Shader_Vert_02)); var fragShaderModule = createShaderModule(typeof(Shader_Frag_02)); 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; vertexInputInfo.vertexBindingDescriptionCount = 0; vertexInputInfo.vertexAttributeDescriptionCount = 0; 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); }
public static VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo() { VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo = VkPipelineVertexInputStateCreateInfo.New(); return(pipelineVertexInputStateCreateInfo); }
private VkPipeline CreateGraphicsPipeline() { // Create shader modules. Shader modules are one of the objects required to create the // graphics pipeline. But after the pipeline is created, we don't need these shader // modules anymore, so we dispose them. VkShaderModule vertexShader = Content.LoadShader("Shader.vert.spv"); VkShaderModule fragmentShader = Content.LoadShader("Shader.frag.spv"); VkPipelineShaderStageCreateInfo *shaderStageCreateInfos = stackalloc VkPipelineShaderStageCreateInfo[2] { new VkPipelineShaderStageCreateInfo { sType = VkStructureType.PipelineShaderStageCreateInfo, pNext = null, stage = VkShaderStageFlags.Vertex, module = vertexShader, pName = Interop.String.ToPointer("main") }, new VkPipelineShaderStageCreateInfo { sType = VkStructureType.PipelineShaderStageCreateInfo, pNext = null, stage = VkShaderStageFlags.Fragment, module = fragmentShader, pName = Interop.String.ToPointer("main") } }; VkVertexInputBindingDescription vertexInputBindingDescription = new VkVertexInputBindingDescription { binding = 0, stride = (uint)Unsafe.SizeOf <Vertex>(), inputRate = VkVertexInputRate.Vertex }; VkVertexInputAttributeDescription *vertexInputAttributeDescription = stackalloc VkVertexInputAttributeDescription[3] { new VkVertexInputAttributeDescription { location = 0, binding = 0, format = VkFormat.R32G32B32A32SFloat, offset = 0 }, // Position. new VkVertexInputAttributeDescription { location = 1, binding = 0, format = VkFormat.R32G32B32SFloat, offset = 12 }, // Normal. new VkVertexInputAttributeDescription { location = 2, binding = 0, format = VkFormat.R32G32SFloat, offset = 24 }// TexCoord. }; var vertexInputStateCreateInfo = new VkPipelineVertexInputStateCreateInfo { sType = VkStructureType.PipelineVertexInputStateCreateInfo, pNext = null, vertexBindingDescriptionCount = 1, pVertexBindingDescriptions = &vertexInputBindingDescription, vertexAttributeDescriptionCount = 3, pVertexAttributeDescriptions = vertexInputAttributeDescription }; var inputAssemblyStateCreateInfo = new VkPipelineInputAssemblyStateCreateInfo { sType = VkStructureType.PipelineInputAssemblyStateCreateInfo, pNext = null, topology = VkPrimitiveTopology.TriangleList }; Viewport viewport = new Viewport(0, 0, Host.Width, Host.Height); Rectangle scissor = new Rectangle(0, 0, Host.Width, Host.Height); var viewportStateCreateInfo = new VkPipelineViewportStateCreateInfo { sType = VkStructureType.PipelineViewportStateCreateInfo, pNext = null, viewportCount = 1, pViewports = &viewport, scissorCount = 1, pScissors = &scissor }; var rasterizationStateCreateInfo = new VkPipelineRasterizationStateCreateInfo { sType = VkStructureType.PipelineRasterizationStateCreateInfo, polygonMode = VkPolygonMode.Fill, cullMode = VkCullModeFlags.Back, frontFace = VkFrontFace.CounterClockwise, lineWidth = 1.0f }; var multisampleStateCreateInfo = new VkPipelineMultisampleStateCreateInfo { sType = VkStructureType.PipelineMultisampleStateCreateInfo, rasterizationSamples = VkSampleCountFlags.Count1, minSampleShading = 1.0f }; var depthStencilStateCreateInfo = new VkPipelineDepthStencilStateCreateInfo { sType = VkStructureType.PipelineDepthStencilStateCreateInfo, depthTestEnable = true, depthWriteEnable = true, depthCompareOp = VkCompareOp.LessOrEqual, back = new VkStencilOpState { failOp = VkStencilOp.Keep, passOp = VkStencilOp.Keep, compareOp = VkCompareOp.Always }, front = new VkStencilOpState { failOp = VkStencilOp.Keep, passOp = VkStencilOp.Keep, compareOp = VkCompareOp.Always } }; var colorBlendAttachmentState = new VkPipelineColorBlendAttachmentState { srcColorBlendFactor = VkBlendFactor.One, dstColorBlendFactor = VkBlendFactor.Zero, colorBlendOp = VkBlendOp.Add, srcAlphaBlendFactor = VkBlendFactor.One, dstAlphaBlendFactor = VkBlendFactor.Zero, alphaBlendOp = VkBlendOp.Add, colorWriteMask = VkColorComponentFlags.All }; var colorBlendStateCreateInfo = new VkPipelineColorBlendStateCreateInfo { sType = VkStructureType.PipelineColorBlendStateCreateInfo, pNext = null, attachmentCount = 1, pAttachments = &colorBlendAttachmentState }; var pipelineCreateInfo = new VkGraphicsPipelineCreateInfo { sType = VkStructureType.GraphicsPipelineCreateInfo, pNext = null, layout = _pipelineLayout, renderPass = _renderPass, subpass = (uint)0, stageCount = 2, pStages = shaderStageCreateInfos, pInputAssemblyState = &inputAssemblyStateCreateInfo, pVertexInputState = &vertexInputStateCreateInfo, pRasterizationState = &rasterizationStateCreateInfo, pMultisampleState = &multisampleStateCreateInfo, pColorBlendState = &colorBlendStateCreateInfo, pDepthStencilState = &depthStencilStateCreateInfo, pViewportState = &viewportStateCreateInfo }; VkPipeline pipeline; VkResult result = vkCreateGraphicsPipelines(Context.Device, VkPipelineCache.Null, 1, &pipelineCreateInfo, null, &pipeline); result.CheckResult(); return(pipeline); } } }
public VkPipeline(VkGraphicsDevice gd, ref GraphicsPipelineDescription description) : base(ref description) { _gd = gd; IsComputePipeline = false; 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.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.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; 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 = 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 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 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; if (outputDesc.DepthAttachment != null) { subpassDependency.dstAccessMask |= VkAccessFlags.DepthStencilAttachmentRead | VkAccessFlags.DepthStencilAttachmentWrite; } renderPassCI.attachmentCount = attachments.Count; renderPassCI.pAttachments = (VkAttachmentDescription *)attachments.Data; renderPassCI.subpassCount = 1; renderPassCI.pSubpasses = &subpass; renderPassCI.dependencyCount = 1; renderPassCI.pDependencies = &subpassDependency; VkResult creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPass); CheckResult(creationResult); pipelineCI.renderPass = _renderPass; VkResult result = vkCreateGraphicsPipelines(_gd.Device, VkPipelineCache.Null, 1, ref pipelineCI, null, out _devicePipeline); CheckResult(result); ResourceSetCount = (uint)description.ResourceLayouts.Length; }
public Pipeline Build() { var stages = _stages.ToArray(); var vertexBindings = new VkVertexInputBindingDescription[_vertexBindingDescriptions.Count]; { var i = 0; foreach (var kv in _vertexBindingDescriptions) { vertexBindings[i++] = kv.Value; } } var attributeBindings = new VkVertexInputAttributeDescription[_vertexAttributeDescriptions.Count]; { var i = 0; foreach (var kv in _vertexAttributeDescriptions) { attributeBindings[i++] = kv.Value; } } var blendStates = new VkPipelineColorBlendAttachmentState[_blendAttachmentStates.Count]; foreach (var kv in _blendAttachmentStates) { blendStates[kv.Key] = kv.Value; } var viewports = _viewports.ToArray(); var scissors = _viewportScissors.ToArray(); var dynamicStates = _dynamicStates.ToArray(); try { unsafe { fixed(VkViewport *viewportPtr = viewports) fixed(VkRect2D * scissorPtr = scissors) fixed(VkDynamicState * dynamicPtr = dynamicStates) fixed(VkPipelineColorBlendAttachmentState * blendPtr = blendStates) fixed(VkVertexInputBindingDescription * vertexPtr = vertexBindings) fixed(VkVertexInputAttributeDescription * attributePtr = attributeBindings) fixed(VkPipelineShaderStageCreateInfo * stagePtr = stages) { if (_basePipeline != null) { _flags |= VkPipelineCreateFlag.Derivative; } else { _flags &= ~VkPipelineCreateFlag.Derivative; } var vertexInputState = new VkPipelineVertexInputStateCreateInfo() { SType = VkStructureType.PipelineVertexInputStateCreateInfo, PNext = IntPtr.Zero, Flags = 0, VertexBindingDescriptionCount = (uint)vertexBindings.Length, PVertexBindingDescriptions = vertexPtr, VertexAttributeDescriptionCount = (uint)attributeBindings.Length, PVertexAttributeDescriptions = attributePtr }; var assemblyState = _asmInfo; var tessState = _tessInfo; var viewportState = new VkPipelineViewportStateCreateInfo() { SType = VkStructureType.PipelineViewportStateCreateInfo, PNext = IntPtr.Zero, Flags = 0, ViewportCount = (uint)viewports.Length, PViewports = viewportPtr, ScissorCount = (uint)scissors.Length, PScissors = scissorPtr }; var rasterState = _rasterInfo; var multisampleState = _multisampleInfo; var depthStencilState = _depthStencilInfo; var colorBlendState = _colorBlendInfo; colorBlendState.AttachmentCount = (uint)blendStates.Length; colorBlendState.PAttachments = blendPtr; var dynamicState = new VkPipelineDynamicStateCreateInfo() { SType = VkStructureType.PipelineDynamicStateCreateInfo, PNext = IntPtr.Zero, Flags = 0, DynamicStateCount = (uint)dynamicStates.Length, PDynamicStates = dynamicPtr }; var info = new VkGraphicsPipelineCreateInfo() { SType = VkStructureType.GraphicsPipelineCreateInfo, PNext = IntPtr.Zero, Flags = _flags, StageCount = (uint)stages.Length, PStages = stagePtr, PVertexInputState = &vertexInputState, PInputAssemblyState = &assemblyState, PTessellationState = &tessState, PViewportState = &viewportState, PRasterizationState = &rasterState, PMultisampleState = &multisampleState, PDepthStencilState = &depthStencilState, PColorBlendState = &colorBlendState, PDynamicState = dynamicStates.Length > 0 ? &dynamicState : (VkPipelineDynamicStateCreateInfo *)0, Layout = _pipelineLayout.Handle, RenderPass = _pass.Handle, Subpass = _subpassId, BasePipelineHandle = _basePipeline?.Handle ?? VkPipeline.Null, BasePipelineIndex = _basePipelineIndex }; VkPipeline result = VkPipeline.Null; VkException.Check(VkDevice.vkCreateGraphicsPipelines(_pass.Device.Handle, VkPipelineCache.Null, 1, &info, _pass.Instance.AllocationCallbacks, &result)); Debug.Assert(result != VkPipeline.Null); return(new Pipeline(_pass.Device, VkPipelineBindPoint.Graphics, _pipelineLayout, result)); } } } finally { foreach (var pin in _pins) { pin.Free(); } foreach (var strPin in _strPins) { Marshal.FreeHGlobal(strPin); } } }
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(); vertexInputInfo.vertexBindingDescriptions = new List <VkVertexInputBindingDescription> { Vertex.GetBindingDescription() }; vertexInputInfo.vertexAttributeDescriptions = Vertex.GetAttributeDescriptions(); 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.CounterClockwise; 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(); pipelineLayoutInfo.setLayouts = new List <VkDescriptorSetLayout> { descriptorSetLayout }; 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(); }
public unsafe GraphicsPipeline( Device device, RenderPass renderPass, List <DescriptorLayout> layouts, List <ShaderModule> shaders, PipelineInputBuilder pipelineInputBuilder, uint subPass = 0, PipelineOptions options = null ) : base(device, renderPass, VkPipelineLayout.Null, VkPipeline.Null) { if (options == null) { options = PipelineOptions.Default; } #region Pipeline Layout var setLayout = new NativeList <VkDescriptorSetLayout>(); foreach (var layout in layouts) { setLayout.Add(layout.Handle); } var pipelineLayoutInfo = new VkPipelineLayoutCreateInfo { sType = VkStructureType.PipelineLayoutCreateInfo, setLayoutCount = setLayout.Count, pSetLayouts = (VkDescriptorSetLayout *)setLayout.Data.ToPointer() }; VkPipelineLayout pipelineLayout; if (VulkanNative.vkCreatePipelineLayout( device.Handle, &pipelineLayoutInfo, null, &pipelineLayout ) != VkResult.Success) { throw new Exception("failed to create pipeline layout"); } _layout = pipelineLayout; #endregion var bindingDescriptions = pipelineInputBuilder.BindingDescriptions; var attributeDescriptions = pipelineInputBuilder.AttributeDescriptions; var vertexInputInfo = new VkPipelineVertexInputStateCreateInfo { sType = VkStructureType.PipelineVertexInputStateCreateInfo, vertexBindingDescriptionCount = bindingDescriptions.Count, pVertexBindingDescriptions = (VkVertexInputBindingDescription *)bindingDescriptions.Data.ToPointer(), vertexAttributeDescriptionCount = attributeDescriptions.Count, pVertexAttributeDescriptions = (VkVertexInputAttributeDescription *)attributeDescriptions.Data.ToPointer() }; var inputAssemble = new VkPipelineInputAssemblyStateCreateInfo { sType = VkStructureType.PipelineInputAssemblyStateCreateInfo, topology = options.Topology, primitiveRestartEnable = VkBool32.False }; var viewport = new VkViewport(); //dynamic (ignored) var scissor = new VkRect2D(); //dynamic (ignored) var viewportState = new VkPipelineViewportStateCreateInfo { sType = VkStructureType.PipelineViewportStateCreateInfo, viewportCount = 1, pViewports = &viewport, scissorCount = 1, pScissors = &scissor }; var rasterizer = new VkPipelineRasterizationStateCreateInfo { sType = VkStructureType.PipelineRasterizationStateCreateInfo, depthClampEnable = false, rasterizerDiscardEnable = VkBool32.False, polygonMode = options.PolygonMode, lineWidth = 1.0f, cullMode = options.CullMode, frontFace = options.FrontFace, depthBiasEnable = VkBool32.False }; var multisampling = new VkPipelineMultisampleStateCreateInfo { sType = VkStructureType.PipelineMultisampleStateCreateInfo, sampleShadingEnable = VkBool32.False, rasterizationSamples = VkSampleCountFlags.Count1, minSampleShading = 1.0f, pSampleMask = null, alphaToCoverageEnable = VkBool32.False, alphaToOneEnable = VkBool32.False }; bool hasDepthAttachment = false; var colorBlendAttachments = new NativeList <VkPipelineColorBlendAttachmentState>(); foreach (var attachment in renderPass.Attachments) { if ((attachment.ImageUsageFlags & VkImageUsageFlags.DepthStencilAttachment) != 0) { hasDepthAttachment = true; continue; } colorBlendAttachments.Add(new VkPipelineColorBlendAttachmentState { colorWriteMask = ( VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A ), blendEnable = VkBool32.False, }); } var depthStencil = new VkPipelineDepthStencilStateCreateInfo { sType = VkStructureType.PipelineDepthStencilStateCreateInfo, depthTestEnable = VkBool32.True, depthWriteEnable = VkBool32.True, depthCompareOp = VkCompareOp.Less, depthBoundsTestEnable = VkBool32.False, stencilTestEnable = VkBool32.False, }; var colorBlending = new VkPipelineColorBlendStateCreateInfo { sType = VkStructureType.PipelineColorBlendStateCreateInfo, logicOpEnable = VkBool32.False, logicOp = VkLogicOp.Copy, attachmentCount = colorBlendAttachments.Count, pAttachments = (VkPipelineColorBlendAttachmentState *)colorBlendAttachments.Data.ToPointer(), blendConstants_0 = 0.0f, blendConstants_1 = 0.0f, blendConstants_2 = 0.0f, blendConstants_3 = 0.0f }; var dynamicStates = new NativeList <VkDynamicState>(); dynamicStates.Add(VkDynamicState.Viewport); dynamicStates.Add(VkDynamicState.Scissor); dynamicStates.Add(VkDynamicState.LineWidth); var dynamicStateInfo = new VkPipelineDynamicStateCreateInfo { sType = VkStructureType.PipelineDynamicStateCreateInfo, dynamicStateCount = dynamicStates.Count, pDynamicStates = (VkDynamicState *)dynamicStates.Data.ToPointer() }; var shaderInfo = new NativeList <VkPipelineShaderStageCreateInfo>(); foreach (var shader in shaders) { shaderInfo.Add(new VkPipelineShaderStageCreateInfo { sType = VkStructureType.PipelineShaderStageCreateInfo, module = shader.Handle, stage = (VkShaderStageFlags)shader.Type, pName = GraphicsApiConstants.MAIN }); } var pipelineInfo = new VkGraphicsPipelineCreateInfo { sType = VkStructureType.GraphicsPipelineCreateInfo, stageCount = shaderInfo.Count, pStages = (VkPipelineShaderStageCreateInfo *)shaderInfo.Data.ToPointer(), pVertexInputState = &vertexInputInfo, pInputAssemblyState = &inputAssemble, pViewportState = &viewportState, pRasterizationState = &rasterizer, pMultisampleState = &multisampling, pDepthStencilState = hasDepthAttachment ? &depthStencil : null, pColorBlendState = &colorBlending, pDynamicState = &dynamicStateInfo, layout = _layout, renderPass = _renderPass.Handle, subpass = subPass, basePipelineHandle = VkPipeline.Null, basePipelineIndex = -1 }; VkPipeline pipeline; if (VulkanNative.vkCreateGraphicsPipelines( _device.Handle, VkPipelineCache.Null, 1, &pipelineInfo, null, &pipeline ) != VkResult.Success) { throw new Exception("faield to create graphics pipeline"); } _handle = pipeline; }