// Helper function to create a renderpass (and fill a list) from a set of render targets // The color attachments will always come first, in the order they are specified private static Vk.RenderPass CreateRenderPass(Vk.Device device, PipelineDescription desc, List <RenderTarget> rts) { // Fill the list rts.Clear(); if (desc.HasColorTargets) { rts.AddRange(desc.ColorTargets); } if (desc.HasDepthTarget) { rts.Add(desc.DepthTarget); } // Collect the attachment descriptions and create the references Vk.AttachmentDescription[] atts = new Vk.AttachmentDescription[desc.TargetCount]; Vk.AttachmentReference[] crefs = new Vk.AttachmentReference[desc.TargetCount - (desc.HasDepthTarget ? 1 : 0)]; if (desc.HasColorTargets) { for (int i = 0; i < desc._colorAIs.Length; ++i) { atts[i] = desc._colorAIs[i]; crefs[i] = new Vk.AttachmentReference(i, desc.ColorTargets[i].DefaultImageLayout); } } if (desc.HasDepthTarget) { atts[atts.Length - 1] = desc._depthAI.Value; } // Specify the lone subpass Vk.SubpassDescription subpass = new Vk.SubpassDescription( colorAttachments: crefs, depthStencilAttachment: desc.HasDepthTarget ? new Vk.AttachmentReference(atts.Length - 1, desc.DepthTarget.DefaultImageLayout) : (Vk.AttachmentReference?)null ); // Create the renderpass var rpci = new Vk.RenderPassCreateInfo( new[] { subpass }, attachments: atts, dependencies: new[] { // Create a two dependencies so that the color and depth buffers do not overwrite each other // TODO: Validate the flags used in these new Vk.SubpassDependency(Vk.Constant.SubpassExternal, 0, Vk.PipelineStages.ColorAttachmentOutput, Vk.PipelineStages.ColorAttachmentOutput, Vk.Accesses.None, Vk.Accesses.ColorAttachmentRead, Vk.Dependencies.ByRegion), new Vk.SubpassDependency(Vk.Constant.SubpassExternal, 0, Vk.PipelineStages.LateFragmentTests, Vk.PipelineStages.EarlyFragmentTests, Vk.Accesses.None, Vk.Accesses.DepthStencilAttachmentRead, Vk.Dependencies.ByRegion) } ); return(device.CreateRenderPass(rpci)); }
internal RenderPass(Device parent, ref RenderPassCreateInfo createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; fixed(AttachmentDescription *attachmentsPtr = createInfo.Attachments) fixed(SubpassDependency * dependenciesPtr = createInfo.Dependencies) { createInfo.ToNative(out RenderPassCreateInfo.Native nativeCreateInfo, attachmentsPtr, dependenciesPtr); long handle; Result result = vkCreateRenderPass(Parent, &nativeCreateInfo, NativeAllocator, &handle); nativeCreateInfo.Free(); VulkanException.ThrowForInvalidResult(result); Handle = handle; } }
/// <summary> /// Create a new render pass object. /// </summary> /// <param name="createInfo"> /// The structure that describes the parameters of the render pass. /// </param> /// <param name="allocator">Controls host memory allocation.</param> /// <returns>The resulting render pass object.</returns> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public RenderPass CreateRenderPass(RenderPassCreateInfo createInfo, AllocationCallbacks?allocator = null) { return(new RenderPass(this, ref createInfo, ref allocator)); }