private void CreateRenderPass(VkFormat colorFormat) { VkAttachmentDescription attachment = new VkAttachmentDescription( colorFormat, VkSampleCountFlags.Count1, VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.Store, VkAttachmentLoadOp.DontCare, VkAttachmentStoreOp.DontCare, VkImageLayout.Undefined, VkImageLayout.PresentSrcKHR ); VkAttachmentReference colorAttachmentRef = new VkAttachmentReference(0, VkImageLayout.ColorAttachmentOptimal); VkSubpassDescription subpass = new VkSubpassDescription { pipelineBindPoint = VkPipelineBindPoint.Graphics, colorAttachmentCount = 1, pColorAttachments = &colorAttachmentRef }; VkSubpassDependency[] dependencies = new VkSubpassDependency[2]; dependencies[0] = new VkSubpassDependency { srcSubpass = SubpassExternal, dstSubpass = 0, srcStageMask = VkPipelineStageFlags.BottomOfPipe, dstStageMask = VkPipelineStageFlags.ColorAttachmentOutput, srcAccessMask = VkAccessFlags.MemoryRead, dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite, dependencyFlags = VkDependencyFlags.ByRegion }; dependencies[1] = new VkSubpassDependency { srcSubpass = 0, dstSubpass = SubpassExternal, srcStageMask = VkPipelineStageFlags.ColorAttachmentOutput, dstStageMask = VkPipelineStageFlags.BottomOfPipe, srcAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite, dstAccessMask = VkAccessFlags.MemoryRead, dependencyFlags = VkDependencyFlags.ByRegion }; fixed(VkSubpassDependency *dependenciesPtr = &dependencies[0]) { VkRenderPassCreateInfo createInfo = new VkRenderPassCreateInfo { sType = VkStructureType.RenderPassCreateInfo, attachmentCount = 1, pAttachments = &attachment, subpassCount = 1, pSubpasses = &subpass, dependencyCount = 2, pDependencies = dependenciesPtr }; vkCreateRenderPass(Device, &createInfo, null, out RenderPass).CheckResult(); } }
public void SetDepthReference(uint attachment, VkImageLayout layout = VkImageLayout.DepthStencilAttachmentOptimal) { DepthReference = new VkAttachmentReference { attachment = attachment, layout = layout }; }
private VkRenderPass CreateRenderPass() { VkAttachmentDescription *attachments = stackalloc VkAttachmentDescription[2] { // Color attachment. new VkAttachmentDescription { format = SwapchainFormat, samples = VkSampleCountFlags.Count1, loadOp = VkAttachmentLoadOp.Clear, storeOp = VkAttachmentStoreOp.Store, stencilLoadOp = VkAttachmentLoadOp.DontCare, stencilStoreOp = VkAttachmentStoreOp.DontCare, initialLayout = VkImageLayout.Undefined, finalLayout = VkImageLayout.PresentSrcKHR }, // Depth attachment. new VkAttachmentDescription { format = _depthStencilBuffer.Format, samples = VkSampleCountFlags.Count1, loadOp = VkAttachmentLoadOp.Clear, storeOp = VkAttachmentStoreOp.DontCare, stencilLoadOp = VkAttachmentLoadOp.DontCare, stencilStoreOp = VkAttachmentStoreOp.DontCare, initialLayout = VkImageLayout.Undefined, finalLayout = VkImageLayout.DepthStencilAttachmentOptimal } }; VkAttachmentReference colorAttachment = new VkAttachmentReference { attachment = 0, layout = VkImageLayout.ColorAttachmentOptimal }; VkAttachmentReference depthStencilAttachment = new VkAttachmentReference { attachment = 1, layout = VkImageLayout.DepthStencilAttachmentOptimal }; var subpass = new VkSubpassDescription { colorAttachmentCount = 1, pColorAttachments = &colorAttachment, pDepthStencilAttachment = &depthStencilAttachment }; VkSubpassDependency *dependencies = stackalloc VkSubpassDependency[2] { new VkSubpassDependency { srcSubpass = uint.MaxValue, // SubpassExternal ? dstSubpass = 0, srcStageMask = VkPipelineStageFlags.BottomOfPipe, dstStageMask = VkPipelineStageFlags.ColorAttachmentOutput, srcAccessMask = VkAccessFlags.MemoryRead, dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite, dependencyFlags = VkDependencyFlags.ByRegion }, new VkSubpassDependency { srcSubpass = 0, dstSubpass = uint.MaxValue, // SubpassExternal ? srcStageMask = VkPipelineStageFlags.ColorAttachmentOutput, dstStageMask = VkPipelineStageFlags.BottomOfPipe, srcAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite, dstAccessMask = VkAccessFlags.MemoryRead, dependencyFlags = VkDependencyFlags.ByRegion } }; var createInfo = new VkRenderPassCreateInfo { sType = VkStructureType.RenderPassCreateInfo, pNext = null, subpassCount = 1, pSubpasses = &subpass, attachmentCount = 2, pAttachments = attachments, dependencyCount = 2, pDependencies = dependencies }; VkRenderPass renderPass; vkCreateRenderPass(Context.Device, &createInfo, null, out renderPass).CheckResult(); return(renderPass); }
public VkFramebuffer(VkGraphicsDevice gd, ref FramebufferDescription description) : base(description.DepthTarget, description.ColorTargets) { _gd = gd; VkRenderPassCreateInfo renderPassCI = VkRenderPassCreateInfo.New(); StackList <VkAttachmentDescription> attachments = new StackList <VkAttachmentDescription>(); uint colorAttachmentCount = (uint)ColorTextures.Count; StackList <VkAttachmentDescription> colorAttachmentDescriptions = new StackList <VkAttachmentDescription>(); StackList <VkAttachmentReference> colorAttachmentRefs = new StackList <VkAttachmentReference>(); for (int i = 0; i < colorAttachmentCount; i++) { VkTexture vkColorTex = Util.AssertSubtype <Texture, VkTexture>(ColorTextures[i]); VkAttachmentDescription colorAttachmentDesc = new VkAttachmentDescription(); colorAttachmentDesc.format = vkColorTex.VkFormat; colorAttachmentDesc.samples = VkSampleCountFlags.Count1; colorAttachmentDesc.loadOp = VkAttachmentLoadOp.DontCare; colorAttachmentDesc.storeOp = VkAttachmentStoreOp.Store; colorAttachmentDesc.stencilLoadOp = VkAttachmentLoadOp.DontCare; colorAttachmentDesc.stencilStoreOp = VkAttachmentStoreOp.DontCare; colorAttachmentDesc.initialLayout = VkImageLayout.Undefined; colorAttachmentDesc.finalLayout = VkImageLayout.PresentSrcKHR; colorAttachmentDescriptions.Add(colorAttachmentDesc); attachments.Add(colorAttachmentDesc); VkAttachmentReference colorAttachmentRef = new VkAttachmentReference(); colorAttachmentRef.attachment = (uint)i; colorAttachmentRef.layout = VkImageLayout.ColorAttachmentOptimal; colorAttachmentRefs.Add(colorAttachmentRef); } VkTexture vkDepthTex = Util.AssertSubtype <Texture, VkTexture>(DepthTexture); VkAttachmentDescription depthAttachmentDesc = new VkAttachmentDescription(); VkAttachmentReference depthAttachmentRef = new VkAttachmentReference(); if (vkDepthTex != null) { depthAttachmentDesc.format = vkDepthTex.VkFormat; depthAttachmentDesc.samples = VkSampleCountFlags.Count1; depthAttachmentDesc.loadOp = VkAttachmentLoadOp.DontCare; depthAttachmentDesc.storeOp = VkAttachmentStoreOp.Store; depthAttachmentDesc.stencilLoadOp = VkAttachmentLoadOp.DontCare; depthAttachmentDesc.stencilStoreOp = VkAttachmentStoreOp.DontCare; depthAttachmentDesc.initialLayout = VkImageLayout.Undefined; depthAttachmentDesc.finalLayout = VkImageLayout.ShaderReadOnlyOptimal; depthAttachmentRef.attachment = (uint)description.ColorTargets.Length; depthAttachmentRef.layout = VkImageLayout.DepthStencilAttachmentOptimal; } VkSubpassDescription subpass = new VkSubpassDescription(); subpass.pipelineBindPoint = VkPipelineBindPoint.Graphics; if (ColorTextures.Count > 0) { subpass.colorAttachmentCount = colorAttachmentCount; subpass.pColorAttachments = (VkAttachmentReference *)colorAttachmentRefs.Data; } if (DepthTexture != 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 (DepthTexture != 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); VkFramebufferCreateInfo fbCI = VkFramebufferCreateInfo.New(); uint fbAttachmentsCount = (uint)description.ColorTargets.Length; if (description.DepthTarget != null) { fbAttachmentsCount += 1; } VkImageView *fbAttachments = stackalloc VkImageView[(int)fbAttachmentsCount]; for (int i = 0; i < fbAttachmentsCount - 1; i++) { Texture colorTarget = description.ColorTargets[i]; VkTexture vkColorTarget = Util.AssertSubtype <Texture, VkTexture>(colorTarget); VkImageViewCreateInfo imageViewCI = VkImageViewCreateInfo.New(); imageViewCI.image = vkColorTarget.DeviceImage; imageViewCI.format = vkColorTarget.VkFormat; imageViewCI.viewType = VkImageViewType.Image2D; imageViewCI.subresourceRange = new VkImageSubresourceRange(VkImageAspectFlags.Color, 0, 1, 0, 1); VkImageView *dest = (fbAttachments + i); VkResult result = vkCreateImageView(_gd.Device, ref imageViewCI, null, dest); CheckResult(result); _attachmentViews.Add(*dest); } // Depth if (description.DepthTarget != null) { VkTexture vkDepthTarget = Util.AssertSubtype <Texture, VkTexture>(description.DepthTarget); VkImageViewCreateInfo depthViewCI = VkImageViewCreateInfo.New(); depthViewCI.image = vkDepthTarget.DeviceImage; depthViewCI.format = vkDepthTarget.VkFormat; depthViewCI.viewType = VkImageViewType.Image2D; depthViewCI.subresourceRange = new VkImageSubresourceRange(VkImageAspectFlags.Depth, 0, 1, 0, 1); VkImageView *dest = (fbAttachments + (fbAttachmentsCount - 1)); VkResult result = vkCreateImageView(_gd.Device, ref depthViewCI, null, dest); CheckResult(result); _attachmentViews.Add(*dest); } if (ColorTextures.Count > 0) { fbCI.width = ColorTextures[0].Width; fbCI.height = ColorTextures[0].Height; } else if (vkDepthTex != null) { fbCI.width = vkDepthTex.Width; fbCI.height = vkDepthTex.Height; } fbCI.attachmentCount = fbAttachmentsCount; fbCI.pAttachments = fbAttachments; fbCI.layers = 1; fbCI.renderPass = _renderPass; creationResult = vkCreateFramebuffer(_gd.Device, ref fbCI, null, out _deviceFramebuffer); CheckResult(creationResult); }
public void Build(int device_index) { if (!locked) { unsafe { uint colorAttachmentCnt = (uint)(ColorAttachments == null ? 0 : ColorAttachments.Length); uint depthAttachmentCnt = DepthAttachment != null ? 1u : 0u; var colorAttachments = new VkAttachmentReference[colorAttachmentCnt]; for (int i = 0; i < colorAttachmentCnt; i++) { colorAttachments[i].attachment = (uint)i; colorAttachments[i].layout = (VkImageLayout)ColorAttachments[i].StartLayout; } var depthAttachment = new VkAttachmentReference() { attachment = colorAttachmentCnt, layout = DepthAttachment == null ? VkImageLayout.ImageLayoutUndefined : (VkImageLayout)DepthAttachment.StartLayout }; var colorAttachments_ptr = colorAttachments.Pointer(); var depthAttachments_ptr = depthAttachment.Pointer(); var preserveAttachments = stackalloc uint[] { colorAttachmentCnt }; var subpassDesc = new VkSubpassDescription() { pipelineBindPoint = VkPipelineBindPoint.PipelineBindPointGraphics, colorAttachmentCount = colorAttachmentCnt, pColorAttachments = colorAttachments_ptr, pDepthStencilAttachment = depthAttachmentCnt > 0 ? depthAttachments_ptr : IntPtr.Zero, preserveAttachmentCount = 0u, pPreserveAttachments = preserveAttachments, }; var subpassDesc_ptr = subpassDesc.Pointer(); var colorAttachmentDesc = new VkAttachmentDescription[colorAttachmentCnt + depthAttachmentCnt]; for (int i = 0; i < colorAttachmentCnt; i++) { colorAttachmentDesc[i].format = (VkFormat)ColorAttachments[i].Format; colorAttachmentDesc[i].samples = VkSampleCountFlags.SampleCount1Bit; colorAttachmentDesc[i].loadOp = (VkAttachmentLoadOp)ColorAttachments[i].LoadOp; colorAttachmentDesc[i].storeOp = (VkAttachmentStoreOp)ColorAttachments[i].StoreOp; colorAttachmentDesc[i].stencilLoadOp = VkAttachmentLoadOp.AttachmentLoadOpDontCare; colorAttachmentDesc[i].stencilStoreOp = VkAttachmentStoreOp.AttachmentStoreOpDontCare; colorAttachmentDesc[i].initialLayout = (VkImageLayout)ColorAttachments[i].InitialLayout; colorAttachmentDesc[i].finalLayout = (VkImageLayout)ColorAttachments[i].FinalLayout; } if (depthAttachmentCnt > 0) { colorAttachmentDesc[colorAttachmentCnt].format = (VkFormat)DepthAttachment.Format; colorAttachmentDesc[colorAttachmentCnt].samples = VkSampleCountFlags.SampleCount1Bit; colorAttachmentDesc[colorAttachmentCnt].loadOp = (VkAttachmentLoadOp)DepthAttachment.LoadOp; colorAttachmentDesc[colorAttachmentCnt].storeOp = (VkAttachmentStoreOp)DepthAttachment.StoreOp; colorAttachmentDesc[colorAttachmentCnt].stencilLoadOp = VkAttachmentLoadOp.AttachmentLoadOpDontCare; colorAttachmentDesc[colorAttachmentCnt].stencilStoreOp = VkAttachmentStoreOp.AttachmentStoreOpDontCare; colorAttachmentDesc[colorAttachmentCnt].initialLayout = (VkImageLayout)DepthAttachment.InitialLayout; colorAttachmentDesc[colorAttachmentCnt].finalLayout = (VkImageLayout)DepthAttachment.FinalLayout; } var colorAttachmentDesc_ptr = colorAttachmentDesc.Pointer(); var subpassDependency = new VkSubpassDependency() { srcSubpass = VkSubpassExternal, dstSubpass = 0, srcStageMask = VkPipelineStageFlags.PipelineStageAllCommandsBit, srcAccessMask = 0, dstStageMask = VkPipelineStageFlags.PipelineStageVertexShaderBit, dstAccessMask = VkAccessFlags.AccessMemoryReadBit, }; var subpassDependency_ptr = subpassDependency.Pointer(); var renderPassInfo = new VkRenderPassCreateInfo() { sType = VkStructureType.StructureTypeRenderPassCreateInfo, attachmentCount = colorAttachmentCnt + depthAttachmentCnt, pAttachments = colorAttachmentDesc_ptr, subpassCount = 1, pSubpasses = subpassDesc_ptr, dependencyCount = 1, pDependencies = subpassDependency_ptr }; IntPtr renderPass_l = IntPtr.Zero; if (vkCreateRenderPass(GraphicsDevice.GetDeviceInfo(device_index).Device, renderPassInfo.Pointer(), null, &renderPass_l) != VkResult.Success) { throw new Exception("Failed to create RenderPass."); } hndl = renderPass_l; devID = device_index; if (GraphicsDevice.EnableValidation) { var objName = new VkDebugUtilsObjectNameInfoEXT() { sType = VkStructureType.StructureTypeDebugUtilsObjectNameInfoExt, pObjectName = Name, objectType = VkObjectType.ObjectTypeRenderPass, objectHandle = (ulong)hndl }; GraphicsDevice.SetDebugUtilsObjectNameEXT(GraphicsDevice.GetDeviceInfo(devID).Device, objName.Pointer()); } } locked = true; } else { throw new Exception("RenderPass is locked."); } }