2
0

BsVulkanFramebuffer.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsVulkanFramebuffer.h"
  4. #include "BsVulkanUtility.h"
  5. #include "BsVulkanDevice.h"
  6. namespace BansheeEngine
  7. {
  8. VulkanFramebuffer::VulkanFramebuffer(const SPtr<VulkanDevice>& device, const VULKAN_FRAMEBUFFER_DESC& desc)
  9. :mDevice(device)
  10. {
  11. // Create render state
  12. VkAttachmentDescription attachments[BS_MAX_MULTIPLE_RENDER_TARGETS + 1];
  13. VkImageView attachmentViews[BS_MAX_MULTIPLE_RENDER_TARGETS + 1];
  14. VkAttachmentReference colorReferences[BS_MAX_MULTIPLE_RENDER_TARGETS];
  15. VkAttachmentReference depthReference;
  16. VkSampleCountFlagBits sampleFlags = VulkanUtility::getSampleFlags(desc.numSamples);
  17. UINT32 attachmentIdx = 0;
  18. for(UINT32 i = 0; i < BS_MAX_MULTIPLE_RENDER_TARGETS; i++)
  19. {
  20. if (desc.color[i].view == VK_NULL_HANDLE)
  21. continue;
  22. VkAttachmentDescription& attachmentDesc = attachments[attachmentIdx];
  23. attachmentDesc.flags = 0;
  24. attachmentDesc.format = desc.color[i].format;
  25. attachmentDesc.samples = sampleFlags;
  26. attachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
  27. attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
  28. attachmentDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  29. attachmentDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  30. attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  31. // If offscreen we make the assumption the surface will be read by a shader
  32. if(desc.offscreen)
  33. attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
  34. else
  35. attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
  36. VkAttachmentReference& ref = colorReferences[attachmentIdx];
  37. ref.attachment = attachmentIdx;
  38. ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  39. attachmentViews[attachmentIdx] = desc.color[i].view;
  40. ; attachmentIdx++;
  41. }
  42. UINT32 numColorAttachments = attachmentIdx;
  43. bool hasDepthAttachment = desc.depth.view != VK_NULL_HANDLE;
  44. if (hasDepthAttachment)
  45. {
  46. VkAttachmentDescription& attachmentDesc = attachments[attachmentIdx];
  47. attachmentDesc.flags = 0;
  48. attachmentDesc.format = desc.depth.format;
  49. attachmentDesc.samples = sampleFlags;
  50. attachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
  51. attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
  52. attachmentDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
  53. attachmentDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
  54. attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  55. attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  56. VkAttachmentReference& ref = depthReference;
  57. ref.attachment = attachmentIdx;
  58. ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  59. attachmentViews[attachmentIdx] = desc.depth.view;
  60. attachmentIdx++;
  61. }
  62. VkSubpassDescription subpassDesc;
  63. subpassDesc.flags = 0;
  64. subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
  65. subpassDesc.colorAttachmentCount = numColorAttachments;
  66. subpassDesc.inputAttachmentCount = 0;
  67. subpassDesc.pInputAttachments = nullptr;
  68. subpassDesc.preserveAttachmentCount = 0;
  69. subpassDesc.pPreserveAttachments = nullptr;
  70. subpassDesc.pResolveAttachments = nullptr;
  71. if (numColorAttachments > 0)
  72. subpassDesc.pColorAttachments = colorReferences;
  73. else
  74. subpassDesc.pColorAttachments = nullptr;
  75. if (hasDepthAttachment)
  76. subpassDesc.pDepthStencilAttachment = &depthReference;
  77. else
  78. subpassDesc.pDepthStencilAttachment = nullptr;
  79. // Subpass dependencies for layout transitions
  80. VkSubpassDependency dependencies[2];
  81. dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
  82. dependencies[0].dstSubpass = 0;
  83. dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
  84. dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  85. dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
  86. dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; // Note: Do we really need read access?
  87. dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; // Note: Is this really required?
  88. dependencies[1].srcSubpass = 0;
  89. dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
  90. dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  91. dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
  92. dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  93. dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
  94. dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;// Note: Is this really required?
  95. VkRenderPassCreateInfo renderPassCI;
  96. renderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
  97. renderPassCI.pNext = nullptr;
  98. renderPassCI.flags = 0;
  99. renderPassCI.attachmentCount = attachmentIdx;
  100. renderPassCI.pAttachments = attachments;
  101. renderPassCI.subpassCount = 1;
  102. renderPassCI.pSubpasses = &subpassDesc;
  103. renderPassCI.dependencyCount = 2;
  104. renderPassCI.pDependencies = dependencies;
  105. VkResult result = vkCreateRenderPass(device->getLogical(), &renderPassCI, gVulkanAllocator, &mRenderPass);
  106. assert(result == VK_SUCCESS);
  107. // Create frame buffer
  108. VkFramebufferCreateInfo framebufferCI;
  109. framebufferCI.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
  110. framebufferCI.pNext = nullptr;
  111. framebufferCI.flags = 0;
  112. framebufferCI.renderPass = mRenderPass;
  113. framebufferCI.attachmentCount = attachmentIdx;
  114. framebufferCI.pAttachments = attachmentViews;
  115. framebufferCI.width = desc.width;
  116. framebufferCI.height = desc.height;
  117. framebufferCI.layers = desc.layers;
  118. result = vkCreateFramebuffer(device->getLogical(), &framebufferCI, gVulkanAllocator, &mFramebuffer);
  119. assert(result == VK_SUCCESS);
  120. }
  121. VulkanFramebuffer::~VulkanFramebuffer()
  122. {
  123. vkDestroyFramebuffer(mDevice->getLogical(), mFramebuffer, gVulkanAllocator);
  124. vkDestroyRenderPass(mDevice->getLogical(), mRenderPass, gVulkanAllocator);
  125. }
  126. }