BsVulkanFramebuffer.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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 bs
  7. {
  8. UINT32 VulkanFramebuffer::sNextValidId = 1;
  9. VulkanFramebuffer::VulkanFramebuffer(VulkanResourceManager* owner, const VULKAN_FRAMEBUFFER_DESC& desc)
  10. : VulkanResource(owner, false), mNumAttachments(0), mNumColorAttachments(0), mNumLayers(desc.layers)
  11. , mColorBaseLayers(), mDepthBaseLayer(0), mHasDepth(false), mSampleFlags(VK_SAMPLE_COUNT_1_BIT)
  12. {
  13. mId = sNextValidId++;
  14. // Create render state
  15. VkAttachmentDescription attachments[BS_MAX_MULTIPLE_RENDER_TARGETS + 1];
  16. VkImageView attachmentViews[BS_MAX_MULTIPLE_RENDER_TARGETS + 1];
  17. VkAttachmentReference colorReferences[BS_MAX_MULTIPLE_RENDER_TARGETS];
  18. VkAttachmentReference depthReference;
  19. mSampleFlags = VulkanUtility::getSampleFlags(desc.numSamples);
  20. UINT32 attachmentIdx = 0;
  21. for(UINT32 i = 0; i < BS_MAX_MULTIPLE_RENDER_TARGETS; i++)
  22. {
  23. if (desc.color[i].view == VK_NULL_HANDLE)
  24. continue;
  25. VkAttachmentDescription& attachmentDesc = attachments[attachmentIdx];
  26. attachmentDesc.flags = 0;
  27. attachmentDesc.format = desc.color[i].format;
  28. attachmentDesc.samples = mSampleFlags;
  29. attachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  30. attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
  31. attachmentDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  32. attachmentDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  33. attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  34. // If offscreen we make the assumption the surface will be read by a shader
  35. if(desc.offscreen)
  36. attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
  37. else
  38. attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
  39. mColorBaseLayers[i] = desc.color[i].baseLayer;
  40. VkAttachmentReference& ref = colorReferences[attachmentIdx];
  41. ref.attachment = attachmentIdx;
  42. ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  43. attachmentViews[attachmentIdx] = desc.color[i].view;
  44. ; attachmentIdx++;
  45. }
  46. mNumColorAttachments = attachmentIdx;
  47. mHasDepth = desc.depth.view != VK_NULL_HANDLE;
  48. if (mHasDepth)
  49. {
  50. VkAttachmentDescription& attachmentDesc = attachments[attachmentIdx];
  51. attachmentDesc.flags = 0;
  52. attachmentDesc.format = desc.depth.format;
  53. attachmentDesc.samples = mSampleFlags;
  54. attachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  55. attachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
  56. attachmentDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  57. attachmentDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
  58. attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  59. attachmentDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  60. mDepthBaseLayer = desc.depth.baseLayer;
  61. VkAttachmentReference& ref = depthReference;
  62. ref.attachment = attachmentIdx;
  63. ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  64. attachmentViews[attachmentIdx] = desc.depth.view;
  65. attachmentIdx++;
  66. }
  67. mNumAttachments = attachmentIdx;
  68. VkSubpassDescription subpassDesc;
  69. subpassDesc.flags = 0;
  70. subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
  71. subpassDesc.colorAttachmentCount = mNumColorAttachments;
  72. subpassDesc.inputAttachmentCount = 0;
  73. subpassDesc.pInputAttachments = nullptr;
  74. subpassDesc.preserveAttachmentCount = 0;
  75. subpassDesc.pPreserveAttachments = nullptr;
  76. subpassDesc.pResolveAttachments = nullptr;
  77. if (mNumColorAttachments > 0)
  78. subpassDesc.pColorAttachments = colorReferences;
  79. else
  80. subpassDesc.pColorAttachments = nullptr;
  81. if (mHasDepth)
  82. subpassDesc.pDepthStencilAttachment = &depthReference;
  83. else
  84. subpassDesc.pDepthStencilAttachment = nullptr;
  85. // Subpass dependencies for layout transitions
  86. VkSubpassDependency dependencies[2];
  87. dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
  88. dependencies[0].dstSubpass = 0;
  89. dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
  90. dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  91. dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
  92. dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; // Note: Do we really need read access?
  93. dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; // Note: Is this really required?
  94. dependencies[1].srcSubpass = 0;
  95. dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
  96. dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  97. dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
  98. dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  99. dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
  100. dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;// Note: Is this really required?
  101. VkRenderPassCreateInfo renderPassCI;
  102. renderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
  103. renderPassCI.pNext = nullptr;
  104. renderPassCI.flags = 0;
  105. renderPassCI.attachmentCount = mNumAttachments;
  106. renderPassCI.pAttachments = attachments;
  107. renderPassCI.subpassCount = 1;
  108. renderPassCI.pSubpasses = &subpassDesc;
  109. renderPassCI.dependencyCount = 2;
  110. renderPassCI.pDependencies = dependencies;
  111. VkDevice device = mOwner->getDevice().getLogical();
  112. // Create discard render pass and frame buffer
  113. VkResult result = vkCreateRenderPass(device, &renderPassCI, gVulkanAllocator, &mRenderPassDiscard);
  114. assert(result == VK_SUCCESS);
  115. //// Create frame buffer
  116. VkFramebufferCreateInfo framebufferCI;
  117. framebufferCI.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
  118. framebufferCI.pNext = nullptr;
  119. framebufferCI.flags = 0;
  120. framebufferCI.renderPass = mRenderPassDiscard;
  121. framebufferCI.attachmentCount = mNumAttachments;
  122. framebufferCI.pAttachments = attachmentViews;
  123. framebufferCI.width = desc.width;
  124. framebufferCI.height = desc.height;
  125. framebufferCI.layers = desc.layers;
  126. result = vkCreateFramebuffer(device, &framebufferCI, gVulkanAllocator, &mFramebufferDiscard);
  127. assert(result == VK_SUCCESS);
  128. // Create preserving render pass and frame buffer
  129. for (UINT32 i = 0; i < mNumColorAttachments; i++)
  130. {
  131. VkAttachmentDescription& attachmentDesc = attachments[i];
  132. attachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
  133. attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  134. }
  135. if (mHasDepth)
  136. {
  137. VkAttachmentDescription& attachmentDesc = attachments[mNumColorAttachments];
  138. attachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
  139. attachmentDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
  140. attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  141. }
  142. vkCreateRenderPass(device, &renderPassCI, gVulkanAllocator, &mRenderPassPreserve);
  143. assert(result == VK_SUCCESS);
  144. //// Create frame buffer
  145. framebufferCI.renderPass = mRenderPassPreserve;
  146. result = vkCreateFramebuffer(device, &framebufferCI, gVulkanAllocator, &mFramebufferPreserve);
  147. assert(result == VK_SUCCESS);
  148. }
  149. VulkanFramebuffer::~VulkanFramebuffer()
  150. {
  151. VkDevice device = mOwner->getDevice().getLogical();
  152. vkDestroyFramebuffer(device, mFramebufferDiscard, gVulkanAllocator);
  153. vkDestroyRenderPass(device, mRenderPassDiscard, gVulkanAllocator);
  154. vkDestroyFramebuffer(device, mFramebufferPreserve, gVulkanAllocator);
  155. vkDestroyRenderPass(device, mRenderPassPreserve, gVulkanAllocator);
  156. }
  157. VkRenderPass VulkanFramebuffer::getRenderPass(bool preserveContents) const
  158. {
  159. if (preserveContents)
  160. return mRenderPassPreserve;
  161. return mRenderPassDiscard;
  162. }
  163. VkFramebuffer VulkanFramebuffer::getFramebuffer(bool preserveContents) const
  164. {
  165. if (preserveContents)
  166. return mFramebufferPreserve;
  167. return mFramebufferDiscard;
  168. }
  169. }