void setupDescriptorSetLayout() { var bindings = VkDescriptorSetLayoutBinding.Alloc(2); { // Binding 0 : Vertex shader uniform buffer bindings[0].binding = 0; bindings[0].descriptorType = VkDescriptorType.UniformBuffer; bindings[0].descriptorCount = 1; bindings[0].stageFlags = VkShaderStageFlagBits.Vertex; // Binding 1 : Fragment shader image sampler bindings[1].binding = 1; bindings[1].descriptorType = VkDescriptorType.CombinedImageSampler; bindings[1].descriptorCount = 1; bindings[1].stageFlags = VkShaderStageFlagBits.Fragment; } { var info = VkDescriptorSetLayoutCreateInfo.Alloc(); info[0].bindings.count = 2; info[0].bindings.pointer = bindings; VkDescriptorSetLayout layout; vkCreateDescriptorSetLayout(device, info, null, &layout); this.layout = layout; } { VkDescriptorSetLayout layout = this.layout; var info = VkPipelineLayoutCreateInfo.Alloc(); info[0].setLayouts = layout; VkPipelineLayout pipelineLayout; vkCreatePipelineLayout(device, info, null, &pipelineLayout); this.pipelineLayout = pipelineLayout; } }
void CreateLayout(PipelineLayoutCreateInfo mInfo) { VkPipelineLayoutCreateInfo info = new VkPipelineLayoutCreateInfo(); info.sType = VkStructureType.PipelineLayoutCreateInfo; NativeArray <VkDescriptorSetLayout> layoutsMarshalled = null; if (mInfo.setLayouts != null) { layoutsMarshalled = new NativeArray <VkDescriptorSetLayout>(mInfo.setLayouts.Count); for (int i = 0; i < mInfo.setLayouts.Count; i++) { layoutsMarshalled[i] = mInfo.setLayouts[i].Native; } info.setLayoutCount = (uint)layoutsMarshalled.Count; info.pSetLayouts = layoutsMarshalled.Address; } var pushConstantsMarshalled = new MarshalledArray <VkPushConstantRange>(mInfo.pushConstantRanges); info.pushConstantRangeCount = (uint)pushConstantsMarshalled.Count; info.pPushConstantRanges = pushConstantsMarshalled.Address; using (layoutsMarshalled) using (pushConstantsMarshalled) { var result = Device.Commands.createPipelineLayout(Device.Native, ref info, Device.Instance.AllocationCallbacks, out pipelineLayout); if (result != VkResult.Success) { throw new PipelineLayoutException(string.Format("Error creating pipeline layout: {0}", result)); } } }
void setupDescriptorSetLayout() { // Binding 0 : Vertex shader uniform buffer VkDescriptorSetLayoutBinding setLayoutBinding = new VkDescriptorSetLayoutBinding() { descriptorType = VkDescriptorType.UniformBuffer, stageFlags = VkShaderStageFlags.Vertex, binding = 0, descriptorCount = 1 }; VkDescriptorSetLayoutCreateInfo descriptorLayout = VkDescriptorSetLayoutCreateInfo.New(); descriptorLayout.pBindings = &setLayoutBinding; descriptorLayout.bindingCount = 1; descriptorSetLayout.Count = 1; Util.CheckResult(vkCreateDescriptorSetLayout(Device, &descriptorLayout, null, (VkDescriptorSetLayout *)descriptorSetLayout.GetAddress(0))); VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = VkPipelineLayoutCreateInfo.New(); pPipelineLayoutCreateInfo.setLayoutCount = 1; pPipelineLayoutCreateInfo.pSetLayouts = (VkDescriptorSetLayout *)descriptorSetLayout.Data.ToPointer(); Util.CheckResult(vkCreatePipelineLayout(Device, &pPipelineLayoutCreateInfo, null, out pipelineLayout)); }
void setupDescriptorSetLayout() { var bindings = new VkDescriptorSetLayoutBinding[] { // layout (binding = 0) uniform UboView new VkDescriptorSetLayoutBinding(0, VkDescriptorType.UniformBuffer, 1, VkShaderStageFlagBits.Vertex), // layout (binding = 1) uniform UboInstance new VkDescriptorSetLayoutBinding(1, VkDescriptorType.UniformBufferDynamic, 1, VkShaderStageFlagBits.Vertex), // no matching uniform sampler2D in shader. new VkDescriptorSetLayoutBinding(2, VkDescriptorType.CombinedImageSampler, 1, VkShaderStageFlagBits.Fragment), }; var descriptorLayoutInfo = new VkDescriptorSetLayoutCreateInfo(); descriptorLayoutInfo.sType = DescriptorSetLayoutCreateInfo; descriptorLayoutInfo.bindings = bindings; VkDescriptorSetLayout layout; vkCreateDescriptorSetLayout(device, &descriptorLayoutInfo, null, &layout); this.descriptorSetLayout = layout; VkPipelineLayoutCreateInfo info = new VkPipelineLayoutCreateInfo(); info.sType = PipelineLayoutCreateInfo; info.setLayouts = layout; VkPipelineLayout pipelineLayout; vkCreatePipelineLayout(device, &info, null, &pipelineLayout); this.pipelineLayout = pipelineLayout; }
public override void Activate() { if (state != ActivableState.Activated) { foreach (DescriptorSetLayout dsl in DescriptorSetLayouts) { dsl.Activate(); } VkPipelineLayoutCreateInfo info = VkPipelineLayoutCreateInfo.New(); VkDescriptorSetLayout[] dsls = DescriptorSetLayouts.Select(dsl => dsl.handle).ToArray(); if (dsls.Length > 0) { info.setLayoutCount = (uint)dsls.Length; info.pSetLayouts = dsls.Pin(); } if (PushConstantRanges.Count > 0) { info.pushConstantRangeCount = (uint)PushConstantRanges.Count; info.pPushConstantRanges = PushConstantRanges.Pin(); } Utils.CheckResult(vkCreatePipelineLayout(Dev.VkDev, ref info, IntPtr.Zero, out handle)); if (dsls.Length > 0) { dsls.Unpin(); } if (PushConstantRanges.Count > 0) { PushConstantRanges.Unpin(); } } base.Activate(); }
public VkShaderResourceBindingSlots(VkDevice device, ShaderResourceDescription[] resources) { Resources = resources; VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCI = VkDescriptorSetLayoutCreateInfo.New(); descriptorSetLayoutCI.bindingCount = (uint)resources.Length; VkDescriptorSetLayoutBinding *bindings = stackalloc VkDescriptorSetLayoutBinding[resources.Length]; for (int i = 0; i < resources.Length; i++) { ShaderResourceDescription desc = resources[i]; bindings[i].binding = (uint)i; bindings[i].descriptorType = MapDescriptorType(desc.Type); bindings[i].descriptorCount = 1; bindings[i].stageFlags = MapStageFlags(desc.Stages); } descriptorSetLayoutCI.pBindings = bindings; vkCreateDescriptorSetLayout(device, ref descriptorSetLayoutCI, null, out VkDescriptorSetLayout descriptorSetLayout); DescriptorSetLayout = descriptorSetLayout; VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New(); pipelineLayoutCI.setLayoutCount = 1; pipelineLayoutCI.pSetLayouts = &descriptorSetLayout; VkResult result = vkCreatePipelineLayout(device, ref pipelineLayoutCI, null, out VkPipelineLayout layout); CheckResult(result); PipelineLayout = layout; }
void setupDescriptorSetLayout() { FixedArray2<VkDescriptorSetLayoutBinding> setLayoutBindings = new FixedArray2<VkDescriptorSetLayoutBinding>( // Binding 0 : Vertex shader uniform buffer Initializers.descriptorSetLayoutBinding( VkDescriptorType.UniformBuffer, VkShaderStageFlags.Vertex, 0), // Binding 1 : Fragment shader image sampler Initializers.descriptorSetLayoutBinding( VkDescriptorType.CombinedImageSampler, VkShaderStageFlags.Fragment, 1)); VkDescriptorSetLayoutCreateInfo descriptorLayout = Initializers.descriptorSetLayoutCreateInfo( &setLayoutBindings.First, setLayoutBindings.Count); Util.CheckResult(vkCreateDescriptorSetLayout(device, &descriptorLayout, null, out descriptorSetLayout)); var dsl = descriptorSetLayout; VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = Initializers.pipelineLayoutCreateInfo( &dsl, 1); Util.CheckResult(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, null, out pipelineLayout)); }
/// <summary> /// パイプラインレイアウトを構築します。 /// </summary> /// <returns></returns> private VkPipelineLayout CreatePipelineLayout(VkDevice device) { var createInfo = new VkPipelineLayoutCreateInfo(); VkPipelineLayout layout = null; VulkanAPI.vkCreatePipelineLayout(device, ref createInfo, out layout); return(layout); }
public PipelineLayout(Device dev, VkPipelineLayoutCreateInfo info) { Device = dev; unsafe { Handle = dev.Handle.CreatePipelineLayout(&info, Instance.AllocationCallbacks); } }
public static VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo( VkDescriptorSetLayout *pSetLayouts, uint setLayoutCount = 1) { VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = VkPipelineLayoutCreateInfo.New(); pipelineLayoutCreateInfo.setLayoutCount = setLayoutCount; pipelineLayoutCreateInfo.pSetLayouts = pSetLayouts; return(pipelineLayoutCreateInfo); }
/// <summary> /// パイプラインレイアウトを構築します。 /// </summary> /// <returns></returns> private VkPipelineLayout CreatePipelineLayout(VkDevice device) { var createInfo = new VkPipelineLayoutCreateInfo(); createInfo.setLayouts = new[] { m_descriptorSetLayout }; VkPipelineLayout layout = null; VulkanAPI.vkCreatePipelineLayout(device, ref createInfo, out layout); return(layout); }
public VkPipelineLayout CreatePipelineLayout(VkDevice device, VkDescriptorSetLayout descSetLayout) { var createInfo = new VkPipelineLayoutCreateInfo(); createInfo.setLayouts = new[] { descSetLayout }; VkPipelineLayout layout = null; VulkanAPI.vkCreatePipelineLayout(device, ref createInfo, out layout); m_pipelineLayouts.Add(layout); return(layout); }
static VkPipelineLayout CreatePipelineLayout(VkDevice device, VkDescriptorSetLayout setLayout) { VkPipelineLayoutCreateInfo pCreateInfo = VkPipelineLayoutCreateInfo.New(); pCreateInfo.pushConstantRangeCount = 0; pCreateInfo.setLayoutCount = 1; pCreateInfo.pSetLayouts = &setLayout; VkPipelineLayout layout = VkPipelineLayout.Null; Assert(vkCreatePipelineLayout(device, &pCreateInfo, null, &layout)); return(layout); }
VkPipelineLayout CreatePipelineLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout) { var info = new VkPipelineLayoutCreateInfo { sType = VkStructureType.PipelineLayoutCreateInfo }; info.setLayouts = descriptorSetLayout; //return device.CreatePipelineLayout(ref info); VkPipelineLayout layout; vkAPI.vkCreatePipelineLayout(device, &info, null, &layout).Check(); info.Free(); return(layout); }
private VkPipelineLayout CreatePipelineLayout() { VkDescriptorSetLayout layout = _descriptorSetLayout; var createInfo = new VkPipelineLayoutCreateInfo { sType = VkStructureType.PipelineLayoutCreateInfo, pNext = null, setLayoutCount = 1, pSetLayouts = &layout }; VkPipelineLayout pipelineLayout; vkCreatePipelineLayout(Context.Device, &createInfo, null, out pipelineLayout).CheckResult(); return(pipelineLayout); }
public VkPipeline(VkGraphicsDevice gd, ref ComputePipelineDescription description) : base(ref description) { _gd = gd; IsComputePipeline = true; VkComputePipelineCreateInfo pipelineCI = VkComputePipelineCreateInfo.New(); // Pipeline Layout ResourceLayout[] resourceLayouts = description.ResourceLayouts; VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New(); pipelineLayoutCI.setLayoutCount = (uint)resourceLayouts.Length; VkDescriptorSetLayout *dsls = stackalloc VkDescriptorSetLayout[resourceLayouts.Length]; for (int i = 0; i < resourceLayouts.Length; i++) { dsls[i] = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(resourceLayouts[i]).DescriptorSetLayout; } pipelineLayoutCI.pSetLayouts = dsls; vkCreatePipelineLayout(_gd.Device, ref pipelineLayoutCI, null, out _pipelineLayout); pipelineCI.layout = _pipelineLayout; // Shader Stage Shader shader = description.ComputeShader; VkShader vkShader = Util.AssertSubtype <Shader, VkShader>(shader); VkPipelineShaderStageCreateInfo stageCI = VkPipelineShaderStageCreateInfo.New(); stageCI.module = vkShader.ShaderModule; stageCI.stage = VkFormats.VdToVkShaderStages(shader.Stage); stageCI.pName = CommonStrings.main; // Meh pipelineCI.stage = stageCI; VkResult result = vkCreateComputePipelines( _gd.Device, VkPipelineCache.Null, 1, ref pipelineCI, null, out _devicePipeline); CheckResult(result); ResourceSetCount = (uint)description.ResourceLayouts.Length; }
void setupDescriptorSetLayout() { VkDescriptorSetLayoutBinding setLayoutBindings = // Binding 0 : Vertex shader uniform buffer Initializers.descriptorSetLayoutBinding( VkDescriptorType.UniformBuffer, VkShaderStageFlags.Vertex, 0); VkDescriptorSetLayoutCreateInfo descriptorLayout = Initializers.descriptorSetLayoutCreateInfo( &setLayoutBindings, 1); Util.CheckResult(vkCreateDescriptorSetLayout(device, &descriptorLayout, null, out descriptorSetLayout)); var dsl = descriptorSetLayout; VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = Initializers.pipelineLayoutCreateInfo( &dsl, 1); // Define push constant // Example uses six light positions as push constants // 6 * 4 * 4 = 96 bytes // Spec requires a minimum of 128 bytes, bigger values // need to be checked against maxPushConstantsSize // But even at only 128 bytes, lots of stuff can fit // inside push constants VkPushConstantRange pushConstantRange = Initializers.pushConstantRange( VkShaderStageFlags.Vertex, pushConstants.Count * (uint)sizeof(Vector4), 0); // Push constant ranges are part of the pipeline layout pipelineLayoutCreateInfo.pushConstantRangeCount = 1; pipelineLayoutCreateInfo.pPushConstantRanges = &pushConstantRange; Util.CheckResult(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out pipelineLayout)); }
void setupDescriptorSetLayout() { FixedArray2 <VkDescriptorSetLayoutBinding> setLayoutBindings = new FixedArray2 <VkDescriptorSetLayoutBinding>( Initializers.descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0), Initializers.descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 1)); VkDescriptorSetLayoutCreateInfo descriptorLayout = Initializers.descriptorSetLayoutCreateInfo( &setLayoutBindings.First, setLayoutBindings.Count); Util.CheckResult(vkCreateDescriptorSetLayout(device, &descriptorLayout, null, out descriptorSetLayout)); var dsl = descriptorSetLayout; VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = Initializers.pipelineLayoutCreateInfo( &dsl, 1); Util.CheckResult(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, null, out pipelineLayout)); }
void setupDescriptorSetLayout() { var bindings = new VkDescriptorSetLayoutBinding[2]; // Binding 0 : Vertex shader uniform buffer bindings[0] = new VkDescriptorSetLayoutBinding(); bindings[0].descriptorType = VkDescriptorType.UniformBuffer; bindings[0].stageFlags = VkShaderStageFlagBits.Vertex; bindings[0].binding = 0; bindings[0].descriptorCount = 1; // Binding 1 : Fragment shader combined sampler bindings[1] = new VkDescriptorSetLayoutBinding(); bindings[1].descriptorType = VkDescriptorType.CombinedImageSampler; bindings[1].stageFlags = VkShaderStageFlagBits.Fragment; bindings[1].binding = 1; bindings[1].descriptorCount = 1; var descriptorLayout = VkDescriptorSetLayoutCreateInfo.Alloc(); descriptorLayout->bindings = bindings; VkDescriptorSetLayout dsl; vkCreateDescriptorSetLayout(device, descriptorLayout, null, &dsl); this.descriptorSetLayout = dsl; var info = new VkPipelineLayoutCreateInfo(); info.sType = PipelineLayoutCreateInfo; info.setLayouts = dsl; { VkPipelineLayout layout; vkCreatePipelineLayout(device, &info, null, &layout); this.pipelineLayout = layout; } }
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); }
public void Build(int deviceIndex) { if (!locked) { unsafe { devID = deviceIndex; var descLayouts = stackalloc IntPtr[Descriptors == null ? 0 : Descriptors.Length]; if (Descriptors != null) { for (int i = 0; i < Descriptors.Length; i++) { descLayouts[i] = Descriptors[i].Layout.hndl; } } var pushConstants = new VkPushConstantRange[PushConstants == null ? 0 : PushConstants.Length]; if (PushConstants != null) { for (int i = 0; i < PushConstants.Length; i++) { pushConstants[i] = new VkPushConstantRange() { offset = PushConstants[i].Offset, size = PushConstants[i].Size, stageFlags = (VkShaderStageFlags)PushConstants[i].Stages } } } ; var pushConstants_arr = pushConstants.Pointer(); var pipelineLayoutInfo = new VkPipelineLayoutCreateInfo() { sType = VkStructureType.StructureTypePipelineLayoutCreateInfo, setLayoutCount = Descriptors == null ? 0 : (uint)Descriptors.Length, //TODO: add descriptor support pSetLayouts = descLayouts, pushConstantRangeCount = PushConstants == null ? 0 : (uint)PushConstants.Length, //TODO: setup push constants pPushConstantRanges = PushConstants == null ? IntPtr.Zero : pushConstants_arr, }; IntPtr pipelineLayout_l = IntPtr.Zero; if (vkCreatePipelineLayout(GraphicsDevice.GetDeviceInfo(deviceIndex).Device, pipelineLayoutInfo.Pointer(), null, &pipelineLayout_l) != VkResult.Success) { throw new Exception("Failed to create pipeline layout."); } hndl = pipelineLayout_l; if (GraphicsDevice.EnableValidation) { var objName = new VkDebugUtilsObjectNameInfoEXT() { sType = VkStructureType.StructureTypeDebugUtilsObjectNameInfoExt, pObjectName = Name, objectType = VkObjectType.ObjectTypePipelineLayout, objectHandle = (ulong)hndl }; GraphicsDevice.SetDebugUtilsObjectNameEXT(GraphicsDevice.GetDeviceInfo(deviceIndex).Device, objName.Pointer()); } } locked = true; } else { throw new Exception("PipelineLayout is locked."); } }
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); }
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 VkPipeline(VkGraphicsDevice gd, ref ComputePipelineDescription description) : base(ref description) { _gd = gd; IsComputePipeline = true; RefCount = new ResourceRefCount(DisposeCore); VkComputePipelineCreateInfo pipelineCI = VkComputePipelineCreateInfo.New(); // Pipeline Layout ResourceLayout[] resourceLayouts = description.ResourceLayouts; VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New(); pipelineLayoutCI.setLayoutCount = (uint)resourceLayouts.Length; VkDescriptorSetLayout *dsls = stackalloc VkDescriptorSetLayout[resourceLayouts.Length]; for (int i = 0; i < resourceLayouts.Length; i++) { dsls[i] = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(resourceLayouts[i]).DescriptorSetLayout; } pipelineLayoutCI.pSetLayouts = dsls; vkCreatePipelineLayout(_gd.Device, ref pipelineLayoutCI, null, out _pipelineLayout); pipelineCI.layout = _pipelineLayout; // Shader Stage VkSpecializationInfo specializationInfo; SpecializationConstant[] specDescs = description.Specializations; if (specDescs != null) { uint specDataSize = 0; foreach (SpecializationConstant spec in specDescs) { specDataSize += VkFormats.GetSpecializationConstantSize(spec.Type); } byte *fullSpecData = stackalloc byte[(int)specDataSize]; int specializationCount = specDescs.Length; VkSpecializationMapEntry *mapEntries = stackalloc VkSpecializationMapEntry[specializationCount]; uint specOffset = 0; for (int i = 0; i < specializationCount; i++) { ulong data = specDescs[i].Data; byte *srcData = (byte *)&data; uint dataSize = VkFormats.GetSpecializationConstantSize(specDescs[i].Type); Unsafe.CopyBlock(fullSpecData + specOffset, srcData, dataSize); mapEntries[i].constantID = specDescs[i].ID; mapEntries[i].offset = specOffset; mapEntries[i].size = (UIntPtr)dataSize; specOffset += dataSize; } specializationInfo.dataSize = (UIntPtr)specDataSize; specializationInfo.pData = fullSpecData; specializationInfo.mapEntryCount = (uint)specializationCount; specializationInfo.pMapEntries = mapEntries; } Shader shader = description.ComputeShader; VkShader vkShader = Util.AssertSubtype <Shader, VkShader>(shader); VkPipelineShaderStageCreateInfo stageCI = VkPipelineShaderStageCreateInfo.New(); stageCI.module = vkShader.ShaderModule; stageCI.stage = VkFormats.VdToVkShaderStages(shader.Stage); stageCI.pName = CommonStrings.main; // Meh stageCI.pSpecializationInfo = &specializationInfo; pipelineCI.stage = stageCI; VkResult result = vkCreateComputePipelines( _gd.Device, VkPipelineCache.Null, 1, ref pipelineCI, null, out _devicePipeline); CheckResult(result); ResourceSetCount = (uint)description.ResourceLayouts.Length; DynamicOffsetsCount = 0; foreach (VkResourceLayout layout in description.ResourceLayouts) { DynamicOffsetsCount += layout.DynamicBufferCount; } }
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(); }
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); }
public static VkResult vkCreatePipelineLayout(VkDevice device, VkPipelineLayoutCreateInfo pipelineLayoutInfo, VkAllocationCallbacks pAllocator, out VkPipelineLayout pipelineLayout) { VkPreconditions.CheckNull(device, nameof(device)); return(GetDevice(device).CreatePipelineLayout(pipelineLayoutInfo, out pipelineLayout)); }
private unsafe void CreatePipelineLayout(PipelineStateDescription pipelineStateDescription) { // Remap descriptor set indices to those in the shader. This ordering generated by the ShaderCompiler var resourceGroups = pipelineStateDescription.EffectBytecode.Reflection.ResourceBindings.Select(x => x.ResourceGroup ?? "Globals").Distinct().ToList(); ResourceGroupCount = resourceGroups.Count; var layouts = pipelineStateDescription.RootSignature.EffectDescriptorSetReflection.Layouts; // Get binding indices used by the shader var destinationBindings = pipelineStateDescription.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" ? pipelineStateDescription.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), ResourceElementIsInteger = sourceEntry.ElementType != EffectParameterType.Float && sourceEntry.ElementType != EffectParameterType.Double, }); } } } // 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, }; vkCreatePipelineLayout(GraphicsDevice.NativeDevice, &pipelineLayoutCreateInfo, null, out NativeLayout); }
public static extern VkResult CreatePipelineLayout( VkDevice device, ref VkPipelineLayoutCreateInfo pCreateInfo, IntPtr pAllocator, out VkPipelineLayout pPipelineLayout );
public override VkResult CreatePipelineLayout(VkPipelineLayoutCreateInfo pipelineLayoutInfo, out VkPipelineLayout pipelineLayout) { throw new NotImplementedException(); }